mirror of https://github.com/zachjs/sv2v.git
fix non-vector enum base types (closes #29)
This commit is contained in:
parent
ad0db916cc
commit
9cc211d51e
|
|
@ -28,10 +28,10 @@ import qualified Data.Set as Set
|
||||||
import Convert.Traverse
|
import Convert.Traverse
|
||||||
import Language.SystemVerilog.AST
|
import Language.SystemVerilog.AST
|
||||||
|
|
||||||
type EnumInfo = (Range, [(Identifier, Maybe Expr)])
|
type EnumInfo = (Maybe Range, [(Identifier, Maybe Expr)])
|
||||||
type Enums = Set.Set EnumInfo
|
type Enums = Set.Set EnumInfo
|
||||||
type Idents = Set.Set Identifier
|
type Idents = Set.Set Identifier
|
||||||
type EnumItem = ((Range, Identifier), Expr)
|
type EnumItem = ((Maybe Range, Identifier), Expr)
|
||||||
|
|
||||||
convert :: [AST] -> [AST]
|
convert :: [AST] -> [AST]
|
||||||
convert = map $ traverseDescriptions convertDescription
|
convert = map $ traverseDescriptions convertDescription
|
||||||
|
|
@ -90,11 +90,19 @@ convergeUsage items enums =
|
||||||
collectIdent _ = return ()
|
collectIdent _ = return ()
|
||||||
|
|
||||||
toItem :: EnumItem -> PackageItem
|
toItem :: EnumItem -> PackageItem
|
||||||
toItem ((r, x), v) =
|
toItem ((mr, x), v) =
|
||||||
Decl $ Localparam itemType x v'
|
Decl $ Localparam itemType x v'
|
||||||
where
|
where
|
||||||
v' = sizedExpr x r (simplify v)
|
v' = if mr == Nothing
|
||||||
itemType = Implicit Unspecified [r]
|
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 :: Maybe Type -> Type
|
||||||
toBaseType Nothing = defaultType
|
toBaseType Nothing = defaultType
|
||||||
|
|
@ -110,9 +118,14 @@ toBaseType (Just t) =
|
||||||
traverseType :: Type -> Writer Enums Type
|
traverseType :: Type -> Writer Enums Type
|
||||||
traverseType (Enum t v rs) = do
|
traverseType (Enum t v rs) = do
|
||||||
let baseType = toBaseType t
|
let baseType = toBaseType t
|
||||||
let (tf, [r]) = typeRanges baseType
|
let (tf, rl) = typeRanges baseType
|
||||||
() <- tell $ Set.singleton (simplifyRange r, v)
|
mr <- return $ case rl of
|
||||||
return $ tf (r : rs)
|
[] -> 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
|
traverseType other = return other
|
||||||
|
|
||||||
simplifyRange :: Range -> Range
|
simplifyRange :: Range -> Range
|
||||||
|
|
@ -126,7 +139,7 @@ traverseExpr (Cast (Left (Enum _ _ _)) e) = e
|
||||||
traverseExpr other = other
|
traverseExpr other = other
|
||||||
|
|
||||||
enumVals :: EnumInfo -> [EnumItem]
|
enumVals :: EnumInfo -> [EnumItem]
|
||||||
enumVals (r, l) =
|
enumVals (mr, l) =
|
||||||
-- check for obviously duplicate values
|
-- check for obviously duplicate values
|
||||||
if noDuplicates
|
if noDuplicates
|
||||||
then res
|
then res
|
||||||
|
|
@ -135,7 +148,7 @@ enumVals (r, l) =
|
||||||
where
|
where
|
||||||
keys = map fst l
|
keys = map fst l
|
||||||
vals = tail $ scanl step (Number "-1") (map snd 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
|
noDuplicates = all (null . tail . flip elemIndices vals) vals
|
||||||
step :: Expr -> Maybe Expr -> Expr
|
step :: Expr -> Maybe Expr -> Expr
|
||||||
step _ (Just expr) = expr
|
step _ (Just expr) = expr
|
||||||
|
|
|
||||||
|
|
@ -84,13 +84,19 @@ typeRanges (Alias ps xx rs) = (Alias ps xx , rs)
|
||||||
typeRanges (Net kw rs) = (Net kw , rs)
|
typeRanges (Net kw rs) = (Net kw , rs)
|
||||||
typeRanges (Implicit sg rs) = (Implicit sg, rs)
|
typeRanges (Implicit sg rs) = (Implicit sg, rs)
|
||||||
typeRanges (IntegerVector kw sg rs) = (IntegerVector kw sg, rs)
|
typeRanges (IntegerVector kw sg rs) = (IntegerVector kw sg, rs)
|
||||||
typeRanges (IntegerAtom kw sg ) = (\[] -> IntegerAtom kw sg, [])
|
typeRanges (IntegerAtom kw sg ) = (nullRange $ IntegerAtom kw sg, [])
|
||||||
typeRanges (NonInteger kw ) = (\[] -> NonInteger kw , [])
|
typeRanges (NonInteger kw ) = (nullRange $ NonInteger kw , [])
|
||||||
typeRanges (Enum t v r) = (Enum t v, r)
|
typeRanges (Enum t v r) = (Enum t v, r)
|
||||||
typeRanges (Struct p l r) = (Struct p l, r)
|
typeRanges (Struct p l r) = (Struct p l, r)
|
||||||
typeRanges (Union p l r) = (Union p l, r)
|
typeRanges (Union p l r) = (Union p l, r)
|
||||||
typeRanges (InterfaceT x my r) = (InterfaceT x my, 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
|
data Signing
|
||||||
= Unspecified
|
= Unspecified
|
||||||
| Signed
|
| Signed
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
Loading…
Reference in New Issue