From ae392d4536f050fd5295eeb4763c87680ef704b6 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Thu, 4 Jun 2020 20:19:21 -0400 Subject: [PATCH] fix single bit enum sizing - single bit localparams retain explicit range - fix $bits on unsized literals - use Implicit over Maybe for underlying type --- src/Convert/DimensionQuery.hs | 1 + src/Convert/Enum.hs | 49 +++++++++-------------- src/Convert/Package.hs | 2 +- src/Convert/Traverse.hs | 6 +-- src/Convert/Typedef.hs | 3 +- src/Language/SystemVerilog/AST/Type.hs | 6 +-- src/Language/SystemVerilog/Parser/Parse.y | 6 +-- test/basic/enum.sv | 15 +++---- test/basic/enum.v | 17 +++----- 9 files changed, 41 insertions(+), 64 deletions(-) diff --git a/src/Convert/DimensionQuery.hs b/src/Convert/DimensionQuery.hs index 075d262..6a450cd 100644 --- a/src/Convert/DimensionQuery.hs +++ b/src/Convert/DimensionQuery.hs @@ -134,5 +134,6 @@ convertBits (Right e) = Number n -> case elemIndex '\'' n of Nothing -> Number "32" + Just 0 -> Number "32" Just idx -> Number $ take idx n _ -> DimsFn FnBits $ Left $ TypeOf e diff --git a/src/Convert/Enum.hs b/src/Convert/Enum.hs index 1bf03f9..79080f6 100644 --- a/src/Convert/Enum.hs +++ b/src/Convert/Enum.hs @@ -26,15 +26,12 @@ import qualified Data.Set as Set import Convert.Traverse import Language.SystemVerilog.AST -type EnumInfo = (Maybe Range, [(Identifier, Maybe Expr)]) +type EnumInfo = (Type, [(Identifier, Maybe Expr)]) type Enums = Set.Set EnumInfo convert :: [AST] -> [AST] convert = map $ concatMap convertDescription -defaultType :: Type -defaultType = IntegerVector TLogic Unspecified [(Number "31", Number "0")] - convertDescription :: Description -> [Description] convertDescription (description @ Package{}) = [Package ml name (items ++ enumItems)] @@ -54,36 +51,30 @@ convertDescription' description = -- convert the collected enums into their corresponding localparams enumItems = concatMap makeEnumItems $ Set.toList enums -toBaseType :: Maybe Type -> Type -toBaseType Nothing = defaultType -toBaseType (Just (Implicit _ rs)) = - fst (typeRanges defaultType) rs -toBaseType (Just t @ (Alias _ _ _)) = t -toBaseType (Just t) = - if null rs - then tf [(Number "0", Number "0")] - else t - where (tf, rs) = typeRanges t - -- replace, but write down, enum types traverseType :: Type -> Writer Enums Type +traverseType (Enum (t @ Alias{}) v rs) = + return $ Enum t v rs -- not ready +traverseType (Enum (Implicit sg rl) v rs) = + traverseType $ Enum t' v rs + where + -- default to a 32 bit logic + t' = IntegerVector TLogic sg rl' + rl' = if null rl + then [(Number "31", Number "0")] + else rl traverseType (Enum t v rs) = do - let baseType = toBaseType t - 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) + let (tf, rl) = typeRanges t + rlParam <- case rl of + [ ] -> return [(Number "0", Number "0")] + [_] -> return rl + _ -> error $ "unexpected multi-dim enum type: " ++ show (Enum t v rs) + tell $ Set.singleton (tf rlParam, v) -- type of localparams + return $ tf (rl ++ rs) -- type of variables traverseType other = return other -simplifyRange :: Range -> Range -simplifyRange (a, b) = (simplify a, simplify b) - makeEnumItems :: EnumInfo -> [PackageItem] -makeEnumItems (mr, l) = +makeEnumItems (itemType, l) = -- check for obviously duplicate values if noDuplicates then zipWith toPackageItem keys vals @@ -97,8 +88,6 @@ makeEnumItems (mr, l) = step _ (Just expr) = expr step expr Nothing = simplify $ BinOp Add expr (Number "1") - rs = maybe [] (\a -> [a]) mr - itemType = Implicit Unspecified rs toPackageItem :: Identifier -> Expr -> PackageItem toPackageItem x v = Decl $ Param Localparam itemType x v' diff --git a/src/Convert/Package.hs b/src/Convert/Package.hs index a9a1bc7..73b3df6 100644 --- a/src/Convert/Package.hs +++ b/src/Convert/Package.hs @@ -95,7 +95,7 @@ prefixPackageItem packageName idents item = Decl (ParamType a x b ) -> Decl (ParamType a (prefix x) b ) other -> other convertType (Alias Nothing x rs) = Alias Nothing (prefix x) rs - convertType (Enum mt items rs) = Enum mt items' rs + convertType (Enum t items rs) = Enum t items' rs where items' = map prefixItem items prefixItem (x, me) = (prefix x, me) diff --git a/src/Convert/Traverse.hs b/src/Convert/Traverse.hs index 56e9aa0..cd42470 100644 --- a/src/Convert/Traverse.hs +++ b/src/Convert/Traverse.hs @@ -857,11 +857,9 @@ traverseNestedTypesM mapper = fullMapper tm (NonInteger kw ) = return $ NonInteger kw tm (TypeOf expr ) = return $ TypeOf expr tm (InterfaceT x my r) = return $ InterfaceT x my r - tm (Enum Nothing vals r) = - return $ Enum Nothing vals r - tm (Enum (Just t) vals r) = do + tm (Enum t vals r) = do t' <- fullMapper t - return $ Enum (Just t') vals r + return $ Enum t' vals r tm (Struct p fields r) = do types <- mapM fullMapper $ map fst fields let idents = map snd fields diff --git a/src/Convert/Typedef.hs b/src/Convert/Typedef.hs index 4f41d97..e44a097 100644 --- a/src/Convert/Typedef.hs +++ b/src/Convert/Typedef.hs @@ -81,11 +81,10 @@ resolveType _ (IntegerVector kw sg rs) = IntegerVector kw sg rs resolveType _ (IntegerAtom kw sg ) = IntegerAtom kw sg resolveType _ (NonInteger kw ) = NonInteger kw resolveType _ (InterfaceT x my rs) = InterfaceT x my rs -resolveType _ (Enum Nothing vals rs) = Enum Nothing vals rs resolveType _ (Alias (Just ps) st rs) = Alias (Just ps) st rs resolveType _ (TypeOf expr) = TypeOf expr resolveType _ (UnpackedType t rs) = UnpackedType t rs -resolveType types (Enum (Just t) vals rs) = Enum (Just $ resolveType types t) vals rs +resolveType types (Enum t vals rs) = Enum (resolveType types t) vals rs resolveType types (Struct p items rs) = Struct p (map (resolveItem types) items) rs resolveType types (Union p items rs) = Union p (map (resolveItem types) items) rs resolveType types (Alias Nothing st rs1) = diff --git a/src/Language/SystemVerilog/AST/Type.hs b/src/Language/SystemVerilog/AST/Type.hs index 0e5f3dd..8f52ddb 100644 --- a/src/Language/SystemVerilog/AST/Type.hs +++ b/src/Language/SystemVerilog/AST/Type.hs @@ -43,7 +43,7 @@ data Type | Net NetTypeAndStrength Signing [Range] | Implicit Signing [Range] | Alias (Maybe Identifier) Identifier [Range] - | Enum (Maybe Type) [Item] [Range] + | Enum Type [Item] [Range] | Struct Packing [Field] [Range] | Union Packing [Field] [Range] | InterfaceT Identifier (Maybe Identifier) [Range] @@ -60,9 +60,9 @@ instance Show Type where show (NonInteger kw ) = printf "%s" (show kw) show (InterfaceT x my r) = x ++ yStr ++ (showRanges r) where yStr = maybe "" ("."++) my - show (Enum mt vals r) = printf "enum %s{%s}%s" tStr (commas $ map showVal vals) (showRanges r) + show (Enum t vals r) = printf "enum %s{%s}%s" tStr (commas $ map showVal vals) (showRanges r) where - tStr = maybe "" showPad mt + tStr = showPad t showVal :: (Identifier, Maybe Expr) -> String showVal (x, e) = x ++ (showAssignment e) show (Struct p items r) = printf "struct %s{\n%s\n}%s" (showPad p) (showFields items) (showRanges r) diff --git a/src/Language/SystemVerilog/Parser/Parse.y b/src/Language/SystemVerilog/Parser/Parse.y index ef27fab..b11cbb0 100644 --- a/src/Language/SystemVerilog/Parser/Parse.y +++ b/src/Language/SystemVerilog/Parser/Parse.y @@ -462,9 +462,9 @@ CastingType :: { Type } | IntegerAtomType { IntegerAtom $1 Unspecified } | NonIntegerType { NonInteger $1 } | Signing { Implicit $1 [] } -EnumBaseType :: { Maybe Type } - : opt(Type) { $1 } - | DimensionsNonEmpty { Just $ Implicit Unspecified $1 } +EnumBaseType :: { Type } + : Type { $1 } + | Dimensions { Implicit Unspecified $1 } NetTypeAndStrength :: { NetTypeAndStrength } : NetType %prec "+" { NetType $1 } diff --git a/test/basic/enum.sv b/test/basic/enum.sv index 8d47efe..d7c4c52 100644 --- a/test/basic/enum.sv +++ b/test/basic/enum.sv @@ -45,14 +45,9 @@ typedef enum int { `define PRINT(name, val) \ dummy``name = name``_``val; \ - $display("%h %h %0d %0d", \ + $display(`"name %h %h %0d %0d`", \ name``_``val, dummy``name, $bits(name``_``val), $bits(dummy``name)); -`define PRINT_UNSIZED(name, val) \ - dummy``name = name``_``val; \ - $display("%h %h %0d", \ - name``_``val, dummy``name, $bits(dummy``name)); - module top; EnumA dummyA; EnumB dummyB; @@ -95,11 +90,11 @@ module top; `PRINT(G, 1) `PRINT(G, 2) - `PRINT_UNSIZED(H, 1) - `PRINT_UNSIZED(H, 2) + `PRINT(H, 1) + `PRINT(H, 2) - `PRINT_UNSIZED(I, 1) - `PRINT_UNSIZED(I, 2) + `PRINT(I, 1) + `PRINT(I, 2) end diff --git a/test/basic/enum.v b/test/basic/enum.v index a390ba6..b53d314 100644 --- a/test/basic/enum.v +++ b/test/basic/enum.v @@ -1,13 +1,8 @@ `define PRINT(name, val) \ dummy``name = val; \ - $display("%h %h %0d %0d", \ + $display(`"name %h %h %0d %0d`", \ val, dummy``name, $bits(val), $bits(dummy``name)); -`define PRINT_UNSIZED(name, val) \ - dummy``name = val; \ - $display("%h %h %0d", \ - val, dummy``name, $bits(dummy``name)); - module top; reg [31:0] dummyA; @@ -15,7 +10,7 @@ module top; reg [31:0] dummyC; reg [31:0] dummyD; reg [31:0] dummyE; - reg [0:0] dummyF; + reg dummyF; reg [0:0] dummyG; reg [3:0] dummyH; reg [31:0] dummyI; @@ -51,11 +46,11 @@ module top; `PRINT(G, 1'b0) `PRINT(G, 1'b1) - `PRINT_UNSIZED(H, 'b1) - `PRINT_UNSIZED(H, 'b0) + `PRINT(H, 4'b1) + `PRINT(H, 4'b0) - `PRINT_UNSIZED(I, 'b0) - `PRINT_UNSIZED(I, 'b1) + `PRINT(I, 'b0) + `PRINT(I, 'b1) end