mirror of https://github.com/zachjs/sv2v.git
PackedArray conversion supports complex shadowing
This commit is contained in:
parent
9c1fc7d020
commit
9305c0f43b
|
|
@ -21,106 +21,49 @@ module Convert.PackedArray (convert) where
|
|||
import Control.Monad.State
|
||||
import Data.Tuple (swap)
|
||||
import qualified Data.Map.Strict as Map
|
||||
import qualified Data.Set as Set
|
||||
|
||||
import Convert.Traverse
|
||||
import Language.SystemVerilog.AST
|
||||
|
||||
type DimMap = Map.Map Identifier [Range]
|
||||
type IdentSet = Set.Set Identifier
|
||||
|
||||
data Info = Info
|
||||
{ sTypeDims :: DimMap
|
||||
, sIdents :: IdentSet
|
||||
} deriving Show
|
||||
|
||||
defaultInfo :: Info
|
||||
defaultInfo = Info Map.empty Set.empty
|
||||
} deriving (Eq, Show)
|
||||
|
||||
convert :: AST -> AST
|
||||
convert = traverseDescriptions convertDescription
|
||||
|
||||
convertDescription :: Description -> Description
|
||||
convertDescription (description @ (Part _ _ _ _ _ _)) =
|
||||
traverseModuleItems (convertModuleItem info) description
|
||||
evalState
|
||||
(initialTraverse description >>= scopedTraverse)
|
||||
(Info Map.empty)
|
||||
where
|
||||
collector = collectModuleItemsM $ collectDeclsM' ExcludeTFs collectDecl
|
||||
info = execState (collector description) defaultInfo
|
||||
initialTraverse = traverseModuleItemsM traverseMIDecl
|
||||
scopedTraverse = traverseModuleItemsM $
|
||||
traverseScopesM traverseDeclM traverseModuleItemM traverseStmtM
|
||||
traverseMIDecl :: ModuleItem -> State Info ModuleItem
|
||||
traverseMIDecl (MIDecl decl) =
|
||||
traverseDeclM decl >>= return . MIDecl
|
||||
traverseMIDecl other = return other
|
||||
convertDescription description = description
|
||||
|
||||
-- collects packed-array dimension and variable existing info into the state
|
||||
collectDecl :: Decl -> State Info ()
|
||||
collectDecl (Variable _ t ident _ _) = do
|
||||
Info typeDims idents <- get
|
||||
let (_, rs) = typeRanges t
|
||||
let typeDims' =
|
||||
if not (isImplicit t) && length rs > 1
|
||||
then Map.insert ident rs typeDims
|
||||
else typeDims
|
||||
let idents' =
|
||||
if not (isImplicit t)
|
||||
then
|
||||
if Set.member ident idents
|
||||
then error $ "unsupported complex shadowing of " ++ show ident
|
||||
else Set.insert ident idents
|
||||
else idents
|
||||
put $ Info typeDims' idents'
|
||||
where
|
||||
isImplicit :: Type -> Bool
|
||||
isImplicit (Implicit _ _) = True
|
||||
isImplicit _ = False
|
||||
collectDecl _ = return ()
|
||||
|
||||
-- shadows the latter info with the former
|
||||
combineInfo :: Info -> Info -> Info
|
||||
combineInfo local global =
|
||||
Info typeDims idents
|
||||
where
|
||||
Info globalTypeDims globalIdents = global
|
||||
Info localTypeDims localIdents = local
|
||||
idents = Set.union globalIdents localIdents
|
||||
typeDims = Map.union localTypeDims $
|
||||
Map.withoutKeys globalTypeDims localIdents
|
||||
|
||||
-- Convert the multi-dimensional packed arrays within the given module item.
|
||||
-- This function must ensure that function/task level shadowing is respected.
|
||||
convertModuleItem :: Info -> ModuleItem -> ModuleItem
|
||||
convertModuleItem globalInfo (orig @ (MIPackageItem (Function ml t x decls stmts))) =
|
||||
rewrite info $
|
||||
MIPackageItem $ Function ml t' x decls stmts
|
||||
where
|
||||
localInfo =
|
||||
execState (collectDecl $ Variable Local t x [] Nothing) $
|
||||
execState (collectDeclsM collectDecl orig) $
|
||||
defaultInfo
|
||||
info = combineInfo localInfo globalInfo
|
||||
-- rewrite the return type of this function
|
||||
Variable Local t' _ [] Nothing =
|
||||
flattenDecl info $ Variable Local t x [] Nothing
|
||||
convertModuleItem globalInfo (orig @ (MIPackageItem (Task ml x decls stmts))) =
|
||||
rewrite info $
|
||||
MIPackageItem $ Task ml x decls stmts
|
||||
where
|
||||
localInfo =
|
||||
execState (collectDeclsM collectDecl orig) $
|
||||
defaultInfo
|
||||
info = combineInfo localInfo globalInfo
|
||||
convertModuleItem info other =
|
||||
rewrite info other
|
||||
|
||||
-- combine the leading two packed ranges of a declaration
|
||||
flattenDecl :: Info -> Decl -> Decl
|
||||
flattenDecl info (origDecl @ (Variable dir t ident a me)) =
|
||||
if Map.notMember ident typeDims
|
||||
then origDecl
|
||||
else flatDecl
|
||||
where
|
||||
typeDims = sTypeDims info
|
||||
(tf, rs) = typeRanges t
|
||||
r1 : r2 : rest = rs
|
||||
rs' = (combineRanges r1 r2) : rest
|
||||
flatDecl = Variable dir (tf rs') ident a me
|
||||
flattenDecl _ other = other
|
||||
-- collects and converts multi-dimensional packed-array declarations
|
||||
traverseDeclM :: Decl -> State Info Decl
|
||||
traverseDeclM (origDecl @ (Variable dir t ident a me)) = do
|
||||
Info typeDims <- get
|
||||
let (tf, rs) = typeRanges t
|
||||
if length rs <= 1
|
||||
then do
|
||||
put $ Info $ Map.delete ident typeDims
|
||||
return origDecl
|
||||
else do
|
||||
put $ Info $ Map.insert ident rs typeDims
|
||||
let r1 : r2 : rest = rs
|
||||
let rs' = (combineRanges r1 r2) : rest
|
||||
return $ Variable dir (tf rs') ident a me
|
||||
traverseDeclM other = return other
|
||||
|
||||
-- combines two ranges into one flattened range
|
||||
combineRanges :: Range -> Range -> Range
|
||||
|
|
@ -144,13 +87,25 @@ combineRanges r1 r2 = r
|
|||
upper = BinOp Add (BinOp Mul size1 size2)
|
||||
(BinOp Sub lower (Number "1"))
|
||||
|
||||
-- rewrite the declarations, expressions, and lvals in a module item to remove
|
||||
-- the packed array dimensions captured in the given info
|
||||
rewrite :: Info -> ModuleItem -> ModuleItem
|
||||
rewrite info =
|
||||
traverseDecls (flattenDecl info) .
|
||||
traverseLHSs (traverseNestedLHSs rewriteLHS ) .
|
||||
traverseExprs (traverseNestedExprs rewriteExpr)
|
||||
traverseModuleItemM :: ModuleItem -> State Info ModuleItem
|
||||
traverseModuleItemM item =
|
||||
traverseLHSsM traverseLHSM item >>=
|
||||
traverseExprsM traverseExprM
|
||||
|
||||
traverseStmtM :: Stmt -> State Info Stmt
|
||||
traverseStmtM stmt =
|
||||
traverseStmtLHSsM traverseLHSM stmt >>=
|
||||
traverseStmtExprsM traverseExprM
|
||||
|
||||
traverseExprM :: Expr -> State Info Expr
|
||||
traverseExprM = traverseNestedExprsM $ stately traverseExpr
|
||||
|
||||
traverseLHSM :: LHS -> State Info LHS
|
||||
traverseLHSM = traverseNestedLHSsM $ stately traverseLHS
|
||||
|
||||
traverseExpr :: Info -> Expr -> Expr
|
||||
traverseExpr info =
|
||||
rewriteExpr
|
||||
where
|
||||
typeDims = sTypeDims info
|
||||
|
||||
|
|
@ -249,9 +204,16 @@ rewrite info =
|
|||
range' = (base, len)
|
||||
rewriteExpr other = other
|
||||
|
||||
-- LHSs need to be converted too. Rather than duplicating the
|
||||
-- procedures, we turn the relevant LHSs into expressions temporarily
|
||||
-- and use the expression conversion written above.
|
||||
-- LHSs need to be converted too. Rather than duplicating the procedures, we
|
||||
-- turn the relevant LHSs into expressions temporarily and use the expression
|
||||
-- conversion written above.
|
||||
traverseLHS :: Info -> LHS -> LHS
|
||||
traverseLHS info =
|
||||
rewriteLHS
|
||||
where
|
||||
typeDims = sTypeDims info
|
||||
rewriteExpr = traverseExpr info
|
||||
|
||||
rewriteLHS :: LHS -> LHS
|
||||
rewriteLHS (LHSIdent x) =
|
||||
LHSIdent x'
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ module Convert.Traverse
|
|||
, traverseExprsM'
|
||||
, traverseExprs'
|
||||
, collectExprsM'
|
||||
, traverseStmtExprsM
|
||||
, traverseStmtExprs
|
||||
, collectStmtExprsM
|
||||
, traverseLHSsM
|
||||
, traverseLHSs
|
||||
, collectLHSsM
|
||||
|
|
@ -61,11 +64,14 @@ module Convert.Traverse
|
|||
, collectNestedModuleItemsM
|
||||
, traverseNestedStmts
|
||||
, collectNestedStmtsM
|
||||
, traverseNestedExprsM
|
||||
, traverseNestedExprs
|
||||
, collectNestedExprsM
|
||||
, traverseNestedLHSsM
|
||||
, traverseNestedLHSs
|
||||
, collectNestedLHSsM
|
||||
, traverseScopesM
|
||||
, stately
|
||||
) where
|
||||
|
||||
import Control.Monad.State
|
||||
|
|
@ -188,7 +194,12 @@ collectStmtsM = collectStmtsM' IncludeTFs
|
|||
traverseNestedStmtsM :: Monad m => MapperM m Stmt -> MapperM m Stmt
|
||||
traverseNestedStmtsM mapper = fullMapper
|
||||
where
|
||||
fullMapper stmt = mapper stmt >>= cs
|
||||
fullMapper stmt = mapper stmt >>= traverseSinglyNestedStmtsM fullMapper
|
||||
|
||||
-- variant of the above which only traverse one level down
|
||||
traverseSinglyNestedStmtsM :: Monad m => MapperM m Stmt -> MapperM m Stmt
|
||||
traverseSinglyNestedStmtsM fullMapper = cs
|
||||
where
|
||||
cs (StmtAttr a stmt) = fullMapper stmt >>= return . StmtAttr a
|
||||
cs (Block name decls stmts) =
|
||||
mapM fullMapper stmts >>= return . Block name decls
|
||||
|
|
@ -430,9 +441,10 @@ traverseNestedExprsM mapper = exprMapper
|
|||
exprs <- mapM exprMapper $ map snd l
|
||||
return $ Pattern $ zip names exprs
|
||||
|
||||
|
||||
traverseExprsM' :: Monad m => TFStrategy -> MapperM m Expr -> MapperM m ModuleItem
|
||||
traverseExprsM' strat mapper = moduleItemMapper
|
||||
exprMapperHelpers :: Monad m => MapperM m Expr ->
|
||||
(MapperM m Range, MapperM m (Maybe Expr), MapperM m Decl)
|
||||
exprMapperHelpers exprMapper =
|
||||
(rangeMapper, maybeExprMapper, declMapper)
|
||||
where
|
||||
|
||||
rangeMapper (a, b) = do
|
||||
|
|
@ -453,59 +465,14 @@ traverseExprsM' strat mapper = moduleItemMapper
|
|||
me' <- maybeExprMapper me
|
||||
return $ Variable d t x a' me'
|
||||
|
||||
exprMapper = mapper
|
||||
traverseExprsM' :: Monad m => TFStrategy -> MapperM m Expr -> MapperM m ModuleItem
|
||||
traverseExprsM' strat exprMapper = moduleItemMapper
|
||||
where
|
||||
|
||||
caseMapper (exprs, stmt) = do
|
||||
exprs' <- mapM exprMapper exprs
|
||||
return (exprs', stmt)
|
||||
stmtMapper = traverseNestedStmtsM flatStmtMapper
|
||||
flatStmtMapper (StmtAttr attr stmt) =
|
||||
-- note: we exclude expressions in attributes from conversion
|
||||
return $ StmtAttr attr stmt
|
||||
flatStmtMapper (Block name decls stmts) = do
|
||||
decls' <- mapM declMapper decls
|
||||
return $ Block name decls' stmts
|
||||
flatStmtMapper (Case u kw e cases def) = do
|
||||
e' <- exprMapper e
|
||||
cases' <- mapM caseMapper cases
|
||||
return $ Case u kw e' cases' def
|
||||
flatStmtMapper (AsgnBlk op lhs expr) =
|
||||
exprMapper expr >>= return . AsgnBlk op lhs
|
||||
flatStmtMapper (Asgn mt lhs expr) =
|
||||
exprMapper expr >>= return . Asgn mt lhs
|
||||
flatStmtMapper (For inits cc asgns stmt) = do
|
||||
inits' <- mapM initMapper inits
|
||||
cc' <- maybeExprMapper cc
|
||||
asgns' <- mapM asgnMapper asgns
|
||||
return $ For inits' cc' asgns' stmt
|
||||
flatStmtMapper (While e stmt) =
|
||||
exprMapper e >>= \e' -> return $ While e' stmt
|
||||
flatStmtMapper (RepeatL e stmt) =
|
||||
exprMapper e >>= \e' -> return $ RepeatL e' stmt
|
||||
flatStmtMapper (DoWhile e stmt) =
|
||||
exprMapper e >>= \e' -> return $ DoWhile e' stmt
|
||||
flatStmtMapper (Forever stmt) = return $ Forever stmt
|
||||
flatStmtMapper (If u cc s1 s2) =
|
||||
exprMapper cc >>= \cc' -> return $ If u cc' s1 s2
|
||||
flatStmtMapper (Timing event stmt) = return $ Timing event stmt
|
||||
flatStmtMapper (Subroutine f (Args l p)) = do
|
||||
l' <- mapM maybeExprMapper l
|
||||
pes <- mapM maybeExprMapper $ map snd p
|
||||
let p' = zip (map fst p) pes
|
||||
return $ Subroutine f (Args l' p')
|
||||
flatStmtMapper (Return expr) =
|
||||
exprMapper expr >>= return . Return
|
||||
flatStmtMapper (Trigger x) = return $ Trigger x
|
||||
flatStmtMapper (Assertion a) = do
|
||||
a' <- traverseAssertionStmtsM stmtMapper a
|
||||
a'' <- traverseAssertionExprsM exprMapper a'
|
||||
return $ Assertion a''
|
||||
flatStmtMapper (Null) = return Null
|
||||
(rangeMapper, maybeExprMapper, declMapper)
|
||||
= exprMapperHelpers exprMapper
|
||||
|
||||
initMapper (Left decl) = declMapper decl >>= return . Left
|
||||
initMapper (Right (l, e)) = exprMapper e >>= \e' -> return $ Right (l, e')
|
||||
|
||||
asgnMapper (l, op, e) = exprMapper e >>= \e' -> return $ (l, op, e')
|
||||
stmtMapper = traverseNestedStmtsM (traverseStmtExprsM exprMapper)
|
||||
|
||||
portBindingMapper (p, me) =
|
||||
maybeExprMapper me >>= \me' -> return (p, me')
|
||||
|
|
@ -602,6 +569,70 @@ traverseExprs = traverseExprs' IncludeTFs
|
|||
collectExprsM :: Monad m => CollectorM m Expr -> CollectorM m ModuleItem
|
||||
collectExprsM = collectExprsM' IncludeTFs
|
||||
|
||||
traverseStmtExprsM :: Monad m => MapperM m Expr -> MapperM m Stmt
|
||||
traverseStmtExprsM exprMapper = flatStmtMapper
|
||||
where
|
||||
|
||||
(_, maybeExprMapper, declMapper)
|
||||
= exprMapperHelpers exprMapper
|
||||
|
||||
caseMapper (exprs, stmt) = do
|
||||
exprs' <- mapM exprMapper exprs
|
||||
return (exprs', stmt)
|
||||
stmtMapper = traverseNestedStmtsM flatStmtMapper
|
||||
flatStmtMapper (StmtAttr attr stmt) =
|
||||
-- note: we exclude expressions in attributes from conversion
|
||||
return $ StmtAttr attr stmt
|
||||
flatStmtMapper (Block name decls stmts) = do
|
||||
decls' <- mapM declMapper decls
|
||||
return $ Block name decls' stmts
|
||||
flatStmtMapper (Case u kw e cases def) = do
|
||||
e' <- exprMapper e
|
||||
cases' <- mapM caseMapper cases
|
||||
return $ Case u kw e' cases' def
|
||||
flatStmtMapper (AsgnBlk op lhs expr) =
|
||||
exprMapper expr >>= return . AsgnBlk op lhs
|
||||
flatStmtMapper (Asgn mt lhs expr) =
|
||||
exprMapper expr >>= return . Asgn mt lhs
|
||||
flatStmtMapper (For inits cc asgns stmt) = do
|
||||
inits' <- mapM initMapper inits
|
||||
cc' <- maybeExprMapper cc
|
||||
asgns' <- mapM asgnMapper asgns
|
||||
return $ For inits' cc' asgns' stmt
|
||||
flatStmtMapper (While e stmt) =
|
||||
exprMapper e >>= \e' -> return $ While e' stmt
|
||||
flatStmtMapper (RepeatL e stmt) =
|
||||
exprMapper e >>= \e' -> return $ RepeatL e' stmt
|
||||
flatStmtMapper (DoWhile e stmt) =
|
||||
exprMapper e >>= \e' -> return $ DoWhile e' stmt
|
||||
flatStmtMapper (Forever stmt) = return $ Forever stmt
|
||||
flatStmtMapper (If u cc s1 s2) =
|
||||
exprMapper cc >>= \cc' -> return $ If u cc' s1 s2
|
||||
flatStmtMapper (Timing event stmt) = return $ Timing event stmt
|
||||
flatStmtMapper (Subroutine f (Args l p)) = do
|
||||
l' <- mapM maybeExprMapper l
|
||||
pes <- mapM maybeExprMapper $ map snd p
|
||||
let p' = zip (map fst p) pes
|
||||
return $ Subroutine f (Args l' p')
|
||||
flatStmtMapper (Return expr) =
|
||||
exprMapper expr >>= return . Return
|
||||
flatStmtMapper (Trigger x) = return $ Trigger x
|
||||
flatStmtMapper (Assertion a) = do
|
||||
a' <- traverseAssertionStmtsM stmtMapper a
|
||||
a'' <- traverseAssertionExprsM exprMapper a'
|
||||
return $ Assertion a''
|
||||
flatStmtMapper (Null) = return Null
|
||||
|
||||
initMapper (Left decl) = declMapper decl >>= return . Left
|
||||
initMapper (Right (l, e)) = exprMapper e >>= \e' -> return $ Right (l, e')
|
||||
|
||||
asgnMapper (l, op, e) = exprMapper e >>= \e' -> return $ (l, op, e')
|
||||
|
||||
traverseStmtExprs :: Mapper Expr -> Mapper Stmt
|
||||
traverseStmtExprs = unmonad traverseStmtExprsM
|
||||
collectStmtExprsM :: Monad m => CollectorM m Expr -> CollectorM m Stmt
|
||||
collectStmtExprsM = collectify traverseStmtExprsM
|
||||
|
||||
traverseLHSsM' :: Monad m => TFStrategy -> MapperM m LHS -> MapperM m ModuleItem
|
||||
traverseLHSsM' strat mapper item =
|
||||
traverseStmtsM' strat (traverseStmtLHSsM mapper) item >>= traverseModuleItemLHSsM
|
||||
|
|
@ -837,3 +868,68 @@ traverseNestedExprs :: Mapper Expr -> Mapper Expr
|
|||
traverseNestedExprs = unmonad traverseNestedExprsM
|
||||
collectNestedExprsM :: Monad m => CollectorM m Expr -> CollectorM m Expr
|
||||
collectNestedExprsM = collectify traverseNestedExprsM
|
||||
|
||||
-- Traverse all the declaration scopes within a ModuleItem. Note that Functions,
|
||||
-- Tasks, Always and Initial blocks are all NOT passed through ModuleItem
|
||||
-- mapper, and MIDecl ModuleItems are NOT passed through the Decl mapper. The
|
||||
-- state is restored to its previous value after each scope is exited. Only the
|
||||
-- Decl mapper may modify the state, as we maintain the invariant that all other
|
||||
-- functions restore the state on exit. The Stmt mapper must not traverse
|
||||
-- statements recursively, as we add a recursive wrapper here.
|
||||
traverseScopesM
|
||||
:: (Eq s, Show s)
|
||||
=> MapperM (State s) Decl
|
||||
-> MapperM (State s) ModuleItem
|
||||
-> MapperM (State s) Stmt
|
||||
-> MapperM (State s) ModuleItem
|
||||
traverseScopesM declMapper moduleItemMapper stmtMapper =
|
||||
fullModuleItemMapper
|
||||
where
|
||||
|
||||
fullStmtMapper stmt = stmtMapper stmt >>= traverseSinglyNestedStmtsM cs
|
||||
cs (Block name decls stmts) = do
|
||||
prevState <- get
|
||||
decls' <- mapM declMapper decls
|
||||
block <- fullStmtMapper $ Block name decls' stmts
|
||||
put prevState
|
||||
return block
|
||||
cs other = fullStmtMapper other
|
||||
|
||||
redirectModuleItem (MIPackageItem (Function ml t x decls stmts)) = do
|
||||
prevState <- get
|
||||
t' <- do
|
||||
res <- declMapper $ Variable Local t x [] Nothing
|
||||
case res of
|
||||
Variable Local newType _ [] Nothing -> return newType
|
||||
_ -> error $ "redirected func ret traverse failed: " ++ show res
|
||||
decls' <- mapM declMapper decls
|
||||
stmts' <- mapM fullStmtMapper stmts
|
||||
put prevState
|
||||
return $ MIPackageItem $ Function ml t' x decls' stmts'
|
||||
redirectModuleItem (MIPackageItem (Task ml x decls stmts)) = do
|
||||
prevState <- get
|
||||
decls' <- mapM declMapper decls
|
||||
stmts' <- mapM fullStmtMapper stmts
|
||||
put prevState
|
||||
return $ MIPackageItem $ Task ml x decls' stmts'
|
||||
redirectModuleItem (AlwaysC kw stmt) =
|
||||
fullStmtMapper stmt >>= return . AlwaysC kw
|
||||
redirectModuleItem (Initial stmt) =
|
||||
fullStmtMapper stmt >>= return . Initial
|
||||
redirectModuleItem item =
|
||||
moduleItemMapper item
|
||||
|
||||
fullModuleItemMapper item = do
|
||||
prevState <- get
|
||||
item' <- redirectModuleItem item
|
||||
currState <- get
|
||||
if prevState == currState
|
||||
then return item'
|
||||
else error $ "illegal scope state modification: "
|
||||
++ show (prevState, item, currState, item')
|
||||
|
||||
-- convert a basic mapper with an initial argument to a stateful mapper
|
||||
stately :: (Eq s, Show s) => (s -> Mapper a) -> MapperM (State s) a
|
||||
stately mapper thing = do
|
||||
s <- get
|
||||
return $ mapper s thing
|
||||
|
|
|
|||
|
|
@ -94,21 +94,180 @@ module top;
|
|||
end
|
||||
|
||||
|
||||
initial begin
|
||||
begin : lol_block
|
||||
logic [1:0][1:0] arr;
|
||||
arr = 4'b1001;
|
||||
$display("LOL: $bits(arr): ", $bits(arr ));
|
||||
$display("LOL: $bits(arr[0]): ", $bits(arr[0] ));
|
||||
$display("LOL: $bits(arr[0][0]): ", $bits(arr[0][0]));
|
||||
$display("LOL: arr[0]: ", arr[0]);
|
||||
$display("LOL: arr[1]: ", arr[1]);
|
||||
$display("LOL: arr[0][1]: ", arr[0][1]);
|
||||
$display("LOL: arr[1][0]: ", arr[1][0]);
|
||||
$display("LOL: arr[1][1]: ", arr[1][1]);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
task magic;
|
||||
begin
|
||||
begin : magic_block
|
||||
begin : magic_block1
|
||||
logic [1:0][1:0] magic_arr;
|
||||
magic_arr = 4'b1001;
|
||||
$display("$bits(magic_arr): ", $bits(magic_arr ));
|
||||
$display("$bits(magic_arr[0]): ", $bits(magic_arr[0] ));
|
||||
$display("$bits(magic_arr[0][0]): ", $bits(magic_arr[0][0]));
|
||||
$display("magic_arr[0][0]: ", magic_arr[0][0]);
|
||||
$display("magic_arr[0][1]: ", magic_arr[0][1]);
|
||||
$display("magic_arr[1][0]: ", magic_arr[1][0]);
|
||||
$display("magic_arr[1][1]: ", magic_arr[1][1]);
|
||||
$display("MB1: $bits(magic_arr): ", $bits(magic_arr ));
|
||||
$display("MB1: $bits(magic_arr[0]): ", $bits(magic_arr[0] ));
|
||||
$display("MB1: $bits(magic_arr[0][0]): ", $bits(magic_arr[0][0]));
|
||||
$display("MB1: magic_arr[0]: ", magic_arr[0]);
|
||||
$display("MB1: magic_arr[1]: ", magic_arr[1]);
|
||||
$display("MB1: magic_arr[0][1]: ", magic_arr[0][1]);
|
||||
$display("MB1: magic_arr[1][0]: ", magic_arr[1][0]);
|
||||
$display("MB1: magic_arr[1][1]: ", magic_arr[1][1]);
|
||||
end
|
||||
begin : magic_block2
|
||||
logic [3:0] magic_arr;
|
||||
magic_arr = 4'b1001;
|
||||
$display("MB2: $bits(magic_arr): ", $bits(magic_arr ));
|
||||
$display("MB2: $bits(magic_arr[0]): ", $bits(magic_arr[0] ));
|
||||
$display("MB2: magic_arr[0]: ", magic_arr[0]);
|
||||
$display("MB2: magic_arr[1]: ", magic_arr[1]);
|
||||
$display("MB2: magic_arr[2]: ", magic_arr[2]);
|
||||
$display("MB2: magic_arr[3]: ", magic_arr[3]);
|
||||
end
|
||||
begin : magic_block3
|
||||
logic [1:0][1:0][1:0] magic_arr;
|
||||
magic_arr = 4'b1001;
|
||||
$display("MB3: $bits(magic_arr): ", $bits(magic_arr ));
|
||||
$display("MB3: $bits(magic_arr[0]): ", $bits(magic_arr[0] ));
|
||||
$display("MB3: $bits(magic_arr[0][0]): ", $bits(magic_arr[0][0] ));
|
||||
$display("MB3: $bits(magic_arr[0][0][0]): ", $bits(magic_arr[0][0][0]));
|
||||
$display("MB3: magic_arr[0]: ", magic_arr[0]);
|
||||
$display("MB3: magic_arr[1]: ", magic_arr[1]);
|
||||
$display("MB3: magic_arr[0][0]: ", magic_arr[0][0]);
|
||||
$display("MB3: magic_arr[0][1]: ", magic_arr[0][1]);
|
||||
$display("MB3: magic_arr[1][0]: ", magic_arr[1][0]);
|
||||
$display("MB3: magic_arr[1][1]: ", magic_arr[1][1]);
|
||||
$display("MB3: magic_arr[0][0][0]: ", magic_arr[0][0][0]);
|
||||
$display("MB3: magic_arr[0][0][1]: ", magic_arr[0][0][1]);
|
||||
$display("MB3: magic_arr[0][1][0]: ", magic_arr[0][1][0]);
|
||||
$display("MB3: magic_arr[0][1][1]: ", magic_arr[0][1][1]);
|
||||
$display("MB3: magic_arr[1][0][1]: ", magic_arr[1][0][1]);
|
||||
$display("MB3: magic_arr[1][0][0]: ", magic_arr[1][0][0]);
|
||||
$display("MB3: magic_arr[1][1][1]: ", magic_arr[1][1][1]);
|
||||
$display("MB3: magic_arr[1][1][0]: ", magic_arr[1][1][0]);
|
||||
begin : magic_block4
|
||||
logic [1:0][1:0] magic_arr;
|
||||
magic_arr = 4'b1001;
|
||||
$display("MB4: $bits(magic_arr): ", $bits(magic_arr ));
|
||||
$display("MB4: $bits(magic_arr[0]): ", $bits(magic_arr[0] ));
|
||||
$display("MB4: $bits(magic_arr[0][0]): ", $bits(magic_arr[0][0]));
|
||||
$display("MB4: magic_arr[0]: ", magic_arr[0]);
|
||||
$display("MB4: magic_arr[1]: ", magic_arr[1]);
|
||||
$display("MB4: magic_arr[0][1]: ", magic_arr[0][1]);
|
||||
$display("MB4: magic_arr[1][0]: ", magic_arr[1][0]);
|
||||
$display("MB4: magic_arr[1][1]: ", magic_arr[1][1]);
|
||||
end
|
||||
magic_arr = 4'b1001;
|
||||
$display("MB3: $bits(magic_arr): ", $bits(magic_arr ));
|
||||
$display("MB3: $bits(magic_arr[0]): ", $bits(magic_arr[0] ));
|
||||
$display("MB3: $bits(magic_arr[0][0]): ", $bits(magic_arr[0][0] ));
|
||||
$display("MB3: $bits(magic_arr[0][0][0]): ", $bits(magic_arr[0][0][0]));
|
||||
$display("MB3: magic_arr[0]: ", magic_arr[0]);
|
||||
$display("MB3: magic_arr[1]: ", magic_arr[1]);
|
||||
$display("MB3: magic_arr[0][0]: ", magic_arr[0][0]);
|
||||
$display("MB3: magic_arr[0][1]: ", magic_arr[0][1]);
|
||||
$display("MB3: magic_arr[1][0]: ", magic_arr[1][0]);
|
||||
$display("MB3: magic_arr[1][1]: ", magic_arr[1][1]);
|
||||
$display("MB3: magic_arr[0][0][0]: ", magic_arr[0][0][0]);
|
||||
$display("MB3: magic_arr[0][0][1]: ", magic_arr[0][0][1]);
|
||||
$display("MB3: magic_arr[0][1][0]: ", magic_arr[0][1][0]);
|
||||
$display("MB3: magic_arr[0][1][1]: ", magic_arr[0][1][1]);
|
||||
$display("MB3: magic_arr[1][0][1]: ", magic_arr[1][0][1]);
|
||||
$display("MB3: magic_arr[1][0][0]: ", magic_arr[1][0][0]);
|
||||
$display("MB3: magic_arr[1][1][1]: ", magic_arr[1][1][1]);
|
||||
$display("MB3: magic_arr[1][1][0]: ", magic_arr[1][1][0]);
|
||||
end
|
||||
end
|
||||
endtask
|
||||
initial magic();
|
||||
|
||||
|
||||
initial begin
|
||||
begin : ntf_magic_block1
|
||||
logic [1:0][1:0] ntf_magic_arr;
|
||||
ntf_magic_arr = 4'b1001;
|
||||
$display("NTFMB1: $bits(ntf_magic_arr): ", $bits(ntf_magic_arr ));
|
||||
$display("NTFMB1: $bits(ntf_magic_arr[0]): ", $bits(ntf_magic_arr[0] ));
|
||||
$display("NTFMB1: $bits(ntf_magic_arr[0][0]): ", $bits(ntf_magic_arr[0][0]));
|
||||
$display("NTFMB1: ntf_magic_arr[0]: ", ntf_magic_arr[0]);
|
||||
$display("NTFMB1: ntf_magic_arr[1]: ", ntf_magic_arr[1]);
|
||||
$display("NTFMB1: ntf_magic_arr[0][1]: ", ntf_magic_arr[0][1]);
|
||||
$display("NTFMB1: ntf_magic_arr[1][0]: ", ntf_magic_arr[1][0]);
|
||||
$display("NTFMB1: ntf_magic_arr[1][1]: ", ntf_magic_arr[1][1]);
|
||||
end
|
||||
begin : ntf_magic_block2
|
||||
logic [3:0] ntf_magic_arr;
|
||||
ntf_magic_arr = 4'b1001;
|
||||
$display("NTFMB2: $bits(ntf_magic_arr): ", $bits(ntf_magic_arr ));
|
||||
$display("NTFMB2: $bits(ntf_magic_arr[0]): ", $bits(ntf_magic_arr[0] ));
|
||||
$display("NTFMB2: ntf_magic_arr[0]: ", ntf_magic_arr[0]);
|
||||
$display("NTFMB2: ntf_magic_arr[1]: ", ntf_magic_arr[1]);
|
||||
$display("NTFMB2: ntf_magic_arr[2]: ", ntf_magic_arr[2]);
|
||||
$display("NTFMB2: ntf_magic_arr[3]: ", ntf_magic_arr[3]);
|
||||
end
|
||||
begin : ntf_magic_block3
|
||||
logic [1:0][1:0][1:0] ntf_magic_arr;
|
||||
ntf_magic_arr = 4'b1001;
|
||||
$display("NTFMB3: $bits(ntf_magic_arr): ", $bits(ntf_magic_arr ));
|
||||
$display("NTFMB3: $bits(ntf_magic_arr[0]): ", $bits(ntf_magic_arr[0] ));
|
||||
$display("NTFMB3: $bits(ntf_magic_arr[0][0]): ", $bits(ntf_magic_arr[0][0] ));
|
||||
$display("NTFMB3: $bits(ntf_magic_arr[0][0][0]): ", $bits(ntf_magic_arr[0][0][0]));
|
||||
$display("NTFMB3: ntf_magic_arr[0]: ", ntf_magic_arr[0]);
|
||||
$display("NTFMB3: ntf_magic_arr[1]: ", ntf_magic_arr[1]);
|
||||
$display("NTFMB3: ntf_magic_arr[0][0]: ", ntf_magic_arr[0][0]);
|
||||
$display("NTFMB3: ntf_magic_arr[0][1]: ", ntf_magic_arr[0][1]);
|
||||
$display("NTFMB3: ntf_magic_arr[1][0]: ", ntf_magic_arr[1][0]);
|
||||
$display("NTFMB3: ntf_magic_arr[1][1]: ", ntf_magic_arr[1][1]);
|
||||
$display("NTFMB3: ntf_magic_arr[0][0][0]: ", ntf_magic_arr[0][0][0]);
|
||||
$display("NTFMB3: ntf_magic_arr[0][0][1]: ", ntf_magic_arr[0][0][1]);
|
||||
$display("NTFMB3: ntf_magic_arr[0][1][0]: ", ntf_magic_arr[0][1][0]);
|
||||
$display("NTFMB3: ntf_magic_arr[0][1][1]: ", ntf_magic_arr[0][1][1]);
|
||||
$display("NTFMB3: ntf_magic_arr[1][0][1]: ", ntf_magic_arr[1][0][1]);
|
||||
$display("NTFMB3: ntf_magic_arr[1][0][0]: ", ntf_magic_arr[1][0][0]);
|
||||
$display("NTFMB3: ntf_magic_arr[1][1][1]: ", ntf_magic_arr[1][1][1]);
|
||||
$display("NTFMB3: ntf_magic_arr[1][1][0]: ", ntf_magic_arr[1][1][0]);
|
||||
begin : ntf_magic_block4
|
||||
logic [1:0][1:0] ntf_magic_arr;
|
||||
ntf_magic_arr = 4'b1001;
|
||||
$display("NTFMB4: $bits(ntf_magic_arr): ", $bits(ntf_magic_arr ));
|
||||
$display("NTFMB4: $bits(ntf_magic_arr[0]): ", $bits(ntf_magic_arr[0] ));
|
||||
$display("NTFMB4: $bits(ntf_magic_arr[0][0]): ", $bits(ntf_magic_arr[0][0]));
|
||||
$display("NTFMB4: ntf_magic_arr[0]: ", ntf_magic_arr[0]);
|
||||
$display("NTFMB4: ntf_magic_arr[1]: ", ntf_magic_arr[1]);
|
||||
$display("NTFMB4: ntf_magic_arr[0][1]: ", ntf_magic_arr[0][1]);
|
||||
$display("NTFMB4: ntf_magic_arr[1][0]: ", ntf_magic_arr[1][0]);
|
||||
$display("NTFMB4: ntf_magic_arr[1][1]: ", ntf_magic_arr[1][1]);
|
||||
end
|
||||
ntf_magic_arr = 4'b1001;
|
||||
$display("NTFMB3: $bits(ntf_magic_arr): ", $bits(ntf_magic_arr ));
|
||||
$display("NTFMB3: $bits(ntf_magic_arr[0]): ", $bits(ntf_magic_arr[0] ));
|
||||
$display("NTFMB3: $bits(ntf_magic_arr[0][0]): ", $bits(ntf_magic_arr[0][0] ));
|
||||
$display("NTFMB3: $bits(ntf_magic_arr[0][0][0]): ", $bits(ntf_magic_arr[0][0][0]));
|
||||
$display("NTFMB3: ntf_magic_arr[0]: ", ntf_magic_arr[0]);
|
||||
$display("NTFMB3: ntf_magic_arr[1]: ", ntf_magic_arr[1]);
|
||||
$display("NTFMB3: ntf_magic_arr[0][0]: ", ntf_magic_arr[0][0]);
|
||||
$display("NTFMB3: ntf_magic_arr[0][1]: ", ntf_magic_arr[0][1]);
|
||||
$display("NTFMB3: ntf_magic_arr[1][0]: ", ntf_magic_arr[1][0]);
|
||||
$display("NTFMB3: ntf_magic_arr[1][1]: ", ntf_magic_arr[1][1]);
|
||||
$display("NTFMB3: ntf_magic_arr[0][0][0]: ", ntf_magic_arr[0][0][0]);
|
||||
$display("NTFMB3: ntf_magic_arr[0][0][1]: ", ntf_magic_arr[0][0][1]);
|
||||
$display("NTFMB3: ntf_magic_arr[0][1][0]: ", ntf_magic_arr[0][1][0]);
|
||||
$display("NTFMB3: ntf_magic_arr[0][1][1]: ", ntf_magic_arr[0][1][1]);
|
||||
$display("NTFMB3: ntf_magic_arr[1][0][1]: ", ntf_magic_arr[1][0][1]);
|
||||
$display("NTFMB3: ntf_magic_arr[1][0][0]: ", ntf_magic_arr[1][0][0]);
|
||||
$display("NTFMB3: ntf_magic_arr[1][1][1]: ", ntf_magic_arr[1][1][1]);
|
||||
$display("NTFMB3: ntf_magic_arr[1][1][0]: ", ntf_magic_arr[1][1][0]);
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
Loading…
Reference in New Issue