Commit 85e3d0f5 by Zachary Snow

initial generate block scoping support

- significant refactor of struct conversion
- significant refactor of typedef conversion
- scoping support in multipack conversion
- scoping support in typeof conversion
parent 211e4b0e
{-# LANGUAGE TupleSections #-}
{- sv2v
- Author: Zachary Snow <zach@zachjs.com>
-
......@@ -25,42 +26,34 @@
module Convert.MultiplePacked (convert) where
import Control.Monad.State
import Control.Monad ((>=>))
import Data.Tuple (swap)
import Data.Maybe (isJust)
import qualified Data.Map.Strict as Map
import Convert.Scoper
import Convert.Traverse
import Language.SystemVerilog.AST
type TypeInfo = (Type, [Range])
type Info = Map.Map Identifier TypeInfo
convert :: [AST] -> [AST]
convert = map $ traverseDescriptions convertDescription
convertDescription :: Description -> Description
convertDescription part @ Part{} =
scopedConversion traverseDeclM traverseModuleItemM traverseStmtM
instances part'
where
(part', instances) = runState
(traverseModuleItemsM traverseInstancesM part) Map.empty
convertDescription other = other
convert = map $ traverseDescriptions $ partScoper
traverseDeclM traverseModuleItemM traverseGenItemM traverseStmtM
-- collects and converts declarations with multiple packed dimensions
traverseDeclM :: Decl -> State Info Decl
traverseDeclM :: Decl -> Scoper TypeInfo Decl
traverseDeclM (Variable dir t ident a e) = do
t' <- traverseTypeM t a ident
return $ Variable dir t' ident a e
traverseDeclExprsM traverseExprM $ Variable dir t' ident a e
traverseDeclM (Param s t ident e) = do
t' <- traverseTypeM t [] ident
return $ Param s t' ident e
traverseDeclM other = return other
traverseDeclExprsM traverseExprM $ Param s t' ident e
traverseDeclM other = traverseDeclExprsM traverseExprM other
traverseTypeM :: Type -> [Range] -> Identifier -> State Info Type
traverseTypeM :: Type -> [Range] -> Identifier -> Scoper TypeInfo Type
traverseTypeM t a ident = do
modify $ Map.insert ident (t, a)
insertElem ident (t, a)
t' <- case t of
Struct pk fields rs -> do
fields' <- flattenFields fields
......@@ -82,18 +75,20 @@ traverseTypeM t a ident = do
fieldTypes' <- mapM (\x -> traverseTypeM x [] "") fieldTypes
return $ zip fieldTypes' fieldNames
-- converts multi-dimensional instances
traverseInstancesM :: ModuleItem -> State Info ModuleItem
traverseInstancesM (Instance m p x rs l) = do
traverseModuleItemM :: ModuleItem -> Scoper TypeInfo ModuleItem
traverseModuleItemM (Instance m p x rs l) = do
-- converts multi-dimensional instances
rs' <- if length rs <= 1
then return rs
else do
let t = Implicit Unspecified rs
modify $ Map.insert x (t, [])
insertElem x (t, [])
let r1 : r2 : rest = rs
return $ (combineRanges r1 r2) : rest
return $ Instance m p x rs' l
traverseInstancesM other = return other
traverseExprsM traverseExprM $ Instance m p x rs' l
traverseModuleItemM item =
traverseLHSsM traverseLHSM item >>=
traverseExprsM traverseExprM
-- combines two ranges into one flattened range
combineRanges :: Range -> Range -> Range
......@@ -117,37 +112,38 @@ combineRanges r1 r2 = r
upper = BinOp Add (BinOp Mul size1 size2)
(BinOp Sub lower (Number "1"))
traverseModuleItemM :: ModuleItem -> State Info ModuleItem
traverseModuleItemM =
traverseLHSsM traverseLHSM >=>
traverseExprsM traverseExprM
traverseStmtM :: Stmt -> State Info Stmt
traverseStmtM :: Stmt -> Scoper TypeInfo Stmt
traverseStmtM =
traverseStmtLHSsM traverseLHSM >=>
traverseStmtExprsM traverseExprM
traverseExprM :: Expr -> State Info Expr
traverseExprM = traverseNestedExprsM $ stately traverseExpr
traverseExprM :: Expr -> Scoper TypeInfo Expr
traverseExprM = traverseNestedExprsM convertExprM
traverseGenItemM :: GenItem -> Scoper TypeInfo GenItem
traverseGenItemM = traverseGenItemExprsM traverseExprM
-- LHSs need to be converted too. Rather than duplicating the procedures, we
-- turn LHSs into expressions temporarily and use the expression conversion.
traverseLHSM :: LHS -> State Info LHS
traverseLHSM :: LHS -> Scoper TypeInfo LHS
traverseLHSM = traverseNestedLHSsM traverseLHSSingleM
where
-- We can't use traverseExprM directly because that would cause Exprs
-- inside of LHSs to be converted twice in a single cycle!
traverseLHSSingleM :: LHS -> State Info LHS
traverseLHSSingleM :: LHS -> Scoper TypeInfo LHS
traverseLHSSingleM lhs = do
let expr = lhsToExpr lhs
expr' <- stately traverseExpr expr
expr' <- convertExprM expr
case exprToLHS expr' of
Just lhs' -> return lhs'
Nothing -> error $ "multi-packed conversion created non-LHS from "
++ (show expr) ++ " to " ++ (show expr')
traverseExpr :: Info -> Expr -> Expr
traverseExpr typeMap =
convertExprM :: Expr -> Scoper TypeInfo Expr
convertExprM = embedScopes convertExpr
convertExpr :: Scopes TypeInfo -> Expr -> Expr
convertExpr scopes =
rewriteExpr
where
-- removes the innermost dimensions of the given type information, and
......@@ -165,19 +161,17 @@ traverseExpr typeMap =
-- given an expression, returns its type information and a tagged
-- version of the expression, if possible
levels :: Expr -> Maybe (TypeInfo, Expr)
levels (Ident x) =
case Map.lookup x typeMap of
Just a -> Just (a, Ident $ tag : x)
Nothing -> Nothing
levels (Bit expr a) =
fmap (dropLevel $ \expr' -> Bit expr' a) (levels expr)
case levels expr of
Just info -> Just $ dropLevel (\expr' -> Bit expr' a) info
Nothing -> fallbackLevels $ Bit expr a
levels (Range expr a b) =
fmap (dropLevel $ \expr' -> Range expr' a b) (levels expr)
levels (Dot expr x) =
case levels expr of
Just ((Struct _ fields [], []), expr') -> dropDot fields expr'
Just ((Union _ fields [], []), expr') -> dropDot fields expr'
_ -> Nothing
_ -> fallbackLevels $ Dot expr x
where
dropDot :: [Field] -> Expr -> Maybe (TypeInfo, Expr)
dropDot fields expr' =
......@@ -187,7 +181,14 @@ traverseExpr typeMap =
where
fieldMap = Map.fromList $ map swap fields
fieldType = fieldMap Map.! x
levels _ = Nothing
levels expr = fallbackLevels expr
fallbackLevels :: Expr -> Maybe (TypeInfo, Expr)
fallbackLevels expr =
fmap ((, expr) . thd3) res
where
res = lookupExpr scopes expr
thd3 (_, _, c) = c
-- given an expression, returns the two most significant (innermost,
-- leftmost) packed dimensions and a tagged version of the expression,
......
......@@ -57,6 +57,12 @@ module Convert.Traverse
, traverseTypeExprsM
, traverseTypeExprs
, collectTypeExprsM
, traverseGenItemExprsM
, traverseGenItemExprs
, collectGenItemExprsM
, traverseDeclExprsM
, traverseDeclExprs
, collectDeclExprsM
, traverseDeclTypesM
, traverseDeclTypes
, collectDeclTypesM
......@@ -97,6 +103,8 @@ module Convert.Traverse
, stately
, traverseFilesM
, traverseFiles
, traverseSinglyNestedGenItemsM
, traverseSinglyNestedStmtsM
) where
import Data.Functor.Identity (Identity, runIdentity)
......@@ -407,7 +415,7 @@ traverseNestedExprsM :: Monad m => MapperM m Expr -> MapperM m Expr
traverseNestedExprsM mapper = exprMapper
where
exprMapper = mapper >=> em
(_, _, _, typeMapper) = exprMapperHelpers exprMapper
(_, _, _, typeMapper, _) = exprMapperHelpers exprMapper
typeOrExprMapper (Left t) =
typeMapper t >>= return . Left
typeOrExprMapper (Right e) =
......@@ -489,9 +497,19 @@ traverseNestedExprsM mapper = exprMapper
em (Nil) = return Nil
exprMapperHelpers :: Monad m => MapperM m Expr ->
(MapperM m Range, MapperM m Decl, MapperM m LHS, MapperM m Type)
( MapperM m Range
, MapperM m Decl
, MapperM m LHS
, MapperM m Type
, MapperM m GenItem
)
exprMapperHelpers exprMapper =
(rangeMapper, declMapper, traverseNestedLHSsM lhsMapper, typeMapper)
( rangeMapper
, declMapper
, traverseNestedLHSsM lhsMapper
, typeMapper
, genItemMapper
)
where
rangeMapper (a, b) = do
......@@ -535,11 +553,26 @@ exprMapperHelpers exprMapper =
return $ LHSStream o e' ls
lhsMapper other = return other
genItemMapper (GenFor (x1, e1) cc (x2, op2, e2) subItem) = do
e1' <- exprMapper e1
e2' <- exprMapper e2
cc' <- exprMapper cc
return $ GenFor (x1, e1') cc' (x2, op2, e2') subItem
genItemMapper (GenIf e i1 i2) = do
e' <- exprMapper e
return $ GenIf e' i1 i2
genItemMapper (GenCase e cases) = do
e' <- exprMapper e
caseExprs <- mapM (mapM exprMapper . fst) cases
let cases' = zip caseExprs (map snd cases)
return $ GenCase e' cases'
genItemMapper other = return other
traverseExprsM' :: Monad m => TFStrategy -> MapperM m Expr -> MapperM m ModuleItem
traverseExprsM' strat exprMapper = moduleItemMapper
where
(rangeMapper, declMapper, lhsMapper, typeMapper)
(rangeMapper, declMapper, lhsMapper, typeMapper, genItemMapper)
= exprMapperHelpers exprMapper
stmtMapper = traverseNestedStmtsM (traverseStmtExprsM exprMapper)
......@@ -632,21 +665,6 @@ traverseExprsM' strat exprMapper = moduleItemMapper
a'' <- traverseAssertionExprsM exprMapper a'
return $ AssertionItem (mx, a'')
genItemMapper (GenFor (x1, e1) cc (x2, op2, e2) subItem) = do
e1' <- exprMapper e1
e2' <- exprMapper e2
cc' <- exprMapper cc
return $ GenFor (x1, e1') cc' (x2, op2, e2') subItem
genItemMapper (GenIf e i1 i2) = do
e' <- exprMapper e
return $ GenIf e' i1 i2
genItemMapper (GenCase e cases) = do
e' <- exprMapper e
caseExprs <- mapM (mapM exprMapper . fst) cases
let cases' = zip caseExprs (map snd cases)
return $ GenCase e' cases'
genItemMapper other = return other
modportDeclMapper (dir, ident, t, e) = do
t' <- typeMapper t
e' <- exprMapper e
......@@ -668,7 +686,7 @@ traverseStmtExprsM :: Monad m => MapperM m Expr -> MapperM m Stmt
traverseStmtExprsM exprMapper = flatStmtMapper
where
(_, declMapper, lhsMapper, _) = exprMapperHelpers exprMapper
(_, declMapper, lhsMapper, _, _) = exprMapperHelpers exprMapper
caseMapper (exprs, stmt) = do
exprs' <- mapM exprMapper exprs
......@@ -888,13 +906,33 @@ collectExprTypesM = collectify traverseExprTypesM
traverseTypeExprsM :: Monad m => MapperM m Expr -> MapperM m Type
traverseTypeExprsM mapper =
typeMapper
where (_, _, _, typeMapper) = exprMapperHelpers mapper
where (_, _, _, typeMapper, _) = exprMapperHelpers mapper
traverseTypeExprs :: Mapper Expr -> Mapper Type
traverseTypeExprs = unmonad traverseTypeExprsM
collectTypeExprsM :: Monad m => CollectorM m Expr -> CollectorM m Type
collectTypeExprsM = collectify traverseTypeExprsM
traverseGenItemExprsM :: Monad m => MapperM m Expr -> MapperM m GenItem
traverseGenItemExprsM mapper =
genItemMapper
where (_, _, _, _, genItemMapper) = exprMapperHelpers mapper
traverseGenItemExprs :: Mapper Expr -> Mapper GenItem
traverseGenItemExprs = unmonad traverseGenItemExprsM
collectGenItemExprsM :: Monad m => CollectorM m Expr -> CollectorM m GenItem
collectGenItemExprsM = collectify traverseGenItemExprsM
traverseDeclExprsM :: Monad m => MapperM m Expr -> MapperM m Decl
traverseDeclExprsM mapper =
declMapper
where (_, declMapper, _, _, _) = exprMapperHelpers mapper
traverseDeclExprs :: Mapper Expr -> Mapper Decl
traverseDeclExprs = unmonad traverseDeclExprsM
collectDeclExprsM :: Monad m => CollectorM m Expr -> CollectorM m Decl
collectDeclExprsM = collectify traverseDeclExprsM
traverseDeclTypesM :: Monad m => MapperM m Type -> MapperM m Decl
traverseDeclTypesM mapper (Param s t x e) =
mapper t >>= \t' -> return $ Param s t' x e
......
......@@ -11,45 +11,27 @@
module Convert.TypeOf (convert) where
import Control.Monad.State
import Data.List (elemIndex)
import Data.Maybe (fromMaybe, mapMaybe)
import Data.Int (Int32)
import Data.Tuple (swap)
import qualified Data.Map.Strict as Map
import Convert.Scoper
import Convert.Traverse
import Language.SystemVerilog.AST
type Info = Map.Map Identifier Type
convert :: [AST] -> [AST]
convert = map $ traverseDescriptions convertDescription
convertDescription :: Description -> Description
convertDescription (description @ Part{}) =
scopedConversion traverseDeclM traverseModuleItemM traverseStmtM
initialState description
where
Part _ _ _ _ _ _ items = description
initialState = Map.fromList $ mapMaybe returnType items
returnType :: ModuleItem -> Maybe (Identifier, Type)
returnType (MIPackageItem (Function _ t f _ _)) =
if t == Implicit Unspecified []
-- functions with no return type implicitly return a single bit
then Just (f, IntegerVector TLogic Unspecified [])
else Just (f, t)
returnType _ = Nothing
convertDescription other = other
convert = map $ traverseDescriptions $ partScoper
traverseDeclM traverseModuleItemM traverseGenItemM traverseStmtM
traverseDeclM :: Decl -> State Info Decl
traverseDeclM :: Decl -> Scoper Type Decl
traverseDeclM decl = do
item <- traverseModuleItemM (MIPackageItem $ Decl decl)
let MIPackageItem (Decl decl') = item
case decl' of
Variable d t ident a e -> do
let t' = injectRanges t a
modify $ Map.insert ident t'
insertElem ident t'
return $ case t' of
UnpackedType t'' a' -> Variable d t'' ident a' e
_ -> Variable d t' ident [] e
......@@ -57,39 +39,58 @@ traverseDeclM decl = do
let t' = if t == Implicit Unspecified []
then IntegerAtom TInteger Unspecified
else t
modify $ Map.insert ident t'
insertElem ident t'
return decl'
ParamType{} -> return decl'
CommentDecl{} -> return decl'
traverseModuleItemM :: ModuleItem -> State Info ModuleItem
traverseModuleItemM item = traverseTypesM traverseTypeM item
traverseModuleItemM :: ModuleItem -> Scoper Type ModuleItem
traverseModuleItemM = traverseTypesM traverseTypeM
traverseGenItemM :: GenItem -> Scoper Type GenItem
traverseGenItemM = traverseGenItemExprsM traverseExprM
traverseStmtM :: Stmt -> Scoper Type Stmt
traverseStmtM = traverseStmtExprsM traverseExprM
traverseStmtM :: Stmt -> State Info Stmt
traverseStmtM =
traverseStmtExprsM $ traverseNestedExprsM $ traverseExprTypesM traverseTypeM
traverseExprM :: Expr -> Scoper Type Expr
traverseExprM = traverseNestedExprsM $ traverseExprTypesM traverseTypeM
traverseTypeM :: Type -> State Info Type
traverseTypeM :: Type -> Scoper Type Type
traverseTypeM (TypeOf expr) = typeof expr
traverseTypeM other = return other
typeof :: Expr -> State Info Type
lookupTypeOf :: Expr -> Scoper Type Type
lookupTypeOf expr = do
details <- lookupExprM expr
case details of
Nothing -> return $ TypeOf expr
-- functions with no return type implicitly return a single bit
Just (_, _, Implicit Unspecified []) ->
return $ IntegerVector TLogic Unspecified []
Just (_, replacements, typ) ->
return $ rewriteType typ
where
rewriteType = traverseNestedTypes $ traverseTypeExprs $
traverseNestedExprs replace
replace :: Expr -> Expr
replace (Ident x) =
Map.findWithDefault (Ident x) x replacements
replace other = other
typeof :: Expr -> Scoper Type Type
typeof (Number n) =
return $ IntegerVector TLogic sg [r]
where
(size, sg) = parseNumber n
r = (Number $ show (size - 1), Number "0")
typeof (orig @ (Ident x)) = do
res <- gets $ Map.lookup x
return $ fromMaybe (TypeOf orig) res
typeof (orig @ (Call (Ident x) _)) = do
res <- gets $ Map.lookup x
return $ fromMaybe (TypeOf orig) res
typeof (Call (Ident x) _) =
typeof $ Ident x
typeof (orig @ (Bit e _)) = do
t <- typeof e
return $ case t of
TypeOf _ -> TypeOf orig
_ -> popRange t
case t of
TypeOf _ -> lookupTypeOf orig
_ -> return $ popRange t
typeof (orig @ (Range e mode r)) = do
t <- typeof e
return $ case t of
......@@ -103,17 +104,18 @@ typeof (orig @ (Range e mode r)) = do
IndexedMinus -> BinOp Add (uncurry (BinOp Sub) r) (Number "1")
typeof (orig @ (Dot e x)) = do
t <- typeof e
return $ case t of
case t of
Struct _ fields [] ->
return $ fieldsType fields
Union _ fields [] ->
return $ fieldsType fields
_ -> lookupTypeOf orig
where
fieldsType :: [Field] -> Type
fieldsType fields =
case lookup x $ map swap fields of
Just typ -> typ
Nothing -> TypeOf orig
_ -> TypeOf orig
typeof (orig @ (Cast (Right (Ident x)) _)) = do
typeMap <- get
if Map.member x typeMap
then return $ typeOfSize (Ident x)
else return $ TypeOf orig
typeof (Cast (Right s) _) = return $ typeOfSize s
typeof (UniOp UniSub e ) = typeof e
typeof (UniOp BitNot e ) = typeof e
......@@ -135,7 +137,7 @@ typeof (Mux _ a b) = return $ largerSizeType a b
typeof (Concat exprs) = return $ typeOfSize $ concatSize exprs
typeof (Repeat reps exprs) = return $ typeOfSize size
where size = BinOp Mul reps (concatSize exprs)
typeof other = return $ TypeOf other
typeof other = lookupTypeOf other
-- determines the size and sign of a number literal
parseNumber :: String -> (Int32, Signing)
......
......@@ -9,108 +9,91 @@
module Convert.Typedef (convert) where
import Control.Monad.Writer
import qualified Data.Map as Map
import Control.Monad ((>=>))
import Convert.Scoper
import Convert.Traverse
import Language.SystemVerilog.AST
type Types = Map.Map Identifier Type
convert :: [AST] -> [AST]
convert = map $ traverseDescriptions convertDescription
convert = map $ traverseDescriptions $ partScoper
traverseDeclM traverseModuleItemM traverseGenItemM traverseStmtM
traverseTypeOrExprM :: TypeOrExpr -> Scoper Type TypeOrExpr
traverseTypeOrExprM (Left (TypeOf (Ident x))) = do
details <- lookupIdentM x
return $ case details of
Nothing -> Left $ TypeOf $ Ident x
Just (_, _, typ) -> Left typ
traverseTypeOrExprM (Right (Ident x)) = do
details <- lookupIdentM x
return $ case details of
Nothing -> Right $ Ident x
Just (_, _, typ) -> Left typ
traverseTypeOrExprM other = return other
convertDescription :: Description -> Description
convertDescription (description @ Part{}) =
traverseModuleItems (convertTypedef types) description'
where
description' =
traverseModuleItems (traverseGenItems convertGenItem) description
types = execWriter $ collectModuleItemsM collectTypedefM description'
convertDescription other = other
traverseExprM :: Expr -> Scoper Type Expr
traverseExprM (Cast v e) = do
v' <- traverseTypeOrExprM v
return $ Cast v' e
traverseExprM (DimsFn f v) = do
v' <- traverseTypeOrExprM v
return $ DimsFn f v'
traverseExprM (DimFn f v e) = do
v' <- traverseTypeOrExprM v
return $ DimFn f v' e
traverseExprM other = return other
convertTypedef :: Types -> ModuleItem -> ModuleItem
convertTypedef types =
removeTypedef .
convertModuleItem .
(traverseExprs $ traverseNestedExprs $ convertExpr) .
(traverseTypes $ resolveType types)
where
removeTypedef :: ModuleItem -> ModuleItem
removeTypedef (MIPackageItem (Typedef _ x)) =
MIPackageItem $ Decl $ CommentDecl $ "removed typedef: " ++ x
removeTypedef other = other
convertTypeOrExpr :: TypeOrExpr -> TypeOrExpr
convertTypeOrExpr (Left (TypeOf (Ident x))) =
if Map.member x types
then Left $ resolveType types (Alias Nothing x [])
else Left $ TypeOf (Ident x)
convertTypeOrExpr (Right (Ident x)) =
if Map.member x types
then Left $ resolveType types (Alias Nothing x [])
else Right $ Ident x
convertTypeOrExpr other = other
convertExpr :: Expr -> Expr
convertExpr (Cast v e) = Cast (convertTypeOrExpr v) e
convertExpr (DimsFn f v) = DimsFn f (convertTypeOrExpr v)
convertExpr (DimFn f v e) = DimFn f (convertTypeOrExpr v) e
convertExpr other = other
convertModuleItem :: ModuleItem -> ModuleItem
convertModuleItem (Instance m params x rs p) =
Instance m (map mapParam params) x rs p
where mapParam (i, v) = (i, convertTypeOrExpr v)
convertModuleItem other = other
traverseModuleItemM :: ModuleItem -> Scoper Type ModuleItem
traverseModuleItemM (MIPackageItem (Typedef t x)) = do
t' <- traverseNestedTypesM traverseTypeM t
insertElem x t'
return $ Generate []
traverseModuleItemM (Instance m params x rs p) = do
let mapParam (i, v) = traverseTypeOrExprM v >>= \v' -> return (i, v')
params' <- mapM mapParam params
traverseModuleItemM' $ Instance m params' x rs p
traverseModuleItemM item = traverseModuleItemM' item
convertGenItem :: GenItem -> GenItem
convertGenItem (GenIf c a b) =
GenIf c a' b'
where
a' = convertGenItem' a
b' = convertGenItem' b
convertGenItem other = other
traverseModuleItemM' :: ModuleItem -> Scoper Type ModuleItem
traverseModuleItemM' =
traverseTypesM traverseTypeM >=>
traverseExprsM (traverseNestedExprsM traverseExprM)
convertGenItem' :: GenItem -> GenItem
convertGenItem' item = do
GenBlock "" items
where
-- convert inner generate blocks first
item' = Generate [traverseNestedGenItems convertGenItem item]
types = execWriter $ collectNestedModuleItemsM collectTypedefM item'
Generate items = traverseNestedModuleItems (convertTypedef types) item'
traverseGenItemM :: GenItem -> Scoper Type GenItem
traverseGenItemM = traverseGenItemExprsM (traverseNestedExprsM traverseExprM)
collectTypedefM :: ModuleItem -> Writer Types ()
collectTypedefM (MIPackageItem (Typedef a b)) = tell $ Map.singleton b a
collectTypedefM _ = return ()
traverseDeclM :: Decl -> Scoper Type Decl
traverseDeclM decl = do
item <- traverseModuleItemM (MIPackageItem $ Decl decl)
let MIPackageItem (Decl decl') = item
case decl' of
Variable{} -> return decl'
Param{} -> return decl'
ParamType{} -> return decl'
CommentDecl{} -> return decl'
resolveItem :: Types -> (Type, Identifier) -> (Type, Identifier)
resolveItem types (t, x) = (resolveType types t, x)
traverseStmtM :: Stmt -> Scoper Type Stmt
traverseStmtM =
traverseStmtExprsM $ traverseNestedExprsM $
traverseExprTypesM traverseTypeM >=> traverseExprM
resolveType :: Types -> Type -> Type
resolveType _ (Net kw sg rs) = Net kw sg rs
resolveType _ (Implicit sg rs) = Implicit sg rs
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 _ (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 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) =
if Map.notMember st types
then Alias Nothing st rs1
else case resolveType types $ types Map.! st of
(Net kw sg rs2) -> Net kw sg $ rs1 ++ rs2
(Implicit sg rs2) -> Implicit sg $ rs1 ++ rs2
(IntegerVector kw sg rs2) -> IntegerVector kw sg $ rs1 ++ rs2
(Enum t v rs2) -> Enum t v $ rs1 ++ rs2
(Struct p l rs2) -> Struct p l $ rs1 ++ rs2
(Union p l rs2) -> Union p l $ rs1 ++ rs2
(InterfaceT x my rs2) -> InterfaceT x my $ rs1 ++ rs2
(Alias ps x rs2) -> Alias ps x $ rs1 ++ rs2
(UnpackedType t rs2) -> UnpackedType t $ rs1 ++ rs2
(IntegerAtom kw sg ) -> nullRange (IntegerAtom kw sg) rs1
(NonInteger kw ) -> nullRange (NonInteger kw ) rs1
(TypeOf expr) -> nullRange (TypeOf expr) rs1
traverseTypeM :: Type -> Scoper Type Type
traverseTypeM (Alias Nothing st rs1) = do
details <- lookupIdentM st
return $ case details of
Nothing -> Alias Nothing st rs1
Just (_, _, typ) -> case typ of
Net kw sg rs2 -> Net kw sg $ rs1 ++ rs2
Implicit sg rs2 -> Implicit sg $ rs1 ++ rs2
IntegerVector kw sg rs2 -> IntegerVector kw sg $ rs1 ++ rs2
Enum t v rs2 -> Enum t v $ rs1 ++ rs2
Struct p l rs2 -> Struct p l $ rs1 ++ rs2
Union p l rs2 -> Union p l $ rs1 ++ rs2
InterfaceT x my rs2 -> InterfaceT x my $ rs1 ++ rs2
Alias ps x rs2 -> Alias ps x $ rs1 ++ rs2
UnpackedType t rs2 -> UnpackedType t $ rs1 ++ rs2
IntegerAtom kw sg -> nullRange (IntegerAtom kw sg) rs1
NonInteger kw -> nullRange (NonInteger kw ) rs1
TypeOf expr -> nullRange (TypeOf expr) rs1
traverseTypeM other = return other
......@@ -81,6 +81,7 @@ executable sv2v
Convert.Package
Convert.ParamType
Convert.RemoveComments
Convert.Scoper
Convert.SignCast
Convert.Simplify
Convert.SizeCast
......
module top;
logic t;
initial $display("A t %0d", $bits(t));
initial $display("A top.t %0d", $bits(top.t));
generate
begin : X
logic [1:0] t;
initial $display("B t %0d", $bits(t));
initial $display("B top.t %0d", $bits(top.t));
initial $display("B X.t %0d", $bits(X.t));
initial $display("B top.X.t %0d", $bits(top.X.t));
begin : Y
logic [2:0] t;
initial $display("C t %0d", $bits(t));
initial $display("C top.t %0d", $bits(top.t));
initial $display("C X.t %0d", $bits(X.t));
initial $display("C top.X.t %0d", $bits(top.X.t));
initial $display("C Y.t %0d", $bits(Y.t));
initial $display("C X.Y.t %0d", $bits(X.Y.t));
initial $display("C top.X.Y.t %0d", $bits(top.X.Y.t));
end
end
for (genvar i = 0; i < 3; ++i) begin : Z
logic [i:0] t;
end
endgenerate
initial $display("A t %0d", $bits(t));
initial $display("A top.t %0d", $bits(top.t));
initial $display("A X.t %0d", $bits(X.t));
initial $display("A top.X.t %0d", $bits(top.X.t));
initial $display("A X.Y.t %0d", $bits(X.Y.t));
initial $display("A top.X.Y.t %0d", $bits(top.X.Y.t));
initial $display("A top.Z[0].t %0d", $bits(top.Z[0].t));
initial $display("A Z[0].t %0d", $bits(Z[0].t));
initial $display("A Z[1].t %0d", $bits(Z[1].t));
initial $display("A Z[2].t %0d", $bits(Z[2].t));
logic x;
initial begin
type(x) x [1:0];
type(x) y [2:0];
$display("size of x = %0d", $bits(x));
$display("size of y = %0d", $bits(y));
end
logic [2:0][3:0] arr;
generate
begin : M
logic [3:0][4:0] arr;
initial $display("M arr[0] = %b", arr[0]);
initial $display("M M.arr[0] = %b", M.arr[0]);
initial $display("M top.arr[0] = %b", top.arr[0]);
end
endgenerate
initial $display("arr[0] = %b", arr[0]);
initial $display("M.arr[0] = %b", M.arr[0]);
initial $display("top.arr[0] = %b", top.arr[0]);
localparam arr2 [2][3] = '{
'{1'b0, 1'b1, 1'b1},
'{1'b1, 1'b0, 1'b0}
};
for (genvar i = 0 ; i < 2 ; ++i) begin
for (genvar j = 0 ; j < 3 ; ++j) begin
localparam value = arr2[i][j];
initial $display("%0d %0d %0d", i, j, value);
end
end
endmodule
module top;
wire t;
initial $display("A t %0d", 1);
initial $display("A top.t %0d", 1);
generate
begin : X
wire [1:0] t;
initial $display("B t %0d", 2);
initial $display("B top.t %0d", 1);
initial $display("B X.t %0d", 2);
initial $display("B top.X.t %0d", 2);
begin : Y
wire [2:0] t;
initial $display("C t %0d", 3);
initial $display("C top.t %0d", 1);
initial $display("C X.t %0d", 2);
initial $display("C top.X.t %0d", 2);
initial $display("C Y.t %0d", 3);
initial $display("C X.Y.t %0d", 3);
initial $display("C top.X.Y.t %0d", 3);
end
end
genvar i;
for (i = 0; i < 3; i = i + 1) begin : Z
wire [i:0] t;
end
endgenerate
initial $display("A t %0d", 1);
initial $display("A top.t %0d", 1);
initial $display("A X.t %0d", 2);
initial $display("A top.X.t %0d", 2);
initial $display("A X.Y.t %0d", 3);
initial $display("A top.X.Y.t %0d", 3);
initial $display("A top.Z[0].t %0d", 1);
initial $display("A Z[0].t %0d", 1);
initial $display("A Z[1].t %0d", 2);
initial $display("A Z[2].t %0d", 3);
wire x;
initial begin : name
reg [1:0] x;
reg [5:0] y;
$display("size of x = %0d", $bits(x));
$display("size of y = %0d", $bits(y));
end
wire [11:0] arr;
generate
begin : M
wire [19:0] arr;
initial $display("M arr[0] = %b", arr[4:0]);
initial $display("M M.arr[0] = %b", M.arr[4:0]);
initial $display("M top.arr[0] = %b", top.arr[3:0]);
end
endgenerate
initial $display("arr[0] = %b", arr[3:0]);
initial $display("M.arr[0] = %b", M.arr[4:0]);
initial $display("top.arr[0] = %b", top.arr[3:0]);
localparam [0:5] arr2 = 6'b011100;
generate
genvar j;
for (i = 0 ; i < 2 ; i = i + 1) begin
for (j = 0 ; j < 3 ; j = j + 1) begin
localparam value = arr2[i * 3 + j];
initial $display("%0d %0d %0d", i, j, value);
end
end
endgenerate
endmodule
module top;
typedef struct packed {
logic x;
logic [1:0] y;
} A;
typedef struct packed {
logic [2:0] x;
logic [3:0] y;
} B;
typedef struct packed {
logic [4:0] x;
logic [5:0] y;
B z;
} C;
A a;
B b;
C c;
generate
begin : foo
typedef struct packed {
logic [6:0] x;
logic [7:0] y;
} B;
typedef struct packed {
logic [8:0] x;
logic [9:0] y;
B z;
} D;
A a;
B b;
C c;
D d;
end
endgenerate
`define INSPECT_SIZE(expr) $display(`"expr -> %0d`", $bits(expr));
`define INSPECT_DATA(expr) $display(`"expr -> %b`", expr);
initial begin
`INSPECT_SIZE(a);
`INSPECT_SIZE(a.x);
`INSPECT_SIZE(a.y);
`INSPECT_SIZE(b);
`INSPECT_SIZE(b.x);
`INSPECT_SIZE(b.y);
`INSPECT_SIZE(c);
`INSPECT_SIZE(c.x);
`INSPECT_SIZE(c.y);
`INSPECT_SIZE(c.z);
`INSPECT_SIZE(c.z.x);
`INSPECT_SIZE(c.z.y);
`INSPECT_SIZE(foo.a);
`INSPECT_SIZE(foo.a.x);
`INSPECT_SIZE(foo.a.y);
`INSPECT_SIZE(foo.b);
`INSPECT_SIZE(foo.b.x);
`INSPECT_SIZE(foo.b.y);
`INSPECT_SIZE(foo.c);
`INSPECT_SIZE(foo.c.x);
`INSPECT_SIZE(foo.c.y);
`INSPECT_SIZE(foo.c.z);
`INSPECT_SIZE(foo.c.z.x);
`INSPECT_SIZE(foo.c.z.y);
`INSPECT_SIZE(foo.d);
`INSPECT_SIZE(foo.d.x);
`INSPECT_SIZE(foo.d.y);
`INSPECT_SIZE(foo.d.z);
`INSPECT_SIZE(foo.d.z.x);
`INSPECT_SIZE(foo.d.z.y);
`INSPECT_DATA(a);
`INSPECT_DATA(b);
`INSPECT_DATA(c);
`INSPECT_DATA(foo.a);
`INSPECT_DATA(foo.b);
`INSPECT_DATA(foo.c);
`INSPECT_DATA(foo.d);
end
endmodule
module top;
wire [2:0] a;
wire [6:0] b;
wire [17:0] c;
generate
begin : foo
wire [2:0] a;
wire [14:0] b;
wire [17:0] c;
wire [33:0] d;
end
endgenerate
`define INSPECT_SIZE(expr, size) $display(`"expr -> %0d`", size);
`define INSPECT_DATA(expr) $display(`"expr -> %b`", expr);
initial begin
`INSPECT_SIZE(a, 3);
`INSPECT_SIZE(a.x, 1);
`INSPECT_SIZE(a.y, 2);
`INSPECT_SIZE(b, 7);
`INSPECT_SIZE(b.x, 3);
`INSPECT_SIZE(b.y, 4);
`INSPECT_SIZE(c, 18);
`INSPECT_SIZE(c.x, 5);
`INSPECT_SIZE(c.y, 6);
`INSPECT_SIZE(c.z, 7);
`INSPECT_SIZE(c.z.x, 3);
`INSPECT_SIZE(c.z.y, 4);
`INSPECT_SIZE(foo.a, 3);
`INSPECT_SIZE(foo.a.x, 1);
`INSPECT_SIZE(foo.a.y, 2);
`INSPECT_SIZE(foo.b, 15);
`INSPECT_SIZE(foo.b.x, 7);
`INSPECT_SIZE(foo.b.y, 8);
`INSPECT_SIZE(foo.c, 18);
`INSPECT_SIZE(foo.c.x, 5);
`INSPECT_SIZE(foo.c.y, 6);
`INSPECT_SIZE(foo.c.z, 7);
`INSPECT_SIZE(foo.c.z.x, 3);
`INSPECT_SIZE(foo.c.z.y, 4);
`INSPECT_SIZE(foo.d, 34);
`INSPECT_SIZE(foo.d.x, 9);
`INSPECT_SIZE(foo.d.y, 10);
`INSPECT_SIZE(foo.d.z, 15);
`INSPECT_SIZE(foo.d.z.x, 7);
`INSPECT_SIZE(foo.d.z.y, 8);
`INSPECT_DATA(a);
`INSPECT_DATA(b);
`INSPECT_DATA(c);
`INSPECT_DATA(foo.a);
`INSPECT_DATA(foo.b);
`INSPECT_DATA(foo.c);
`INSPECT_DATA(foo.d);
end
endmodule
......@@ -134,6 +134,7 @@ module top;
input StructA b;
input StructB c;
input StructC d;
integer unused;
input StructD e;
input StructE f;
$display("F: %1d%1d%1d -> ", i,j,k, a,b,c,d,e,f);
......
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