`define 宏中的循环
For loop in `define Macro
我在 SO 上搜索,在网上搜索,没有找到答案。
我有以下代码,它成功地完全解析了`定义并生成了预期的结果,但是如果调用宏的次数很大,那么我们可以使用 Looping Construct? 。
`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 循环时,就像下面的代码一样,
`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
问了很多次,但没有人给出正确的解决方案,任何帮助都非常感谢。
对于任何模拟,都会发生以下事件序列:
Compilation Phase ==> Elaboration Phase ==> Run Phase (Simulation Phase)
在编译时,执行语法错误检查和宏文本替换。 计算所有变量的内存并构建可执行文件。在编译期间,程序的源代码被翻译成可执行代码。
在精化时间,形成实例和实例之间的连接。通过连接,我的意思是检查端口宽度和端口存在等。因为,创建了实际实例,参数也在详细说明时评估。
在运行时间,当然实际模拟开始运行ning从零时间开始病房。
宏在编译时求值(因此称为编译器指令),而generate
块在细化时间。
参考IEEE 1800-2012,第27.3节:
Generate schemes are evaluated during elaboration of the design.
...
They are evaluated at elaboration time, and the result is determined before simulation begins. Therefore, all expressions in generate schemes shall be constant expressions, deterministic at elaboration time.
第一个例子运行因为一切都在编译时完成。所有变量都是在编译时声明的。因此代码工作正常。
在第二个示例中,您试图在详细说明时声明变量,这是不允许的。在详细说明时不再分配 变量 的内存。
参考IEEE 1800-2012第3.12节了解更多关于编译和细化时间的信息。
这个问题实际上比sharvil111解释的要简单得多。
指令 `define
s、`ifdef
s 和 `include
s 都由预处理器处理,该预处理器产生文本流并输入编译器。预处理器对 Verilog 语法一无所知,编译器也看不到任何这些指令,因为它们已被处理掉。
您实际上可以通过添加将预处理器的输出写入
的 vlog -E <filename>
选项来查看此中间文本流
Verilog/SystemVerilog 中没有循环指令。您的一些选择是:
- 手写宏。也许你可以在你的文本编辑器中找到一些功能来帮助你做到这一点
- 使用其他一些宏预处理器生成您的代码。这会使调试变得困难,因为您必须管理两组源代码文件。
- 重组您的代码以使用数组而不是单独命名的参数
我在 SO 上搜索,在网上搜索,没有找到答案。 我有以下代码,它成功地完全解析了`定义并生成了预期的结果,但是如果调用宏的次数很大,那么我们可以使用 Looping Construct? 。
`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 循环时,就像下面的代码一样,
`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
问了很多次,但没有人给出正确的解决方案,任何帮助都非常感谢。
对于任何模拟,都会发生以下事件序列:
Compilation Phase ==> Elaboration Phase ==> Run Phase (Simulation Phase)
在编译时,执行语法错误检查和宏文本替换。 计算所有变量的内存并构建可执行文件。在编译期间,程序的源代码被翻译成可执行代码。
在精化时间,形成实例和实例之间的连接。通过连接,我的意思是检查端口宽度和端口存在等。因为,创建了实际实例,参数也在详细说明时评估。
在运行时间,当然实际模拟开始运行ning从零时间开始病房。
宏在编译时求值(因此称为编译器指令),而generate
块在细化时间。
参考IEEE 1800-2012,第27.3节:
Generate schemes are evaluated during elaboration of the design. ... They are evaluated at elaboration time, and the result is determined before simulation begins. Therefore, all expressions in generate schemes shall be constant expressions, deterministic at elaboration time.
第一个例子运行因为一切都在编译时完成。所有变量都是在编译时声明的。因此代码工作正常。
在第二个示例中,您试图在详细说明时声明变量,这是不允许的。在详细说明时不再分配 变量 的内存。
参考IEEE 1800-2012第3.12节了解更多关于编译和细化时间的信息。
这个问题实际上比sharvil111解释的要简单得多。
指令 `define
s、`ifdef
s 和 `include
s 都由预处理器处理,该预处理器产生文本流并输入编译器。预处理器对 Verilog 语法一无所知,编译器也看不到任何这些指令,因为它们已被处理掉。
您实际上可以通过添加将预处理器的输出写入
的vlog -E <filename>
选项来查看此中间文本流
Verilog/SystemVerilog 中没有循环指令。您的一些选择是:
- 手写宏。也许你可以在你的文本编辑器中找到一些功能来帮助你做到这一点
- 使用其他一些宏预处理器生成您的代码。这会使调试变得困难,因为您必须管理两组源代码文件。
- 重组您的代码以使用数组而不是单独命名的参数