diff --git a/src/Convert.hs b/src/Convert.hs index 0e0ae57..ede81ef 100644 --- a/src/Convert.hs +++ b/src/Convert.hs @@ -50,7 +50,6 @@ phases excludes = , Convert.ForDecl.convert , Convert.FuncRet.convert , Convert.EmptyArgs.convert - , Convert.Enum.convert , Convert.IntTypes.convert , Convert.KWArgs.convert , Convert.Mux.convert @@ -63,6 +62,7 @@ phases excludes = , Convert.UnbasedUnsized.convert , Convert.Unique.convert , Convert.Package.convert + , Convert.Enum.convert , Convert.NestPI.convert , Convert.Return.convert , selectExclude (Job.Interface, Convert.Interface.convert) diff --git a/src/Convert/Enum.hs b/src/Convert/Enum.hs index e29b2b0..309707c 100644 --- a/src/Convert/Enum.hs +++ b/src/Convert/Enum.hs @@ -44,15 +44,33 @@ convertDescription (description @ (Part _ _ _ _ _ _)) = Part extern kw lifetime name ports (enumItems ++ items) where -- replace and collect the enum types in this description - (Part extern kw lifetime name ports items, enums) = + (Part extern kw lifetime name ports items, enumPairs) = + convertDescription' description + -- convert the collected enums into their corresponding localparams + enumItems = map MIPackageItem $ map toItem $ sortOn snd $ convergeUsage items enumPairs +convertDescription (description @ (Package _ _ _)) = + Package ml name (items ++ enumItems) + where + -- replace and collect the enum types in this description + (Package ml name items, enumPairs) = + convertDescription' description + -- convert the collected enums into their corresponding localparams + enumItems = map toItem $ sortOn snd $ enumPairs +convertDescription other = other + +-- replace and collect the enum types in a description +convertDescription' :: Description -> (Description, [EnumItem]) +convertDescription' description = + (description', enumPairs) + where + -- replace and collect the enum types in this description + (description', enums) = runWriter $ traverseModuleItemsM (traverseTypesM traverseType) $ traverseModuleItems (traverseExprs $ traverseNestedExprs traverseExpr) $ description -- convert the collected enums into their corresponding localparams enumPairs = concatMap enumVals $ Set.toList enums - enumItems = map toItem $ sortOn snd $ convergeUsage items enumPairs -convertDescription other = other -- add only the enums actually used in the given items convergeUsage :: [ModuleItem] -> [EnumItem] -> [EnumItem] @@ -63,7 +81,7 @@ convergeUsage items enums = where -- determine which of the enum items are actually used here (usedEnums, unusedEnums) = partition isUsed enums - enumItems = map toItem usedEnums + enumItems = map MIPackageItem $ map toItem usedEnums isUsed ((_, x), _) = Set.member x usedIdents usedIdents = execWriter $ mapM (collectExprsM $ collectNestedExprsM collectIdent) $ items @@ -71,9 +89,9 @@ convergeUsage items enums = collectIdent (Ident x) = tell $ Set.singleton x collectIdent _ = return () -toItem :: EnumItem -> ModuleItem +toItem :: EnumItem -> PackageItem toItem ((r, x), v) = - MIPackageItem $ Decl $ Localparam itemType x v' + Decl $ Localparam itemType x v' where v' = sizedExpr x r (simplify v) itemType = Implicit Unspecified [r] @@ -103,6 +121,7 @@ simplifyRange (a, b) = (simplify a, simplify b) -- drop any enum type casts in favor of implicit conversion from the -- converted type traverseExpr :: Expr -> Expr +traverseExpr (Cast (Left (IntegerVector _ _ _)) e) = e traverseExpr (Cast (Left (Enum _ _ _)) e) = e traverseExpr other = other diff --git a/test/basic/package_enum.sv b/test/basic/package_enum_1.sv similarity index 100% rename from test/basic/package_enum.sv rename to test/basic/package_enum_1.sv diff --git a/test/basic/package_enum.v b/test/basic/package_enum_1.v similarity index 100% rename from test/basic/package_enum.v rename to test/basic/package_enum_1.v diff --git a/test/basic/package_enum_2.sv b/test/basic/package_enum_2.sv new file mode 100644 index 0000000..7d1154f --- /dev/null +++ b/test/basic/package_enum_2.sv @@ -0,0 +1,13 @@ +package foo_pkg; + typedef enum logic [2:0] { + AccessAck = 3'd0, + AccessAckData = 3'd1 + } inp_t; +endpackage + +module top; + import foo_pkg::*; + inp_t test; + assign test = foo_pkg::AccessAck; + initial $display(test); +endmodule diff --git a/test/basic/package_enum_2.v b/test/basic/package_enum_2.v new file mode 100644 index 0000000..06b4eb9 --- /dev/null +++ b/test/basic/package_enum_2.v @@ -0,0 +1,6 @@ +module top; + localparam [2:0] foo_pkg_AccessAck = 3'd0; + wire [2:0] test; + assign test = foo_pkg_AccessAck; + initial $display(test); +endmodule diff --git a/test/basic/package_enum_3.sv b/test/basic/package_enum_3.sv new file mode 100644 index 0000000..7feb9f8 --- /dev/null +++ b/test/basic/package_enum_3.sv @@ -0,0 +1,18 @@ +package foo_pkg; + typedef enum logic [2:0] { + AccessAck = 3'd0, + AccessAckData = 3'd1 + } inp_t; +endpackage + +module top; + import foo_pkg::*; + wire [2:0] test; + + always_comb begin + case (test) + AccessAck: $display("Ack"); + default : $display("default"); + endcase + end +endmodule diff --git a/test/basic/package_enum_3.v b/test/basic/package_enum_3.v new file mode 100644 index 0000000..ceb07f7 --- /dev/null +++ b/test/basic/package_enum_3.v @@ -0,0 +1,11 @@ +module top; + localparam [2:0] AccessAck = 3'd0; + wire [2:0] test; + + always @(*) begin + case (test) + AccessAck: $display("Ack"); + default : $display("default"); + endcase + end +endmodule