mirror of https://github.com/zachjs/sv2v.git
handle naming and scoping of unnamed generate blocks
This commit is contained in:
parent
6e85245118
commit
9d7f917608
|
|
@ -47,6 +47,7 @@ import qualified Convert.Typedef
|
||||||
import qualified Convert.TypeOf
|
import qualified Convert.TypeOf
|
||||||
import qualified Convert.UnbasedUnsized
|
import qualified Convert.UnbasedUnsized
|
||||||
import qualified Convert.Unique
|
import qualified Convert.Unique
|
||||||
|
import qualified Convert.UnnamedGenBlock
|
||||||
import qualified Convert.UnpackedArray
|
import qualified Convert.UnpackedArray
|
||||||
import qualified Convert.Unsigned
|
import qualified Convert.Unsigned
|
||||||
import qualified Convert.Wildcard
|
import qualified Convert.Wildcard
|
||||||
|
|
@ -105,6 +106,7 @@ initialPhases selectExclude =
|
||||||
, Convert.Package.convert
|
, Convert.Package.convert
|
||||||
, Convert.ParamNoDefault.convert
|
, Convert.ParamNoDefault.convert
|
||||||
, Convert.ResolveBindings.convert
|
, Convert.ResolveBindings.convert
|
||||||
|
, Convert.UnnamedGenBlock.convert
|
||||||
]
|
]
|
||||||
|
|
||||||
convert :: [Job.Exclude] -> Phase
|
convert :: [Job.Exclude] -> Phase
|
||||||
|
|
|
||||||
|
|
@ -341,7 +341,7 @@ inlineInstance global ranges modportBindings items partName
|
||||||
comment :
|
comment :
|
||||||
map (MIPackageItem . Decl) bindingBaseParams ++
|
map (MIPackageItem . Decl) bindingBaseParams ++
|
||||||
map (MIPackageItem . Decl) parameterBinds ++
|
map (MIPackageItem . Decl) parameterBinds ++
|
||||||
(wrapInstance $ GenBlock instanceName $ map GenModuleItem items')
|
wrapInstance instanceName items'
|
||||||
: portBindings
|
: portBindings
|
||||||
where
|
where
|
||||||
items' = evalScoper
|
items' = evalScoper
|
||||||
|
|
@ -367,11 +367,20 @@ inlineInstance global ranges modportBindings items partName
|
||||||
|
|
||||||
comment = MIPackageItem $ Decl $ CommentDecl $
|
comment = MIPackageItem $ Decl $ CommentDecl $
|
||||||
"expanded " ++ inlineKind ++ " instance: " ++ instanceName
|
"expanded " ++ inlineKind ++ " instance: " ++ instanceName
|
||||||
portBindings = mapMaybe portBindingItem $
|
portBindings =
|
||||||
|
wrapPortBindings $
|
||||||
|
map portBindingItem $
|
||||||
|
filter ((/= Nil) . snd) $
|
||||||
filter notSubstituted instancePorts
|
filter notSubstituted instancePorts
|
||||||
notSubstituted :: PortBinding -> Bool
|
notSubstituted :: PortBinding -> Bool
|
||||||
notSubstituted (portName, _) =
|
notSubstituted (portName, _) =
|
||||||
lookup portName modportBindings == Nothing
|
lookup portName modportBindings == Nothing
|
||||||
|
wrapPortBindings :: [ModuleItem] -> [ModuleItem]
|
||||||
|
wrapPortBindings =
|
||||||
|
if isArray
|
||||||
|
then (\x -> [x]) . wrapInstance blockName
|
||||||
|
else id
|
||||||
|
where blockName = instanceName ++ "_port_bindings"
|
||||||
|
|
||||||
rewriteItem :: ModuleItem -> ModuleItem
|
rewriteItem :: ModuleItem -> ModuleItem
|
||||||
rewriteItem =
|
rewriteItem =
|
||||||
|
|
@ -573,10 +582,8 @@ inlineInstance global ranges modportBindings items partName
|
||||||
++ " expected type, found expr: " ++ show e'
|
++ " expected type, found expr: " ++ show e'
|
||||||
overrideParam other = other
|
overrideParam other = other
|
||||||
|
|
||||||
portBindingItem :: PortBinding -> Maybe ModuleItem
|
portBindingItem :: PortBinding -> ModuleItem
|
||||||
portBindingItem (_, Nil) = Nothing
|
|
||||||
portBindingItem (ident, expr) =
|
portBindingItem (ident, expr) =
|
||||||
Just $ wrapInstance $ GenModuleItem $
|
|
||||||
if findDeclDir ident == Input
|
if findDeclDir ident == Input
|
||||||
then bind (LHSDot (inj LHSBit LHSIdent) ident) expr
|
then bind (LHSDot (inj LHSBit LHSIdent) ident) expr
|
||||||
else bind (toLHS expr) (Dot (inj Bit Ident) ident)
|
else bind (toLHS expr) (Dot (inj Bit Ident) ident)
|
||||||
|
|
@ -614,8 +621,8 @@ inlineInstance global ranges modportBindings items partName
|
||||||
[arrayRange @ (arrayLeft, arrayRight)] = ranges
|
[arrayRange @ (arrayLeft, arrayRight)] = ranges
|
||||||
|
|
||||||
-- wrap the given item in a generate loop if necessary
|
-- wrap the given item in a generate loop if necessary
|
||||||
wrapInstance :: GenItem -> ModuleItem
|
wrapInstance :: Identifier -> [ModuleItem] -> ModuleItem
|
||||||
wrapInstance item =
|
wrapInstance blockName moduleItems =
|
||||||
Generate $
|
Generate $
|
||||||
if not isArray then
|
if not isArray then
|
||||||
[item]
|
[item]
|
||||||
|
|
@ -624,6 +631,7 @@ inlineInstance global ranges modportBindings items partName
|
||||||
, GenFor inits cond incr item
|
, GenFor inits cond incr item
|
||||||
]
|
]
|
||||||
where
|
where
|
||||||
|
item = GenBlock blockName $ map GenModuleItem moduleItems
|
||||||
inits = (loopVar, arrayLeft)
|
inits = (loopVar, arrayLeft)
|
||||||
cond = endianCondExpr arrayRange
|
cond = endianCondExpr arrayRange
|
||||||
(BinOp Ge (Ident loopVar) arrayRight)
|
(BinOp Ge (Ident loopVar) arrayRight)
|
||||||
|
|
|
||||||
|
|
@ -512,8 +512,6 @@ scopeModuleItemT declMapper moduleItemMapper genItemMapper stmtMapper =
|
||||||
fullModuleItemMapper item >>= return . MIAttr attr
|
fullModuleItemMapper item >>= return . MIAttr attr
|
||||||
fullModuleItemMapper item = moduleItemMapper item
|
fullModuleItemMapper item = moduleItemMapper item
|
||||||
|
|
||||||
-- TODO: This doesn't yet support implicit naming of generate blocks as
|
|
||||||
-- blocks as described in Section 27.6.
|
|
||||||
fullGenItemMapper :: GenItem -> ScoperT a m GenItem
|
fullGenItemMapper :: GenItem -> ScoperT a m GenItem
|
||||||
fullGenItemMapper genItem = do
|
fullGenItemMapper genItem = do
|
||||||
genItem' <- genItemMapper genItem
|
genItem' <- genItemMapper genItem
|
||||||
|
|
@ -524,7 +522,7 @@ scopeModuleItemT declMapper moduleItemMapper genItemMapper stmtMapper =
|
||||||
injected' <- mapM fullModuleItemMapper injected
|
injected' <- mapM fullModuleItemMapper injected
|
||||||
genItem'' <- scopeGenItemMapper genItem'
|
genItem'' <- scopeGenItemMapper genItem'
|
||||||
let genItems = map GenModuleItem injected' ++ [genItem'']
|
let genItems = map GenModuleItem injected' ++ [genItem'']
|
||||||
return $ GenBlock "" genItems
|
return $ GenBlock "" genItems -- flattened during traversal
|
||||||
scopeGenItemMapper :: GenItem -> ScoperT a m GenItem
|
scopeGenItemMapper :: GenItem -> ScoperT a m GenItem
|
||||||
scopeGenItemMapper (GenFor (index, a) b c genItem) = do
|
scopeGenItemMapper (GenFor (index, a) b c genItem) = do
|
||||||
genItem' <- scopeGenItemBranchMapper index genItem
|
genItem' <- scopeGenItemBranchMapper index genItem
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
{- sv2v
|
||||||
|
- Author: Zachary Snow <zach@zachjs.com>
|
||||||
|
-
|
||||||
|
- Labels any unnamed generate blocks, per IEEE 1800-2017 Section 27.6
|
||||||
|
-
|
||||||
|
- This transformation is performed before any others, and is only performed
|
||||||
|
- once. The AST traversal utilities are not used here to avoid the automatic
|
||||||
|
- elaboration they perform.
|
||||||
|
-}
|
||||||
|
|
||||||
|
module Convert.UnnamedGenBlock (convert) where
|
||||||
|
|
||||||
|
import Control.Monad.State.Strict
|
||||||
|
import Data.List (isPrefixOf)
|
||||||
|
|
||||||
|
import Language.SystemVerilog.AST
|
||||||
|
|
||||||
|
convert :: [AST] -> [AST]
|
||||||
|
convert = map $ map traverseDescription
|
||||||
|
|
||||||
|
traverseDescription :: Description -> Description
|
||||||
|
traverseDescription (Part attrs extern kw lifetime name ports items) =
|
||||||
|
Part attrs extern kw lifetime name ports $
|
||||||
|
evalState (mapM traverseModuleItemM items) initialState
|
||||||
|
traverseDescription other = other
|
||||||
|
|
||||||
|
type S = State Info
|
||||||
|
type Info = ([Identifier], Int)
|
||||||
|
|
||||||
|
initialState :: Info
|
||||||
|
initialState = ([], 1)
|
||||||
|
|
||||||
|
traverseModuleItemM :: ModuleItem -> S ModuleItem
|
||||||
|
traverseModuleItemM (item @ (Genvar x)) = declaration x item
|
||||||
|
traverseModuleItemM (item @ (NInputGate _ _ x _ _)) = declaration x item
|
||||||
|
traverseModuleItemM (item @ (NOutputGate _ _ x _ _)) = declaration x item
|
||||||
|
traverseModuleItemM (item @ (Instance _ _ x _ _)) = declaration x item
|
||||||
|
traverseModuleItemM (MIPackageItem (Decl decl)) =
|
||||||
|
traverseDeclM decl >>= return . MIPackageItem . Decl
|
||||||
|
traverseModuleItemM (MIAttr attr item) =
|
||||||
|
traverseModuleItemM item >>= return . MIAttr attr
|
||||||
|
traverseModuleItemM (Generate items) =
|
||||||
|
mapM traverseGenItemM items >>= return . Generate
|
||||||
|
traverseModuleItemM item = return item
|
||||||
|
|
||||||
|
-- add a declaration to the conflict list
|
||||||
|
traverseDeclM :: Decl -> S Decl
|
||||||
|
traverseDeclM decl =
|
||||||
|
case decl of
|
||||||
|
Variable _ _ x _ _ -> declaration x decl
|
||||||
|
Param _ _ x _ -> declaration x decl
|
||||||
|
ParamType _ x _ -> declaration x decl
|
||||||
|
CommentDecl{} -> return decl
|
||||||
|
|
||||||
|
-- label the generate blocks within an individual generate item which is already
|
||||||
|
-- in a list of generate items (top level or generate block)
|
||||||
|
traverseGenItemM :: GenItem -> S GenItem
|
||||||
|
traverseGenItemM (item @ GenIf{}) = do
|
||||||
|
item' <- labelGenElse item
|
||||||
|
incrCount >> return item'
|
||||||
|
traverseGenItemM (item @ GenBlock{}) = do
|
||||||
|
item' <- labelBlock item
|
||||||
|
incrCount >> return item'
|
||||||
|
traverseGenItemM (GenFor a b c item) = do
|
||||||
|
item' <- labelBlock item
|
||||||
|
incrCount >> return (GenFor a b c item')
|
||||||
|
traverseGenItemM (GenCase expr cases) = do
|
||||||
|
let (exprs, items) = unzip cases
|
||||||
|
items' <- mapM labelBlock items
|
||||||
|
let cases' = zip exprs items'
|
||||||
|
incrCount >> return (GenCase expr cases')
|
||||||
|
traverseGenItemM (GenModuleItem item) =
|
||||||
|
traverseModuleItemM item >>= return . GenModuleItem
|
||||||
|
traverseGenItemM GenNull = return GenNull
|
||||||
|
|
||||||
|
-- increment the counter each time a generate construct is encountered
|
||||||
|
incrCount :: S ()
|
||||||
|
incrCount = modify' $ \(idents, count) -> (idents, count + 1)
|
||||||
|
|
||||||
|
genblk :: Identifier
|
||||||
|
genblk = "genblk"
|
||||||
|
|
||||||
|
-- adds the given identifier to the list of possible identifier conflicts, if
|
||||||
|
-- necessary, and then returns the second argument as a shorthand courtesy
|
||||||
|
declaration :: Identifier -> a -> S a
|
||||||
|
declaration x a = do
|
||||||
|
when (genblk `isPrefixOf` x) $ do
|
||||||
|
let ident = drop (length genblk) x
|
||||||
|
modify' $ \(idents, count) -> (ident : idents, count)
|
||||||
|
return a
|
||||||
|
|
||||||
|
-- generate a locally unique gen block name
|
||||||
|
makeBlockName :: S Identifier
|
||||||
|
makeBlockName = do
|
||||||
|
(idents, count) <- get
|
||||||
|
let uniqueSuffix = prependZeroes idents (show count)
|
||||||
|
return $ genblk ++ uniqueSuffix
|
||||||
|
|
||||||
|
-- prepend zeroes until the string isn't in the list
|
||||||
|
prependZeroes :: [String] -> String -> String
|
||||||
|
prependZeroes xs x | notElem x xs = x
|
||||||
|
prependZeroes xs x = prependZeroes xs ('0' : x)
|
||||||
|
|
||||||
|
-- if the item is a generate conditional item, give its `then` block and any
|
||||||
|
-- direct `else if` blocks the same name
|
||||||
|
labelGenElse :: GenItem -> S GenItem
|
||||||
|
labelGenElse (GenIf cond thenItem elseItem) = do
|
||||||
|
thenItem' <- labelBlock thenItem
|
||||||
|
elseItem' <- labelGenElse elseItem
|
||||||
|
return $ GenIf cond thenItem' elseItem'
|
||||||
|
labelGenElse other = labelBlock other
|
||||||
|
|
||||||
|
-- transform the given item into a named generate block
|
||||||
|
labelBlock :: GenItem -> S GenItem
|
||||||
|
labelBlock (GenBlock "" items) =
|
||||||
|
makeBlockName >>= labelBlock . flip GenBlock items
|
||||||
|
labelBlock (GenBlock x items) =
|
||||||
|
return $ GenBlock x $
|
||||||
|
evalState (mapM traverseGenItemM items) initialState
|
||||||
|
labelBlock GenNull = return GenNull
|
||||||
|
labelBlock item = labelBlock $ GenBlock "" [item]
|
||||||
|
|
@ -1352,6 +1352,7 @@ GenItems :: { [GenItem] }
|
||||||
GenItem :: { GenItem }
|
GenItem :: { GenItem }
|
||||||
: GenBlock { uncurry GenBlock $1 }
|
: GenBlock { uncurry GenBlock $1 }
|
||||||
| NonGenerateModuleItem { genItemsToGenItem $ map GenModuleItem $1 }
|
| NonGenerateModuleItem { genItemsToGenItem $ map GenModuleItem $1 }
|
||||||
|
| "generate" GenItems "endgenerate" { genItemsToGenItem $2 }
|
||||||
| ConditionalGenerateConstruct { $1 }
|
| ConditionalGenerateConstruct { $1 }
|
||||||
| LoopGenerateConstruct { $1 }
|
| LoopGenerateConstruct { $1 }
|
||||||
ConditionalGenerateConstruct :: { GenItem }
|
ConditionalGenerateConstruct :: { GenItem }
|
||||||
|
|
@ -1375,7 +1376,7 @@ GenCase :: { GenCase }
|
||||||
| "default" opt(":") GenItemOrNull { ([], $3) }
|
| "default" opt(":") GenItemOrNull { ([], $3) }
|
||||||
|
|
||||||
GenvarInitialization :: { Expr -> (Identifier, AsgnOp, Expr) -> GenItem -> GenItem }
|
GenvarInitialization :: { Expr -> (Identifier, AsgnOp, Expr) -> GenItem -> GenItem }
|
||||||
: "genvar" Identifier "=" Expr { \a b c -> GenBlock "" [GenModuleItem (Genvar $2), GenFor ($2, $4) a b c] }
|
: "genvar" Identifier "=" Expr { \a b c -> genItemsToGenItem [GenModuleItem (Genvar $2), GenFor ($2, $4) a b c] }
|
||||||
| Identifier "=" Expr { GenFor ($1, $3) }
|
| Identifier "=" Expr { GenFor ($1, $3) }
|
||||||
|
|
||||||
GenvarIteration :: { (Identifier, AsgnOp, Expr) }
|
GenvarIteration :: { (Identifier, AsgnOp, Expr) }
|
||||||
|
|
@ -1480,7 +1481,7 @@ parseError a = case a of
|
||||||
|
|
||||||
genItemsToGenItem :: [GenItem] -> GenItem
|
genItemsToGenItem :: [GenItem] -> GenItem
|
||||||
genItemsToGenItem [x] = x
|
genItemsToGenItem [x] = x
|
||||||
genItemsToGenItem xs = GenBlock "" xs
|
genItemsToGenItem xs = GenModuleItem $ Generate xs
|
||||||
|
|
||||||
combineDeclsAndStmts :: ([Decl], [Stmt]) -> ([Decl], [Stmt]) ->
|
combineDeclsAndStmts :: ([Decl], [Stmt]) -> ([Decl], [Stmt]) ->
|
||||||
ParseState ([Decl], [Stmt])
|
ParseState ([Decl], [Stmt])
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,7 @@ executable sv2v
|
||||||
Convert.TypeOf
|
Convert.TypeOf
|
||||||
Convert.UnbasedUnsized
|
Convert.UnbasedUnsized
|
||||||
Convert.Unique
|
Convert.Unique
|
||||||
|
Convert.UnnamedGenBlock
|
||||||
Convert.UnpackedArray
|
Convert.UnpackedArray
|
||||||
Convert.Unsigned
|
Convert.Unsigned
|
||||||
Convert.Wildcard
|
Convert.Wildcard
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
module top;
|
||||||
|
if (1) begin
|
||||||
|
// should not be visible in a top-level VCD
|
||||||
|
wire x;
|
||||||
|
assign x = 1;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
// This test was adapted from Section 27.6 of IEEE 1800-2017
|
||||||
|
|
||||||
|
module mod;
|
||||||
|
initial $dumpvars(0, mod);
|
||||||
|
// needed because of steveicarus/iverilog#528
|
||||||
|
`ifdef __ICARUS__
|
||||||
|
`define BEGIN(name) begin : name
|
||||||
|
`define END end
|
||||||
|
`else
|
||||||
|
`define BEGIN(name)
|
||||||
|
`define END
|
||||||
|
`endif
|
||||||
|
|
||||||
|
parameter genblk2 = 0;
|
||||||
|
genvar i;
|
||||||
|
|
||||||
|
// The following generate block is implicitly named genblk1
|
||||||
|
|
||||||
|
if (genblk2) `BEGIN(genblk1) logic a; `END // mod.genblk1.a
|
||||||
|
else `BEGIN(genblk1) logic b; `END // mod.genblk1.b
|
||||||
|
|
||||||
|
// The following generate block is implicitly named genblk02
|
||||||
|
// as genblk2 is already a declared identifier
|
||||||
|
|
||||||
|
if (genblk2) `BEGIN(genblk02) logic a; `END // mod.genblk02.a
|
||||||
|
else `BEGIN(genblk02) logic b; `END // mod.genblk02.b
|
||||||
|
|
||||||
|
// The following generate block would have been named genblk3
|
||||||
|
// but is explicitly named g1
|
||||||
|
|
||||||
|
for (i = 0; i < 1; i = i + 1) begin : g1 // block name
|
||||||
|
// The following generate block is implicitly named genblk1
|
||||||
|
// as the first nested scope inside g1
|
||||||
|
if (1) `BEGIN(genblk1) logic a; `END // mod.g1[0].genblk1.a
|
||||||
|
end
|
||||||
|
|
||||||
|
// The following generate block is implicitly named genblk4 since
|
||||||
|
// it belongs to the fourth generate construct in scope "mod".
|
||||||
|
// The previous generate block would have been
|
||||||
|
// named genblk3 if it had not been explicitly named g1
|
||||||
|
|
||||||
|
for (i = 0; i < 1; i = i + 1) `BEGIN(genblk4)
|
||||||
|
// The following generate block is implicitly named genblk1
|
||||||
|
// as the first nested generate block in genblk4
|
||||||
|
if (1) `BEGIN(genblk1) logic a; `END // mod.genblk4[0].genblk1.a
|
||||||
|
`END
|
||||||
|
|
||||||
|
// The following generate block is implicitly named genblk5
|
||||||
|
if (1) `BEGIN(genblk5) logic a; `END // mod.genblk5.a
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module top;
|
||||||
|
mod #(0) m0();
|
||||||
|
mod #(1) m1();
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
module example;
|
||||||
|
parameter P = 0;
|
||||||
|
|
||||||
|
// needed because of steveicarus/iverilog#528
|
||||||
|
`ifdef __ICARUS__
|
||||||
|
`define BEGIN begin : `BLK
|
||||||
|
`define END end
|
||||||
|
`else
|
||||||
|
`define BEGIN
|
||||||
|
`define END
|
||||||
|
`endif
|
||||||
|
|
||||||
|
`define BLK genblk1
|
||||||
|
if (P == 1) `BEGIN integer w = 1; `END
|
||||||
|
else if (P == 2) `BEGIN integer x = 2; `END
|
||||||
|
else if (P == 3) `BEGIN integer y = 3; `END
|
||||||
|
else `BEGIN integer z = 9; `END
|
||||||
|
|
||||||
|
`undef BLK
|
||||||
|
`define BLK genblk2
|
||||||
|
case (P)
|
||||||
|
1 : `BEGIN integer w = 1; `END
|
||||||
|
2 : `BEGIN integer x = 2; `END
|
||||||
|
3 : `BEGIN integer y = 3; `END
|
||||||
|
default: `BEGIN integer z = 9; `END
|
||||||
|
endcase
|
||||||
|
|
||||||
|
`undef BLK
|
||||||
|
`define BLK genblk3
|
||||||
|
if (1) `BEGIN wire a = 1; `END
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module top;
|
||||||
|
`define TEST(i, v) \
|
||||||
|
example #(i) e``i(); \
|
||||||
|
initial #i begin \
|
||||||
|
$display(`"e``i.genblk1.v: %0d`", e``i.genblk1.v); \
|
||||||
|
$display(`"e``i.genblk2.v: %0d`", e``i.genblk2.v); \
|
||||||
|
$display(`"e``i.genblk3.a: %0d`", e``i.genblk3.a); \
|
||||||
|
end
|
||||||
|
`TEST(1, w)
|
||||||
|
`TEST(2, x)
|
||||||
|
`TEST(3, y)
|
||||||
|
`TEST(4, z)
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
module example;
|
||||||
|
initial $display("example");
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module top;
|
||||||
|
wire genblk1;
|
||||||
|
wire genblk33;
|
||||||
|
(* foo = 1 *) wire genblk01;
|
||||||
|
genvar genblk001;
|
||||||
|
example genblk0001();
|
||||||
|
|
||||||
|
wire x, y;
|
||||||
|
wire o1, o2, o3;
|
||||||
|
and genblk00001(o1, x, y);
|
||||||
|
not genblk000001(o2, o3, o1);
|
||||||
|
|
||||||
|
parameter genblk0000001 = 1;
|
||||||
|
`ifndef REF
|
||||||
|
typedef logic genblk00000001;
|
||||||
|
`endif
|
||||||
|
|
||||||
|
`define BLK genblk000000001
|
||||||
|
|
||||||
|
if (1) begin
|
||||||
|
`ifdef REF
|
||||||
|
: `BLK
|
||||||
|
reg
|
||||||
|
`else
|
||||||
|
genblk00000001
|
||||||
|
`endif
|
||||||
|
x = genblk0000001;
|
||||||
|
end
|
||||||
|
initial begin
|
||||||
|
`BLK.x = 1;
|
||||||
|
$display("%b", `BLK.x);
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
`define REF
|
||||||
|
`include "unnamed_genblk_zeroes.sv"
|
||||||
Loading…
Reference in New Issue