From 9cc211d51e6ed88c3c515f76e41de5e81079183c Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Thu, 5 Sep 2019 00:34:56 -0400 Subject: [PATCH] fix non-vector enum base types (closes #29) --- src/Convert/Enum.hs | 33 ++++++++++++++++++-------- src/Language/SystemVerilog/AST/Type.hs | 10 ++++++-- test/basic/enum_int.sv | 21 ++++++++++++++++ test/basic/enum_int.v | 17 +++++++++++++ 4 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 test/basic/enum_int.sv create mode 100644 test/basic/enum_int.v diff --git a/src/Convert/Enum.hs b/src/Convert/Enum.hs index 309707c..a517f6f 100644 --- a/src/Convert/Enum.hs +++ b/src/Convert/Enum.hs @@ -28,10 +28,10 @@ import qualified Data.Set as Set import Convert.Traverse import Language.SystemVerilog.AST -type EnumInfo = (Range, [(Identifier, Maybe Expr)]) +type EnumInfo = (Maybe Range, [(Identifier, Maybe Expr)]) type Enums = Set.Set EnumInfo type Idents = Set.Set Identifier -type EnumItem = ((Range, Identifier), Expr) +type EnumItem = ((Maybe Range, Identifier), Expr) convert :: [AST] -> [AST] convert = map $ traverseDescriptions convertDescription @@ -90,11 +90,19 @@ convergeUsage items enums = collectIdent _ = return () toItem :: EnumItem -> PackageItem -toItem ((r, x), v) = +toItem ((mr, x), v) = Decl $ Localparam itemType x v' where - v' = sizedExpr x r (simplify v) - itemType = Implicit Unspecified [r] + v' = if mr == Nothing + then simplify v + else sizedExpr x r (simplify v) + rs = maybe [] (\a -> [a]) mr + r = defaultRange mr + itemType = Implicit Unspecified rs + +defaultRange :: Maybe Range -> Range +defaultRange Nothing = (Number "0", Number "0") +defaultRange (Just r) = r toBaseType :: Maybe Type -> Type toBaseType Nothing = defaultType @@ -110,9 +118,14 @@ toBaseType (Just t) = traverseType :: Type -> Writer Enums Type traverseType (Enum t v rs) = do let baseType = toBaseType t - let (tf, [r]) = typeRanges baseType - () <- tell $ Set.singleton (simplifyRange r, v) - return $ tf (r : rs) + let (tf, rl) = typeRanges baseType + mr <- return $ case rl of + [] -> Nothing + [r] -> Just r + _ -> error $ "unexpected multi-dim enum type: " + ++ show (Enum t v rs) + () <- tell $ Set.singleton (fmap simplifyRange mr, v) + return $ tf (rl ++ rs) traverseType other = return other simplifyRange :: Range -> Range @@ -126,7 +139,7 @@ traverseExpr (Cast (Left (Enum _ _ _)) e) = e traverseExpr other = other enumVals :: EnumInfo -> [EnumItem] -enumVals (r, l) = +enumVals (mr, l) = -- check for obviously duplicate values if noDuplicates then res @@ -135,7 +148,7 @@ enumVals (r, l) = where keys = map fst l vals = tail $ scanl step (Number "-1") (map snd l) - res = zip (zip (repeat r) keys) vals + res = zip (zip (repeat mr) keys) vals noDuplicates = all (null . tail . flip elemIndices vals) vals step :: Expr -> Maybe Expr -> Expr step _ (Just expr) = expr diff --git a/src/Language/SystemVerilog/AST/Type.hs b/src/Language/SystemVerilog/AST/Type.hs index 13b3725..41b6cb1 100644 --- a/src/Language/SystemVerilog/AST/Type.hs +++ b/src/Language/SystemVerilog/AST/Type.hs @@ -84,13 +84,19 @@ typeRanges (Alias ps xx rs) = (Alias ps xx , rs) typeRanges (Net kw rs) = (Net kw , rs) typeRanges (Implicit sg rs) = (Implicit sg, rs) typeRanges (IntegerVector kw sg rs) = (IntegerVector kw sg, rs) -typeRanges (IntegerAtom kw sg ) = (\[] -> IntegerAtom kw sg, []) -typeRanges (NonInteger kw ) = (\[] -> NonInteger kw , []) +typeRanges (IntegerAtom kw sg ) = (nullRange $ IntegerAtom kw sg, []) +typeRanges (NonInteger kw ) = (nullRange $ NonInteger kw , []) typeRanges (Enum t v r) = (Enum t v, r) typeRanges (Struct p l r) = (Struct p l, r) typeRanges (Union p l r) = (Union p l, r) typeRanges (InterfaceT x my r) = (InterfaceT x my, r) +nullRange :: Type -> ([Range] -> Type) +nullRange t [] = t +nullRange t [(Number "0", Number "0")] = t +nullRange t other = + error $ "non vector type " ++ show t ++ " cannot have a range" + data Signing = Unspecified | Signed diff --git a/test/basic/enum_int.sv b/test/basic/enum_int.sv new file mode 100644 index 0000000..5404a44 --- /dev/null +++ b/test/basic/enum_int.sv @@ -0,0 +1,21 @@ +package foo_pkg; + typedef enum int { + Foo = 0, + Goo = 1 + } my_t; +endpackage + +module top; + initial begin + $display(foo_pkg::Foo); + $display(foo_pkg::Goo); + end +endmodule + +module top2; + import foo_pkg::*; + initial begin + $display(Foo); + $display(Goo); + end +endmodule diff --git a/test/basic/enum_int.v b/test/basic/enum_int.v new file mode 100644 index 0000000..3700906 --- /dev/null +++ b/test/basic/enum_int.v @@ -0,0 +1,17 @@ +module top; + localparam foo_pkg_Foo = 0; + localparam foo_pkg_Goo = 1; + initial begin + $display(foo_pkg_Foo); + $display(foo_pkg_Goo); + end +endmodule + +module top2; + localparam Foo = 0; + localparam Goo = 1; + initial begin + $display(Foo); + $display(Goo); + end +endmodule