diff --git a/src/Convert/ParamType.hs b/src/Convert/ParamType.hs index 294c842..1db7f1f 100644 --- a/src/Convert/ParamType.hs +++ b/src/Convert/ParamType.hs @@ -149,13 +149,25 @@ convert files = where Part attrs extern kw ml m p items = part m' = moduleInstanceName m typeMap - items' = map (traverseDecls rewriteDecl) items + items' = map (traverseExprs rewriteExpr) $ + map (traverseDecls rewriteDecl) items rewriteDecl :: Decl -> Decl rewriteDecl (ParamType Parameter x _) = ParamType Localparam x (fst $ typeMap Map.! x) rewriteDecl other = other additionalParamItems = concatMap makeAddedParams $ Map.toList $ Map.map snd typeMap + rewriteExpr :: Expr -> Expr + rewriteExpr (orig @ (Dot (Ident x) y)) = + if x == m + then Dot (Ident m') y + else orig + rewriteExpr other = + traverseExprTypes rewriteType $ + traverseSinglyNestedExprs rewriteExpr other + rewriteType :: Type -> Type + rewriteType = + traverseNestedTypes $ traverseTypeExprs rewriteExpr makeAddedParams :: (Identifier, IdentSet) -> [ModuleItem] makeAddedParams (paramName, identSet) = @@ -235,7 +247,7 @@ exprToType _ = Nothing -- checks where a type is sufficiently resolved to be substituted isSimpleType :: Type -> Bool isSimpleType typ = - (not $ typeHasQueries typ) && + (not $ typeIsUnresolved typ) && case typ of IntegerVector{} -> True IntegerAtom {} -> True @@ -246,17 +258,19 @@ isSimpleType typ = Union _ fields _ -> all (isSimpleType . fst) fields _ -> False --- returns whether a top-level type contains any dimension queries -typeHasQueries :: Type -> Bool -typeHasQueries = - not . null . execWriter . collectTypeExprsM +-- returns whether a top-level type contains any dimension queries or +-- hierarchical references +typeIsUnresolved :: Type -> Bool +typeIsUnresolved = + getAny . execWriter . collectTypeExprsM (collectNestedExprsM collectUnresolvedExprM) where - collectUnresolvedExprM :: Expr -> Writer [Expr] () - collectUnresolvedExprM (expr @ PSIdent{}) = tell [expr] - collectUnresolvedExprM (expr @ CSIdent{}) = tell [expr] - collectUnresolvedExprM (expr @ DimsFn{}) = tell [expr] - collectUnresolvedExprM (expr @ DimFn {}) = tell [expr] + collectUnresolvedExprM :: Expr -> Writer Any () + collectUnresolvedExprM PSIdent{} = tell $ Any True + collectUnresolvedExprM CSIdent{} = tell $ Any True + collectUnresolvedExprM DimsFn {} = tell $ Any True + collectUnresolvedExprM DimFn {} = tell $ Any True + collectUnresolvedExprM Dot {} = tell $ Any True collectUnresolvedExprM _ = return () prepareTypeIdents :: Identifier -> Type -> (Type, IdentSet) diff --git a/test/basic/paramtype_hier.sv b/test/basic/paramtype_hier.sv new file mode 100644 index 0000000..e35feb4 --- /dev/null +++ b/test/basic/paramtype_hier.sv @@ -0,0 +1,19 @@ +module Module; + parameter int S; + parameter type T; + T x = '1; + initial $display("Module %0d: %b, %0d", S, Module.x, $bits(T)); +endmodule + +module top; + parameter ONE = 1; + logic [ONE*7:ONE*0] x; + if (1) begin : blk + localparam W = ONE * 3; + typedef logic [W-1:$bits(x)] T; + T x; + end + Module #(1, logic [$bits(x)-1:0]) m1(); + Module #(2, logic [$bits(blk.x)-1:0]) m2(); + Module #(3, logic [top.blk.W-1:0]) m3(); +endmodule diff --git a/test/basic/paramtype_hier.v b/test/basic/paramtype_hier.v new file mode 100644 index 0000000..7631247 --- /dev/null +++ b/test/basic/paramtype_hier.v @@ -0,0 +1,18 @@ +module Module; + parameter S = 0; + parameter T = 0; + wire [T-1:0] x = 1'sb1; + initial $display("Module %0d: %b, %0d", S, Module.x, T); +endmodule + +module top; + parameter ONE = 1; + wire [ONE*7:ONE*0] x; + if (1) begin : blk + localparam W = ONE * 3; + wire [W-1:$bits(x)] x; + end + Module #(1, 8) m1(); + Module #(2, 7) m2(); + Module #(3, 3) m3(); +endmodule