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) =
Number n ->
case elemIndex '\'' n of
Nothing -> Number "32"
Just 0 -> Number "32"
Just idx -> Number $ take idx n
_ -> DimsFn FnBits $ Left $ TypeOf e
......@@ -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'
......
......@@ -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)
......
......@@ -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
......
......@@ -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) =
......
......@@ -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)
......
......@@ -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 }
......
......@@ -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
......
`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
......
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