Commit ae392d45 by Zachary Snow

fix single bit enum sizing

- single bit localparams retain explicit range
- fix $bits on unsized literals
- use Implicit over Maybe for underlying type
parent 97b2d1d1
...@@ -134,5 +134,6 @@ convertBits (Right e) = ...@@ -134,5 +134,6 @@ convertBits (Right e) =
Number n -> Number n ->
case elemIndex '\'' n of case elemIndex '\'' n of
Nothing -> Number "32" Nothing -> Number "32"
Just 0 -> Number "32"
Just idx -> Number $ take idx n Just idx -> Number $ take idx n
_ -> DimsFn FnBits $ Left $ TypeOf e _ -> DimsFn FnBits $ Left $ TypeOf e
...@@ -26,15 +26,12 @@ import qualified Data.Set as Set ...@@ -26,15 +26,12 @@ import qualified Data.Set as Set
import Convert.Traverse import Convert.Traverse
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
type EnumInfo = (Maybe Range, [(Identifier, Maybe Expr)]) type EnumInfo = (Type, [(Identifier, Maybe Expr)])
type Enums = Set.Set EnumInfo type Enums = Set.Set EnumInfo
convert :: [AST] -> [AST] convert :: [AST] -> [AST]
convert = map $ concatMap convertDescription convert = map $ concatMap convertDescription
defaultType :: Type
defaultType = IntegerVector TLogic Unspecified [(Number "31", Number "0")]
convertDescription :: Description -> [Description] convertDescription :: Description -> [Description]
convertDescription (description @ Package{}) = convertDescription (description @ Package{}) =
[Package ml name (items ++ enumItems)] [Package ml name (items ++ enumItems)]
...@@ -54,36 +51,30 @@ convertDescription' description = ...@@ -54,36 +51,30 @@ convertDescription' description =
-- convert the collected enums into their corresponding localparams -- convert the collected enums into their corresponding localparams
enumItems = concatMap makeEnumItems $ Set.toList enums 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 -- replace, but write down, enum types
traverseType :: Type -> Writer Enums Type 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 traverseType (Enum t v rs) = do
let baseType = toBaseType t let (tf, rl) = typeRanges t
let (tf, rl) = typeRanges baseType rlParam <- case rl of
mr <- return $ case rl of [ ] -> return [(Number "0", Number "0")]
[] -> Nothing [_] -> return rl
[r] -> Just r _ -> error $ "unexpected multi-dim enum type: " ++ show (Enum t v rs)
_ -> error $ "unexpected multi-dim enum type: " tell $ Set.singleton (tf rlParam, v) -- type of localparams
++ show (Enum t v rs) return $ tf (rl ++ rs) -- type of variables
() <- tell $ Set.singleton (fmap simplifyRange mr, v)
return $ tf (rl ++ rs)
traverseType other = return other traverseType other = return other
simplifyRange :: Range -> Range
simplifyRange (a, b) = (simplify a, simplify b)
makeEnumItems :: EnumInfo -> [PackageItem] makeEnumItems :: EnumInfo -> [PackageItem]
makeEnumItems (mr, l) = makeEnumItems (itemType, l) =
-- check for obviously duplicate values -- check for obviously duplicate values
if noDuplicates if noDuplicates
then zipWith toPackageItem keys vals then zipWith toPackageItem keys vals
...@@ -97,8 +88,6 @@ makeEnumItems (mr, l) = ...@@ -97,8 +88,6 @@ makeEnumItems (mr, l) =
step _ (Just expr) = expr step _ (Just expr) = expr
step expr Nothing = step expr Nothing =
simplify $ BinOp Add expr (Number "1") simplify $ BinOp Add expr (Number "1")
rs = maybe [] (\a -> [a]) mr
itemType = Implicit Unspecified rs
toPackageItem :: Identifier -> Expr -> PackageItem toPackageItem :: Identifier -> Expr -> PackageItem
toPackageItem x v = toPackageItem x v =
Decl $ Param Localparam itemType x v' Decl $ Param Localparam itemType x v'
......
...@@ -95,7 +95,7 @@ prefixPackageItem packageName idents item = ...@@ -95,7 +95,7 @@ prefixPackageItem packageName idents item =
Decl (ParamType a x b ) -> Decl (ParamType a (prefix x) b ) Decl (ParamType a x b ) -> Decl (ParamType a (prefix x) b )
other -> other other -> other
convertType (Alias Nothing x rs) = Alias Nothing (prefix x) rs 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 where
items' = map prefixItem items items' = map prefixItem items
prefixItem (x, me) = (prefix x, me) prefixItem (x, me) = (prefix x, me)
......
...@@ -857,11 +857,9 @@ traverseNestedTypesM mapper = fullMapper ...@@ -857,11 +857,9 @@ traverseNestedTypesM mapper = fullMapper
tm (NonInteger kw ) = return $ NonInteger kw tm (NonInteger kw ) = return $ NonInteger kw
tm (TypeOf expr ) = return $ TypeOf expr tm (TypeOf expr ) = return $ TypeOf expr
tm (InterfaceT x my r) = return $ InterfaceT x my r tm (InterfaceT x my r) = return $ InterfaceT x my r
tm (Enum Nothing vals r) = tm (Enum t vals r) = do
return $ Enum Nothing vals r
tm (Enum (Just t) vals r) = do
t' <- fullMapper t t' <- fullMapper t
return $ Enum (Just t') vals r return $ Enum t' vals r
tm (Struct p fields r) = do tm (Struct p fields r) = do
types <- mapM fullMapper $ map fst fields types <- mapM fullMapper $ map fst fields
let idents = map snd fields let idents = map snd fields
......
...@@ -81,11 +81,10 @@ resolveType _ (IntegerVector kw sg rs) = IntegerVector kw sg rs ...@@ -81,11 +81,10 @@ resolveType _ (IntegerVector kw sg rs) = IntegerVector kw sg rs
resolveType _ (IntegerAtom kw sg ) = IntegerAtom kw sg resolveType _ (IntegerAtom kw sg ) = IntegerAtom kw sg
resolveType _ (NonInteger kw ) = NonInteger kw resolveType _ (NonInteger kw ) = NonInteger kw
resolveType _ (InterfaceT x my rs) = InterfaceT x my rs 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 _ (Alias (Just ps) st rs) = Alias (Just ps) st rs
resolveType _ (TypeOf expr) = TypeOf expr resolveType _ (TypeOf expr) = TypeOf expr
resolveType _ (UnpackedType t rs) = UnpackedType t rs 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 (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 (Union p items rs) = Union p (map (resolveItem types) items) rs
resolveType types (Alias Nothing st rs1) = resolveType types (Alias Nothing st rs1) =
......
...@@ -43,7 +43,7 @@ data Type ...@@ -43,7 +43,7 @@ data Type
| Net NetTypeAndStrength Signing [Range] | Net NetTypeAndStrength Signing [Range]
| Implicit Signing [Range] | Implicit Signing [Range]
| Alias (Maybe Identifier) Identifier [Range] | Alias (Maybe Identifier) Identifier [Range]
| Enum (Maybe Type) [Item] [Range] | Enum Type [Item] [Range]
| Struct Packing [Field] [Range] | Struct Packing [Field] [Range]
| Union Packing [Field] [Range] | Union Packing [Field] [Range]
| InterfaceT Identifier (Maybe Identifier) [Range] | InterfaceT Identifier (Maybe Identifier) [Range]
...@@ -60,9 +60,9 @@ instance Show Type where ...@@ -60,9 +60,9 @@ instance Show Type where
show (NonInteger kw ) = printf "%s" (show kw) show (NonInteger kw ) = printf "%s" (show kw)
show (InterfaceT x my r) = x ++ yStr ++ (showRanges r) show (InterfaceT x my r) = x ++ yStr ++ (showRanges r)
where yStr = maybe "" ("."++) my 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 where
tStr = maybe "" showPad mt tStr = showPad t
showVal :: (Identifier, Maybe Expr) -> String showVal :: (Identifier, Maybe Expr) -> String
showVal (x, e) = x ++ (showAssignment e) showVal (x, e) = x ++ (showAssignment e)
show (Struct p items r) = printf "struct %s{\n%s\n}%s" (showPad p) (showFields items) (showRanges r) show (Struct p items r) = printf "struct %s{\n%s\n}%s" (showPad p) (showFields items) (showRanges r)
......
...@@ -462,9 +462,9 @@ CastingType :: { Type } ...@@ -462,9 +462,9 @@ CastingType :: { Type }
| IntegerAtomType { IntegerAtom $1 Unspecified } | IntegerAtomType { IntegerAtom $1 Unspecified }
| NonIntegerType { NonInteger $1 } | NonIntegerType { NonInteger $1 }
| Signing { Implicit $1 [] } | Signing { Implicit $1 [] }
EnumBaseType :: { Maybe Type } EnumBaseType :: { Type }
: opt(Type) { $1 } : Type { $1 }
| DimensionsNonEmpty { Just $ Implicit Unspecified $1 } | Dimensions { Implicit Unspecified $1 }
NetTypeAndStrength :: { NetTypeAndStrength } NetTypeAndStrength :: { NetTypeAndStrength }
: NetType %prec "+" { NetType $1 } : NetType %prec "+" { NetType $1 }
......
...@@ -45,14 +45,9 @@ typedef enum int { ...@@ -45,14 +45,9 @@ typedef enum int {
`define PRINT(name, val) \ `define PRINT(name, val) \
dummy``name = 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)); 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; module top;
EnumA dummyA; EnumA dummyA;
EnumB dummyB; EnumB dummyB;
...@@ -95,11 +90,11 @@ module top; ...@@ -95,11 +90,11 @@ module top;
`PRINT(G, 1) `PRINT(G, 1)
`PRINT(G, 2) `PRINT(G, 2)
`PRINT_UNSIZED(H, 1) `PRINT(H, 1)
`PRINT_UNSIZED(H, 2) `PRINT(H, 2)
`PRINT_UNSIZED(I, 1) `PRINT(I, 1)
`PRINT_UNSIZED(I, 2) `PRINT(I, 2)
end end
......
`define PRINT(name, val) \ `define PRINT(name, val) \
dummy``name = val; \ dummy``name = val; \
$display("%h %h %0d %0d", \ $display(`"name %h %h %0d %0d`", \
val, dummy``name, $bits(val), $bits(dummy``name)); 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; module top;
reg [31:0] dummyA; reg [31:0] dummyA;
...@@ -15,7 +10,7 @@ module top; ...@@ -15,7 +10,7 @@ module top;
reg [31:0] dummyC; reg [31:0] dummyC;
reg [31:0] dummyD; reg [31:0] dummyD;
reg [31:0] dummyE; reg [31:0] dummyE;
reg [0:0] dummyF; reg dummyF;
reg [0:0] dummyG; reg [0:0] dummyG;
reg [3:0] dummyH; reg [3:0] dummyH;
reg [31:0] dummyI; reg [31:0] dummyI;
...@@ -51,11 +46,11 @@ module top; ...@@ -51,11 +46,11 @@ module top;
`PRINT(G, 1'b0) `PRINT(G, 1'b0)
`PRINT(G, 1'b1) `PRINT(G, 1'b1)
`PRINT_UNSIZED(H, 'b1) `PRINT(H, 4'b1)
`PRINT_UNSIZED(H, 'b0) `PRINT(H, 4'b0)
`PRINT_UNSIZED(I, 'b0) `PRINT(I, 'b0)
`PRINT_UNSIZED(I, 'b1) `PRINT(I, 'b1)
end end
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment