对于`define Macro中的循环

时间:2016-04-15 10:03:22

标签: verilog hdl user-defined-types preprocessor-directive

我搜索了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

有人问过更多次,但任何人都没有给出适当的解决方案,任何帮助都会得到很多赞赏。

2 个答案:

答案 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中没有循环指令。有些选择是:

  • 手动编写宏。也许你可以在文本编辑器中找到一些功能来帮助你做到这一点
  • 使用其他一些宏预处理器来生成代码。这可能会使调试变得困难,因为您必须管理两组源代码文件。
  • 重构代码以使用数组而不是具有单独命名的参数