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