我搜索了SO,在网络上,没有找到ans。 我有以下代码,成功完全解析了`定义并生成预期结果,但如果调用宏的次数很大,那么我们可以使用 循环构造吗? 。
`define myreg(name) \
addr_``name
`define para(i) \
parameter `myreg(i) = i
module register;
`para(1);
`para(2);
`para(3);
`para(4);
initial
begin
$display("ADDR1 = %d, ADDR2 = %d", addr_1, addr_2);
$display("ADDR3 = %d, ADDR4 = %d", addr_3, addr_4);
#100 $finish;
end
endmodule
模拟结果:
// # Loading work.register(fast)
// # run -all
// # ADDR1 = 1, ADDR2 = 2
// # ADDR3 = 3, ADDR4 = 4
// # ** Note: $finish : reg.v(18)
现在,当我使用 for loop 时,如下面的代码所示,
`define myreg(name) \
addr_``name
`define para(i) \
parameter `myreg(i) = i
module register;
genvar i;
generate
for (i = 1; i<=4; i=i+1)
begin
`para(i);
end
endgenerate
initial
begin
$display("ADDR1 = %d, ADDR2 = %d", addr_1, addr_2);
$display("ADDR3 = %d, ADDR4 = %d", addr_3, addr_4);
#100 $finish;
end
endmodule
在这种情况下,它在显示或使用时显示错误, 模拟结果:
// # vsim -lib work register -c -do "run -all; quit -f" -appendlog -l qverilog.log -vopt
// # ** Note: (vsim-3813) Design is being optimized due to module recompilation...
// # ** Error (suppressible): (vopt-7063) reg.v(24): Failed to find 'addr_1' in hierarchical name '/addr_1'.
// # ** Error (suppressible): (vopt-7063) reg.v(24): Failed to find 'addr_2' in hierarchical name '/addr_2'.
// # ** Error (suppressible): (vopt-7063) reg.v(25): Failed to find 'addr_3' in hierarchical name '/addr_3'.
// # ** Error (suppressible): (vopt-7063) reg.v(25): Failed to find 'addr_4' in hierarchical name '/addr_4'.
// # Optimization failed
// # Error loading design
有人问过更多次,但任何人都没有给出适当的解决方案,任何帮助都会得到很多赞赏。
答案 0 :(得分:3)
对于任何模拟,都会发生以下事件序列:
编译阶段==&gt;精化阶段==&gt;运行阶段(模拟阶段)
在编译时,执行语法错误检查和宏文本替换。 计算所有变量的内存并构建可执行文件。在编译期间,程序的源代码被翻译到可执行代码。
在详细时间,形成实例之间的实例和连接。通过连接,我的意思是检查端口宽度和端口存在等。因为,实际实例已创建,参数也已评估< / strong>在精心制作的时候。
运行时,当然,实际模拟开始从病房零时间开始运行。
宏在编译时(因此称为编译器指令)进行评估,而generate
块在精化时进行评估。
参考IEEE 1800-2012,第27.3节:
在详细阐述设计期间评估生成方案。 ... 它们在精化时评估,结果在模拟开始之前确定。因此,生成方案中的所有表达式都应是常量表达式,在精化时确定性。
第一个示例运行是因为一切都在编译时完成。所有变量都在编译时声明。因此代码工作正常。
在第二个示例中,您尝试在精心制作时 声明变量 ,这是不允许的。在精化时不再分配内存到变量。
有关编译和制定时间的更多信息,请参阅IEEE 1800-2012第3.12节。
答案 1 :(得分:1)
问题实际上比sharvil111解释的要简单得多。
指令`define
s,`ifdef
和`include
都由预处理器处理,该预处理器生成文本流并被送入编译器。预处理器对Verilog语法一无所知,编译器也没有看到任何这些指令,因为它们已经被处理掉了。
您实际上可以通过添加vlog -E <filename>
选项来查看此中间文本流,该选项将预处理器的输出写入
Verilog / SystemVerilog中没有循环指令。有些选择是: