From 04d6fa61997af782a13f85a84b5e444af95f5344 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Tue, 13 Apr 2021 22:22:33 -0400 Subject: [PATCH] fix additional type parameter instantiation issues - avoid premature conversion of default struct type parameters - allow use of $clog2, $signed, and $unsigned in type parameters - more thorough and efficient top reference ident renaming - precede type param conversion with hier const pass --- src/Convert.hs | 2 +- src/Convert/ParamType.hs | 23 ++++++++++++++------ src/Convert/Traverse.hs | 30 +++++++++++++++++++++++++- test/basic/paramtype.sv | 7 ++++-- test/basic/paramtype.v | 18 ++++++++++------ test/basic/paramtype_struct_default.sv | 21 ++++++++++++++++++ test/basic/paramtype_struct_default.v | 8 +++++++ 7 files changed, 93 insertions(+), 16 deletions(-) create mode 100644 test/basic/paramtype_struct_default.sv create mode 100644 test/basic/paramtype_struct_default.v diff --git a/src/Convert.hs b/src/Convert.hs index b02225e..ca4cf78 100644 --- a/src/Convert.hs +++ b/src/Convert.hs @@ -75,10 +75,10 @@ mainPhases selectExclude = , Convert.MultiplePacked.convert , Convert.UnbasedUnsized.convert , Convert.Cast.convert + , Convert.ParamType.convert , Convert.HierConst.convert , Convert.TypeOf.convert , Convert.DimensionQuery.convert - , Convert.ParamType.convert , Convert.Simplify.convert , Convert.Stream.convert , Convert.Struct.convert diff --git a/src/Convert/ParamType.hs b/src/Convert/ParamType.hs index e124029..5d16a63 100644 --- a/src/Convert/ParamType.hs +++ b/src/Convert/ParamType.hs @@ -150,13 +150,15 @@ convert files = Part attrs extern kw ml m p items = part m' = moduleInstanceName m typeMap items' = map rewriteModuleItem items - rewriteModuleItem = traverseDecls rewriteDecl . - traverseNestedModuleItems - (traverseExprs rewriteExpr . traverseLHSs rewriteLHS) + rewriteModuleItem = traverseNestedModuleItems $ traverseNodes + rewriteExpr rewriteDecl rewriteType rewriteLHS rewriteStmt rewriteDecl :: Decl -> Decl rewriteDecl (ParamType Parameter x _) = - ParamType Localparam x (fst $ typeMap Map.! x) - rewriteDecl other = other + ParamType Localparam x t + where t = rewriteType $ fst $ typeMap Map.! x + rewriteDecl other = + traverseDeclTypes rewriteType $ + traverseDeclExprs rewriteExpr other additionalParamItems = concatMap makeAddedParams $ Map.toList $ Map.map snd typeMap rewriteExpr :: Expr -> Expr @@ -177,7 +179,13 @@ convert files = traverseSinglyNestedLHSs rewriteLHS other rewriteType :: Type -> Type rewriteType = - traverseNestedTypes $ traverseTypeExprs rewriteExpr + traverseTypeExprs rewriteExpr . + traverseSinglyNestedTypes rewriteType + rewriteStmt :: Stmt -> Stmt + rewriteStmt = + traverseStmtLHSs rewriteLHS . + traverseStmtExprs rewriteExpr . + traverseSinglyNestedStmts rewriteStmt makeAddedParams :: (Identifier, IdentSet) -> [ModuleItem] makeAddedParams (paramName, identSet) = @@ -289,6 +297,9 @@ prepareTypeIdents prefix = (traverseTypeExprsM $ traverseNestedExprsM prepareExprIdents) where prepareExprIdents :: Expr -> Writer IdentSet Expr + prepareExprIdents (e @ (Ident "$unsigned")) = return e + prepareExprIdents (e @ (Ident "$signed" )) = return e + prepareExprIdents (e @ (Ident "$clog2" )) = return e prepareExprIdents (Ident x) = do tell $ Set.singleton x return $ Ident $ prefix ++ '_' : x diff --git a/src/Convert/Traverse.hs b/src/Convert/Traverse.hs index 757a4e0..d562814 100644 --- a/src/Convert/Traverse.hs +++ b/src/Convert/Traverse.hs @@ -27,6 +27,7 @@ module Convert.Traverse , traverseExprs , collectExprsM , traverseNodesM +, traverseNodes , traverseStmtExprsM , traverseStmtExprs , collectStmtExprsM @@ -98,6 +99,8 @@ module Convert.Traverse , traverseFiles , traverseSinglyNestedGenItemsM , traverseSinglyNestedStmtsM +, traverseSinglyNestedStmts +, collectSinglyNestedStmtsM ) where import Data.Functor.Identity (Identity, runIdentity) @@ -252,6 +255,11 @@ traverseSinglyNestedStmtsM fullMapper = cs cs (Null) = return Null cs (CommentStmt c) = return $ CommentStmt c +traverseSinglyNestedStmts :: Mapper Stmt -> Mapper Stmt +traverseSinglyNestedStmts = unmonad traverseSinglyNestedStmtsM +collectSinglyNestedStmtsM :: Monad m => CollectorM m Stmt -> CollectorM m Stmt +collectSinglyNestedStmtsM = collectify traverseSinglyNestedStmtsM + traverseAssertionStmtsM :: Monad m => MapperM m Stmt -> MapperM m Assertion traverseAssertionStmtsM mapper = assertionMapper where @@ -623,6 +631,21 @@ traverseNodesM exprMapper declMapper typeMapper lhsMapper stmtMapper = e' <- exprMapper e return (dir, ident, e') +traverseNodes + :: Mapper Expr + -> Mapper Decl + -> Mapper Type + -> Mapper LHS + -> Mapper Stmt + -> Mapper ModuleItem +traverseNodes exprMapper declMapper typeMapper lhsMapper stmtMapper = + runIdentity . traverseNodesM + (return . exprMapper) + (return . declMapper) + (return . typeMapper) + (return . lhsMapper ) + (return . stmtMapper) + traverseStmtExprsM :: Monad m => MapperM m Expr -> MapperM m Stmt traverseStmtExprsM exprMapper = flatStmtMapper where @@ -947,7 +970,12 @@ traverseTypesM' strategy mapper = traverseExprsM (traverseNestedExprsM exprMapper) where exprMapper = traverseExprTypesM mapper - declMapper = traverseDeclTypesM mapper + declMapper = + if strategy == IncludeParamTypes + then traverseDeclTypesM mapper + else \decl -> case decl of + ParamType{} -> return decl + _ -> traverseDeclTypesM mapper decl miMapper (MIPackageItem (Function l t x d s)) = mapper t >>= \t' -> return $ MIPackageItem $ Function l t' x d s miMapper (MIPackageItem (other @ (Task _ _ _ _))) = diff --git a/test/basic/paramtype.sv b/test/basic/paramtype.sv index 7cdd249..4f183b3 100644 --- a/test/basic/paramtype.sv +++ b/test/basic/paramtype.sv @@ -72,8 +72,8 @@ module p #( T x = 0; U y = 1; initial begin - $display("p %b %b %d", x, x+1, $bits(T)); - $display("p %b %b %d", y, y+1, $bits(U)); + $display("p %b %b %0d", x, x+1, $bits(T)); + $display("p %b %b %0d", y, y+1, $bits(U)); end endmodule @@ -112,3 +112,6 @@ module f_4; o_nodef #(.T(logic [1:0]), .U(logic), .b(0), .a(1)) x(); endmodule module p_1; p #(logic [1:0], logic [2:0]) x(); endmodule module p_2; p x(); endmodule module p_3; localparam W = 2; p #(logic [W:0], logic [W:0]) x(); endmodule +module p_4; parameter W = 2; p #(logic [$clog2(W):0], logic [$clog2(W):0]) x(); endmodule +module p_5; parameter W = 2; p #(logic [$unsigned(W):0], logic [$unsigned(W):0]) x(); endmodule +module p_6; parameter W = 2; p #(logic [$signed(W):0], logic [$signed(W):0]) x(); endmodule diff --git a/test/basic/paramtype.v b/test/basic/paramtype.v index e15994a..7035aeb 100644 --- a/test/basic/paramtype.v +++ b/test/basic/paramtype.v @@ -36,11 +36,17 @@ module top; $display("n_nodef b= 1 001 00000000000000000000000000000010 3"); $display("n_nodef a= 1 01 00000000000000000000000000000010 2"); $display("n_nodef b= 0 0 00000000000000000000000000000001 1"); - $display("p 00 00000000000000000000000000000001 2"); - $display("p 001 00000000000000000000000000000010 3"); - $display("p 0 00000000000000000000000000000001 1"); - $display("p 1 00000000000000000000000000000010 1"); - $display("p 000 00000000000000000000000000000001 3"); - $display("p 001 00000000000000000000000000000010 3"); + $display("p 00 00000000000000000000000000000001 2"); + $display("p 001 00000000000000000000000000000010 3"); + $display("p 0 00000000000000000000000000000001 1"); + $display("p 1 00000000000000000000000000000010 1"); + $display("p 000 00000000000000000000000000000001 3"); + $display("p 001 00000000000000000000000000000010 3"); + $display("p 00 00000000000000000000000000000001 2"); + $display("p 01 00000000000000000000000000000010 2"); + $display("p 000 00000000000000000000000000000001 3"); + $display("p 001 00000000000000000000000000000010 3"); + $display("p 000 00000000000000000000000000000001 3"); + $display("p 001 00000000000000000000000000000010 3"); end endmodule diff --git a/test/basic/paramtype_struct_default.sv b/test/basic/paramtype_struct_default.sv new file mode 100644 index 0000000..da34495 --- /dev/null +++ b/test/basic/paramtype_struct_default.sv @@ -0,0 +1,21 @@ +module example(inp, data, valid); + parameter W = 16; + typedef struct packed { + logic [W-1:0] data; + logic valid; + } line_t; + parameter type local_line_t = line_t; + input local_line_t inp; + output logic [W-1:0] data; + assign data = inp.data; + output logic valid; + assign valid = inp.valid; +endmodule + +module top; + reg [16:0] inp; + wire [15:0] data; + wire valid; + example e(.*); + initial inp = 17'b1_01100011_11001111; +endmodule diff --git a/test/basic/paramtype_struct_default.v b/test/basic/paramtype_struct_default.v new file mode 100644 index 0000000..6abcf10 --- /dev/null +++ b/test/basic/paramtype_struct_default.v @@ -0,0 +1,8 @@ +module top; + reg [16:0] inp; + wire [15:0] data; + wire valid; + assign data = inp[16:1]; + assign valid = inp[0]; + initial inp = 17'b1_01100011_11001111; +endmodule