Commit 9305c0f4 by Zachary Snow

PackedArray conversion supports complex shadowing

parent 9c1fc7d0
...@@ -21,106 +21,49 @@ module Convert.PackedArray (convert) where ...@@ -21,106 +21,49 @@ module Convert.PackedArray (convert) where
import Control.Monad.State import Control.Monad.State
import Data.Tuple (swap) import Data.Tuple (swap)
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
import Convert.Traverse import Convert.Traverse
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
type DimMap = Map.Map Identifier [Range] type DimMap = Map.Map Identifier [Range]
type IdentSet = Set.Set Identifier
data Info = Info data Info = Info
{ sTypeDims :: DimMap { sTypeDims :: DimMap
, sIdents :: IdentSet } deriving (Eq, Show)
} deriving Show
defaultInfo :: Info
defaultInfo = Info Map.empty Set.empty
convert :: AST -> AST convert :: AST -> AST
convert = traverseDescriptions convertDescription convert = traverseDescriptions convertDescription
convertDescription :: Description -> Description convertDescription :: Description -> Description
convertDescription (description @ (Part _ _ _ _ _ _)) = convertDescription (description @ (Part _ _ _ _ _ _)) =
traverseModuleItems (convertModuleItem info) description evalState
(initialTraverse description >>= scopedTraverse)
(Info Map.empty)
where where
collector = collectModuleItemsM $ collectDeclsM' ExcludeTFs collectDecl initialTraverse = traverseModuleItemsM traverseMIDecl
info = execState (collector description) defaultInfo 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 convertDescription description = description
-- collects packed-array dimension and variable existing info into the state -- collects and converts multi-dimensional packed-array declarations
collectDecl :: Decl -> State Info () traverseDeclM :: Decl -> State Info Decl
collectDecl (Variable _ t ident _ _) = do traverseDeclM (origDecl @ (Variable dir t ident a me)) = do
Info typeDims idents <- get Info typeDims <- get
let (_, rs) = typeRanges t let (tf, rs) = typeRanges t
let typeDims' = if length rs <= 1
if not (isImplicit t) && length rs > 1 then do
then Map.insert ident rs typeDims put $ Info $ Map.delete ident typeDims
else typeDims return origDecl
let idents' = else do
if not (isImplicit t) put $ Info $ Map.insert ident rs typeDims
then let r1 : r2 : rest = rs
if Set.member ident idents let rs' = (combineRanges r1 r2) : rest
then error $ "unsupported complex shadowing of " ++ show ident return $ Variable dir (tf rs') ident a me
else Set.insert ident idents traverseDeclM other = return other
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
-- combines two ranges into one flattened range -- combines two ranges into one flattened range
combineRanges :: Range -> Range -> Range combineRanges :: Range -> Range -> Range
...@@ -144,13 +87,25 @@ combineRanges r1 r2 = r ...@@ -144,13 +87,25 @@ 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"))
-- rewrite the declarations, expressions, and lvals in a module item to remove traverseModuleItemM :: ModuleItem -> State Info ModuleItem
-- the packed array dimensions captured in the given info traverseModuleItemM item =
rewrite :: Info -> ModuleItem -> ModuleItem traverseLHSsM traverseLHSM item >>=
rewrite info = traverseExprsM traverseExprM
traverseDecls (flattenDecl info) .
traverseLHSs (traverseNestedLHSs rewriteLHS ) . traverseStmtM :: Stmt -> State Info Stmt
traverseExprs (traverseNestedExprs rewriteExpr) 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 where
typeDims = sTypeDims info typeDims = sTypeDims info
...@@ -249,9 +204,16 @@ rewrite info = ...@@ -249,9 +204,16 @@ rewrite info =
range' = (base, len) range' = (base, len)
rewriteExpr other = other rewriteExpr other = other
-- LHSs need to be converted too. Rather than duplicating the -- LHSs need to be converted too. Rather than duplicating the procedures, we
-- procedures, we turn the relevant LHSs into expressions temporarily -- turn the relevant LHSs into expressions temporarily and use the expression
-- and use the expression conversion written above. -- conversion written above.
traverseLHS :: Info -> LHS -> LHS
traverseLHS info =
rewriteLHS
where
typeDims = sTypeDims info
rewriteExpr = traverseExpr info
rewriteLHS :: LHS -> LHS rewriteLHS :: LHS -> LHS
rewriteLHS (LHSIdent x) = rewriteLHS (LHSIdent x) =
LHSIdent x' LHSIdent x'
......
...@@ -32,6 +32,9 @@ module Convert.Traverse ...@@ -32,6 +32,9 @@ module Convert.Traverse
, traverseExprsM' , traverseExprsM'
, traverseExprs' , traverseExprs'
, collectExprsM' , collectExprsM'
, traverseStmtExprsM
, traverseStmtExprs
, collectStmtExprsM
, traverseLHSsM , traverseLHSsM
, traverseLHSs , traverseLHSs
, collectLHSsM , collectLHSsM
...@@ -61,11 +64,14 @@ module Convert.Traverse ...@@ -61,11 +64,14 @@ module Convert.Traverse
, collectNestedModuleItemsM , collectNestedModuleItemsM
, traverseNestedStmts , traverseNestedStmts
, collectNestedStmtsM , collectNestedStmtsM
, traverseNestedExprsM
, traverseNestedExprs , traverseNestedExprs
, collectNestedExprsM , collectNestedExprsM
, traverseNestedLHSsM , traverseNestedLHSsM
, traverseNestedLHSs , traverseNestedLHSs
, collectNestedLHSsM , collectNestedLHSsM
, traverseScopesM
, stately
) where ) where
import Control.Monad.State import Control.Monad.State
...@@ -188,7 +194,12 @@ collectStmtsM = collectStmtsM' IncludeTFs ...@@ -188,7 +194,12 @@ collectStmtsM = collectStmtsM' IncludeTFs
traverseNestedStmtsM :: Monad m => MapperM m Stmt -> MapperM m Stmt traverseNestedStmtsM :: Monad m => MapperM m Stmt -> MapperM m Stmt
traverseNestedStmtsM mapper = fullMapper traverseNestedStmtsM mapper = fullMapper
where 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 (StmtAttr a stmt) = fullMapper stmt >>= return . StmtAttr a
cs (Block name decls stmts) = cs (Block name decls stmts) =
mapM fullMapper stmts >>= return . Block name decls mapM fullMapper stmts >>= return . Block name decls
...@@ -430,9 +441,10 @@ traverseNestedExprsM mapper = exprMapper ...@@ -430,9 +441,10 @@ traverseNestedExprsM mapper = exprMapper
exprs <- mapM exprMapper $ map snd l exprs <- mapM exprMapper $ map snd l
return $ Pattern $ zip names exprs return $ Pattern $ zip names exprs
exprMapperHelpers :: Monad m => MapperM m Expr ->
traverseExprsM' :: Monad m => TFStrategy -> MapperM m Expr -> MapperM m ModuleItem (MapperM m Range, MapperM m (Maybe Expr), MapperM m Decl)
traverseExprsM' strat mapper = moduleItemMapper exprMapperHelpers exprMapper =
(rangeMapper, maybeExprMapper, declMapper)
where where
rangeMapper (a, b) = do rangeMapper (a, b) = do
...@@ -453,59 +465,14 @@ traverseExprsM' strat mapper = moduleItemMapper ...@@ -453,59 +465,14 @@ traverseExprsM' strat mapper = moduleItemMapper
me' <- maybeExprMapper me me' <- maybeExprMapper me
return $ Variable d t x a' me' return $ Variable d t x a' me'
exprMapper = mapper traverseExprsM' :: Monad m => TFStrategy -> MapperM m Expr -> MapperM m ModuleItem
traverseExprsM' strat exprMapper = moduleItemMapper
caseMapper (exprs, stmt) = do where
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 (rangeMapper, maybeExprMapper, declMapper)
initMapper (Right (l, e)) = exprMapper e >>= \e' -> return $ Right (l, e') = exprMapperHelpers exprMapper
asgnMapper (l, op, e) = exprMapper e >>= \e' -> return $ (l, op, e') stmtMapper = traverseNestedStmtsM (traverseStmtExprsM exprMapper)
portBindingMapper (p, me) = portBindingMapper (p, me) =
maybeExprMapper me >>= \me' -> return (p, me') maybeExprMapper me >>= \me' -> return (p, me')
...@@ -602,6 +569,70 @@ traverseExprs = traverseExprs' IncludeTFs ...@@ -602,6 +569,70 @@ traverseExprs = traverseExprs' IncludeTFs
collectExprsM :: Monad m => CollectorM m Expr -> CollectorM m ModuleItem collectExprsM :: Monad m => CollectorM m Expr -> CollectorM m ModuleItem
collectExprsM = collectExprsM' IncludeTFs 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' :: Monad m => TFStrategy -> MapperM m LHS -> MapperM m ModuleItem
traverseLHSsM' strat mapper item = traverseLHSsM' strat mapper item =
traverseStmtsM' strat (traverseStmtLHSsM mapper) item >>= traverseModuleItemLHSsM traverseStmtsM' strat (traverseStmtLHSsM mapper) item >>= traverseModuleItemLHSsM
...@@ -837,3 +868,68 @@ traverseNestedExprs :: Mapper Expr -> Mapper Expr ...@@ -837,3 +868,68 @@ traverseNestedExprs :: Mapper Expr -> Mapper Expr
traverseNestedExprs = unmonad traverseNestedExprsM traverseNestedExprs = unmonad traverseNestedExprsM
collectNestedExprsM :: Monad m => CollectorM m Expr -> CollectorM m Expr collectNestedExprsM :: Monad m => CollectorM m Expr -> CollectorM m Expr
collectNestedExprsM = collectify traverseNestedExprsM 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; ...@@ -94,21 +94,180 @@ module top;
end 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; task magic;
begin begin
begin : magic_block begin : magic_block1
logic [1:0][1:0] magic_arr; logic [1:0][1:0] magic_arr;
magic_arr = 4'b1001; magic_arr = 4'b1001;
$display("$bits(magic_arr): ", $bits(magic_arr )); $display("MB1: $bits(magic_arr): ", $bits(magic_arr ));
$display("$bits(magic_arr[0]): ", $bits(magic_arr[0] )); $display("MB1: $bits(magic_arr[0]): ", $bits(magic_arr[0] ));
$display("$bits(magic_arr[0][0]): ", $bits(magic_arr[0][0])); $display("MB1: $bits(magic_arr[0][0]): ", $bits(magic_arr[0][0]));
$display("magic_arr[0][0]: ", magic_arr[0][0]); $display("MB1: magic_arr[0]: ", magic_arr[0]);
$display("magic_arr[0][1]: ", magic_arr[0][1]); $display("MB1: magic_arr[1]: ", magic_arr[1]);
$display("magic_arr[1][0]: ", magic_arr[1][0]); $display("MB1: magic_arr[0][1]: ", magic_arr[0][1]);
$display("magic_arr[1][1]: ", magic_arr[1][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
end end
endtask endtask
initial magic(); 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 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