Verilog For `定义宏中的循环
我在网上搜索,没有找到ans。 我有以下代码,它成功地完全解析了`定义并生成预期结果,但如果宏的调用次数很大,我们可以使用循环构造吗?Verilog For `定义宏中的循环,verilog,hdl,user-defined-types,preprocessor-directive,Verilog,Hdl,User Defined Types,Preprocessor Directive,我在网上搜索,没有找到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 =
`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)
// # 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
现在,当我对循环使用时,就像下面的代码一样
`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
它被询问了很多次,但没有任何人给出正确的解决方案,任何帮助都非常感谢。对于任何模拟,都会发生以下事件序列: 编译阶段==>精化阶段==>运行阶段(模拟阶段) 在编译时执行语法错误检查和宏文本替换计算所有变量的内存,并生成可执行文件。在编译时,程序的源代码被翻译成可执行代码 在精化时间,实例之间形成了实例和连接。通过连接性,我的意思是检查端口宽度和端口存在等。由于创建了实际实例,参数也在细化时进行评估 当然,在运行时间时,实际模拟从零开始运行 宏在编译时求值(因此称为编译器指令),而
生成
块在精化时求值
`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
参考第27.3节:
生成方案在设计的细化过程中进行评估。
...
在细化时对其进行评估,并在模拟开始之前确定结果。因此,生成方案中的所有表达式应为常量表达式,在细化时具有确定性
第一个示例之所以运行,是因为一切都是在编译时完成的。所有变量都是在编译时声明的。因此,代码运行良好
在第二个示例中,您试图在细化时声明变量,这是不允许的。细化时不再为变量分配内存
有关编译和精化时间的更多信息,请参阅第3.12节。这个问题实际上比Sharvill111解释的要简单得多 指令
`define
s、`ifdef
s和`include
s都由产生文本流的预处理器处理,并输入编译器。预处理器对Verilog语法一无所知,编译器也看不到这些指令,因为它们已经被处理掉了
通过添加vlog-E
选项,可以看到这个中间文本流,该选项将预处理器的输出写入
Verilog/SystemVerilog中没有循环指令。您可以选择以下选项:
- 手工写出宏。也许您可以在文本编辑器中找到一些函数来帮助您完成这项工作
- 使用其他宏预处理器生成代码。这会使调试变得困难,因为您必须管理两组源代码文件
- 重新构造代码以使用数组,而不是使用单独命名的参数
generate
循环绝不是解决方案。我更喜欢使用由参数控制的变量数组,比如parameter SIZE=5;注册号[7:0]地址[大小]代码>。或者您可以使用一些宏控制数组,如ifdef SIZE reg[7:0]ADDR[SIZE];否则定义尺寸5地址[尺寸];endif
。并提供SIZE
作为模拟开关,如+define+SIZE=5
。这将根据模拟开关覆盖大小
。在注释中,您可以添加它来回答吗?“使用其他宏预处理器生成代码。这可能会导致调试困难,因为您必须管理两组源代码文件。”您能给出任何示例或代码吗?请告诉我,如何使用该vlog-E?它列在Questa/ModelSim参考手册中。我找不到它,请您共享该文档链接和页码好吗?只需键入vlog-help
,或在打开gui时查看帮助菜单