Commit 2e06d45c by Zachary Snow

fix inadvertent duplicate declaration generation

Disabling the package item injection routine used in the enum conversion
when there were no items to inject exposed cases where conversions would
generate duplicate declarations. The hierarchical constant and param
type conversions were trivially affected. The package conversion could
inject class items within a generate region and then re-inject them
outside of that generate region. The package conversions now uses an
upgraded generate region flattening utility to ensure injected class
items are seen. This also includes coverage for a conflict which
occurred even without the enum conversion change.
parent ac548cac
...@@ -39,7 +39,10 @@ convertDescription :: Description -> [Description] ...@@ -39,7 +39,10 @@ convertDescription :: Description -> [Description]
convertDescription (description @ Part{}) = convertDescription (description @ Part{}) =
[Part attrs extern kw lifetime name ports items'] [Part attrs extern kw lifetime name ports items']
where where
items' = inject enumItems items -- only keep what's used items' = -- only keep what's used
if null enumItems
then items
else inject enumItems items
Part attrs extern kw lifetime name ports items = description' Part attrs extern kw lifetime name ports items = description'
(description', enumItems) = convertDescription' description (description', enumItems) = convertDescription' description
convertDescription other = [other] convertDescription other = [other]
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
module Convert.HierConst (convert) where module Convert.HierConst (convert) where
import Control.Monad (when)
import Data.Either (fromLeft) import Data.Either (fromLeft)
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
...@@ -86,6 +87,8 @@ traverseExprM (expr @ (Dot _ x)) = do ...@@ -86,6 +87,8 @@ traverseExprM (expr @ (Dot _ x)) = do
(Just ([_, _], _, Left{}), Just ([_, _], _, Left{})) -> (Just ([_, _], _, Left{}), Just ([_, _], _, Left{})) ->
return $ Ident x return $ Ident x
(Just (accesses @ [Access _ Nil, _], _, Left False), _) -> do (Just (accesses @ [Access _ Nil, _], _, Left False), _) -> do
details <- lookupElemM $ prefix x
when (details == Nothing) $
insertElem accesses (Left True) insertElem accesses (Left True)
return $ Ident $ prefix x return $ Ident $ prefix x
(Just ([Access _ Nil, _], _, Left True), _) -> (Just ([Access _ Nil, _], _, Left True), _) ->
......
...@@ -610,7 +610,8 @@ convertDescription pis (orig @ Part{}) = ...@@ -610,7 +610,8 @@ convertDescription pis (orig @ Part{}) =
else Part attrs extern kw lifetime name ports items' else Part attrs extern kw lifetime name ports items'
where where
Part attrs extern kw lifetime name ports items = orig Part attrs extern kw lifetime name ports items = orig
items' = addItems pis Set.empty (map addUsedPIs items) items' = addItems pis Set.empty $ map addUsedPIs $
foldr breakGenerate [] items -- ensure decls are visible
convertDescription _ other = other convertDescription _ other = other
-- attempt to fix simple declaration order issues -- attempt to fix simple declaration order issues
......
...@@ -23,6 +23,7 @@ type Instance = Map.Map Identifier (Type, IdentSet) ...@@ -23,6 +23,7 @@ type Instance = Map.Map Identifier (Type, IdentSet)
type Instances = Set.Set (Identifier, Instance) type Instances = Set.Set (Identifier, Instance)
type IdentSet = Set.Set Identifier type IdentSet = Set.Set Identifier
type DeclMap = Map.Map Identifier Decl
type UsageMap = [(Identifier, Set.Set Identifier)] type UsageMap = [(Identifier, Set.Set Identifier)]
convert :: [AST] -> [AST] convert :: [AST] -> [AST]
...@@ -241,20 +242,20 @@ typeIsUnresolved = ...@@ -241,20 +242,20 @@ typeIsUnresolved =
collectUnresolvedExprM Dot {} = tell $ Any True collectUnresolvedExprM Dot {} = tell $ Any True
collectUnresolvedExprM _ = return () collectUnresolvedExprM _ = return ()
prepareTypeExprs :: Identifier -> Identifier -> Type -> (Type, (IdentSet, [Decl])) prepareTypeExprs :: Identifier -> Identifier -> Type -> (Type, (IdentSet, DeclMap))
prepareTypeExprs instanceName paramName = prepareTypeExprs instanceName paramName =
runWriter . traverseNestedTypesM runWriter . traverseNestedTypesM
(traverseTypeExprsM $ traverseNestedExprsM prepareExpr) (traverseTypeExprsM $ traverseNestedExprsM prepareExpr)
where where
prepareExpr :: Expr -> Writer (IdentSet, [Decl]) Expr prepareExpr :: Expr -> Writer (IdentSet, DeclMap) Expr
prepareExpr (e @ Call{}) = do prepareExpr (e @ Call{}) = do
tell (Set.empty, [decl]) tell (Set.empty, Map.singleton x decl)
prepareExpr $ Ident x prepareExpr $ Ident x
where where
decl = Param Localparam (TypeOf e) x e decl = Param Localparam (TypeOf e) x e
x = instanceName ++ "_sv2v_pfunc_" ++ shortHash e x = instanceName ++ "_sv2v_pfunc_" ++ shortHash e
prepareExpr (Ident x) = do prepareExpr (Ident x) = do
tell (Set.singleton x, []) tell (Set.singleton x, Map.empty)
return $ Ident $ paramName ++ '_' : x return $ Ident $ paramName ++ '_' : x
prepareExpr other = return other prepareExpr other = return other
...@@ -301,9 +302,9 @@ convertModuleItemM (orig @ (Instance m bindings x r p)) = ...@@ -301,9 +302,9 @@ convertModuleItemM (orig @ (Instance m bindings x r p)) =
bindingsMap = Map.fromList bindings bindingsMap = Map.fromList bindings
resolvedTypesWithDecls = Map.mapMaybeWithKey resolveType bindingsMap resolvedTypesWithDecls = Map.mapMaybeWithKey resolveType bindingsMap
resolvedTypes = Map.map (\(a, (b, _)) -> (a, b)) resolvedTypesWithDecls resolvedTypes = Map.map (\(a, (b, _)) -> (a, b)) resolvedTypesWithDecls
addedDecls = concatMap (snd . snd . snd) $ addedDecls = Map.elems $ Map.unions $ map (snd . snd) $
Map.toList resolvedTypesWithDecls Map.elems resolvedTypesWithDecls
resolveType :: Identifier -> TypeOrExpr -> Maybe (Type, (IdentSet, [Decl])) resolveType :: Identifier -> TypeOrExpr -> Maybe (Type, (IdentSet, DeclMap))
resolveType _ Right{} = Nothing resolveType _ Right{} = Nothing
resolveType paramName (Left t) = resolveType paramName (Left t) =
Just $ prepareTypeExprs x paramName t Just $ prepareTypeExprs x paramName t
......
...@@ -11,6 +11,7 @@ module Convert.Traverse ...@@ -11,6 +11,7 @@ module Convert.Traverse
, unmonad , unmonad
, collectify , collectify
, mapBothM , mapBothM
, breakGenerate
, traverseDescriptionsM , traverseDescriptionsM
, traverseDescriptions , traverseDescriptions
, collectDescriptionsM , collectDescriptionsM
...@@ -132,21 +133,21 @@ traverseDescriptions = map ...@@ -132,21 +133,21 @@ traverseDescriptions = map
collectDescriptionsM :: Monad m => CollectorM m Description -> CollectorM m AST collectDescriptionsM :: Monad m => CollectorM m Description -> CollectorM m AST
collectDescriptionsM = mapM_ collectDescriptionsM = mapM_
breakGenerate :: ModuleItem -> [ModuleItem] breakGenerate :: ModuleItem -> [ModuleItem] -> [ModuleItem]
breakGenerate (Generate genItems) = breakGenerate (Generate genItems) items =
if all isGenModuleItem genItems foldr breakGenerateStep items genItems
then map (\(GenModuleItem item) -> item) genItems breakGenerate item items = item : items
else [Generate genItems]
where breakGenerateStep :: GenItem -> [ModuleItem] -> [ModuleItem]
isGenModuleItem :: GenItem -> Bool breakGenerateStep (GenModuleItem item) items = item : items
isGenModuleItem (GenModuleItem _) = True breakGenerateStep genItem (Generate genItems : items) =
isGenModuleItem _ = False Generate (genItem : genItems) : items
breakGenerate other = [other] breakGenerateStep genItem items = Generate [genItem] : items
traverseModuleItemsM :: Monad m => MapperM m ModuleItem -> MapperM m Description traverseModuleItemsM :: Monad m => MapperM m ModuleItem -> MapperM m Description
traverseModuleItemsM mapper (Part attrs extern kw lifetime name ports items) = do traverseModuleItemsM mapper (Part attrs extern kw lifetime name ports items) = do
items' <- mapM (traverseNestedModuleItemsM mapper) items items' <- mapM (traverseNestedModuleItemsM mapper) items
let items'' = concatMap breakGenerate items' let items'' = foldr breakGenerate [] items'
return $ Part attrs extern kw lifetime name ports items'' return $ Part attrs extern kw lifetime name ports items''
where where
traverseModuleItemsM mapper (PackageItem packageItem) = do traverseModuleItemsM mapper (PackageItem packageItem) = do
...@@ -159,18 +160,18 @@ traverseModuleItemsM mapper (Package lifetime name items) = do ...@@ -159,18 +160,18 @@ traverseModuleItemsM mapper (Package lifetime name items) = do
let itemsWrapped = map MIPackageItem items let itemsWrapped = map MIPackageItem items
itemsWrapped' <- mapM (traverseNestedModuleItemsM mapper) itemsWrapped itemsWrapped' <- mapM (traverseNestedModuleItemsM mapper) itemsWrapped
let items' = map (\(MIPackageItem item) -> item) $ let items' = map (\(MIPackageItem item) -> item) $
concatMap breakGenerate itemsWrapped' foldr breakGenerate [] itemsWrapped'
return $ Package lifetime name items' return $ Package lifetime name items'
traverseModuleItemsM mapper (Class lifetime name decls items) = do traverseModuleItemsM mapper (Class lifetime name decls items) = do
let declsWrapped = map (MIPackageItem . Decl) decls let declsWrapped = map (MIPackageItem . Decl) decls
declsWrapped' <- mapM (traverseNestedModuleItemsM mapper) declsWrapped declsWrapped' <- mapM (traverseNestedModuleItemsM mapper) declsWrapped
let decls' = map (\(MIPackageItem (Decl decl)) -> decl) $ let decls' = map (\(MIPackageItem (Decl decl)) -> decl) $
concatMap breakGenerate declsWrapped' foldr breakGenerate [] declsWrapped'
items' <- fmap concat $ mapM indirect items items' <- fmap concat $ mapM indirect items
return $ Class lifetime name decls' items' return $ Class lifetime name decls' items'
where where
indirect (qualifier, item) = indirect (qualifier, item) =
fmap (map (unwrap qualifier) . breakGenerate) $ fmap (map (unwrap qualifier) . flip breakGenerate []) $
traverseNestedModuleItemsM mapper (MIPackageItem item) traverseNestedModuleItemsM mapper (MIPackageItem item)
unwrap qualifier = \(MIPackageItem item) -> (qualifier, item) unwrap qualifier = \(MIPackageItem item) -> (qualifier, item)
......
...@@ -126,3 +126,4 @@ module p_6; parameter W = 2; p #(logic [$signed(W):0], logic [$signed(W):0]) x() ...@@ -126,3 +126,4 @@ module p_6; parameter W = 2; p #(logic [$signed(W):0], logic [$signed(W):0]) x()
module p_7; parameter W = 2; p #(logic [square(W):0], logic [square(W):0]) x(); endmodule module p_7; parameter W = 2; p #(logic [square(W):0], logic [square(W):0]) x(); endmodule
module p_8; p #(OtherT) x(); endmodule module p_8; p #(OtherT) x(); endmodule
module p_9; p #(SomeT, OtherT) x(); endmodule module p_9; p #(SomeT, OtherT) x(); endmodule
module p_A; if (1) begin : blk p #(SomeT, OtherT) x(); end endmodule
...@@ -54,5 +54,7 @@ module top; ...@@ -54,5 +54,7 @@ module top;
$display("p 1 00000000000000000000000000000010 1"); $display("p 1 00000000000000000000000000000010 1");
$display("p 0000000000 00000000000000000000000000000001 10"); $display("p 0000000000 00000000000000000000000000000001 10");
$display("p 0000000001 00000000000000000000000000000010 10"); $display("p 0000000001 00000000000000000000000000000010 10");
$display("p 0000000000 00000000000000000000000000000001 10");
$display("p 0000000001 00000000000000000000000000000010 10");
end end
endmodule endmodule
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment