Commit 9305c0f4 by Zachary Snow

PackedArray conversion supports complex shadowing

parent 9c1fc7d0
......@@ -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
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
traverseExprsM' :: Monad m => TFStrategy -> MapperM m Expr -> MapperM m ModuleItem
traverseExprsM' strat exprMapper = moduleItemMapper
where
initMapper (Left decl) = declMapper decl >>= return . Left
initMapper (Right (l, e)) = exprMapper e >>= \e' -> return $ Right (l, e')
(rangeMapper, maybeExprMapper, declMapper)
= exprMapperHelpers exprMapper
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
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