Verilog For `定义宏中的循环

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 =

我在网上搜索,没有找到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)
// # 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中没有循环指令。您可以选择以下选项:

  • 手工写出宏。也许您可以在文本编辑器中找到一些函数来帮助您完成这项工作

  • 使用其他宏预处理器生成代码。这会使调试变得困难,因为您必须管理两组源代码文件
  • 重新构造代码以使用数组,而不是使用单独命名的参数

你的解释太完美了!我理解了这个概念,现在我应该为第二个代码做什么?在编译时是否可能有重复或“for”循环之类的事情?。或者这是不可能的?您只有一组有限的编译器指令,使用
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时查看帮助菜单