首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Verilog中重用多个始终块

如何在Verilog中重用多个始终块
EN

Stack Overflow用户
提问于 2015-12-10 12:25:47
回答 3查看 1.4K关注 0票数 1

下面是始终块的代码。

我需要有相同的代码11次,具有相同的功能,但对不同的变量。那么,我如何重用代码呢?

代码语言:javascript
复制
  always @(posedge tconClk or negedge tconRst_n)
  begin
    if(~tconRst_n)
    begin
      pulse_cnt <= 0;
      pulse_start = 0;
      start_written = 0;
      pulse_width <= 'h271;
    end
    else if(~pulse_rst)
    begin
      pulse_cnt <= 0;
      pulse_start = 0;
    end
    else
    begin
      if(start_signal)
      begin
//        start_written = 0;
        pulse_width <= (pulse_start) ? pulse_width : START_PW;
        pulse_start = 1;
      end
      pulse_cnt <= (pulse_start) ? (pulse_cnt + 1) : pulse_cnt;
    end
  end

命名模式-

  • tconClktconRst_n很常见,
  • pulse_cnt0pulse_cnt1 upto 10
  • pulse_width0pulse_width1 upto 10
  • pulse_start[0:10] (阵列)
  • start_written[0:10] (阵列)
  • pulse_rst[0:10] (阵列)
  • start_signal[0:10] (阵列)
  • START_PW (没有模式,每个11块都有不同的名称)

注-

  1. 定义宏不起作用,因为这段代码包含许多verilog令牌。
  2. 我无法生成代码的模块,因为始终块中使用的信号也用于代码的其他部分。因此,如果我制作模块,那么我将无法确保正确的reg或连接到模块。(就像模块输出端口必须是导线一样,但在代码的其他部分中,同样的信号被用作reg )。
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-12-11 19:19:16

您可以使用emacs脚本verilog模式,使用模块中的RTL并利用AUTO_TEMPLATE。然后在(或批)emacs中执行类似于以下(未测试)的verilog-batch-auto

代码语言:javascript
复制
/* PulseModule AUTO_TEMPLATE "\([0-9]+\)$" (
     .pulse_cnt(pulse_cnt@),
     .pulse_width(pulse_width@),
     .pulse_start(pulse_start[@]),
     .start_written(start_written[@]),
     .pulse_rst(pulse_rst[@]),
     .start_signal(start_signal[@]),
     .tconClk(tconClk),
     .tconRst_n(tconRst_n)
    );
*/
PulseModule pm_0 (/*AUTOINST*/ .start_pulse_width(START_PW) );
PulseModule pm_1 (/*AUTOINST*/ .start_pulse_width(OTHER_START_PW) );
...
PulseModule pm_10 (/*AUTOINST*/ .start_pulse_width(SOME_OTHER_START_PW) );

还有各种嵌入式代码(如Perl的EP3、Ruby的eRuby/、Python的预演等等)。它可以生成所需的代码。

SystemVerilog增强了宏的功能。对于您来说,``特性将使您的任务更容易。见IEEE Std 1800-2012§22.5.1 `IEEE Std 1800-2012

多行宏很难调试.尽管可以将RTL作为一个宏放置,但我强烈建议将其放在模块中,并让宏实例化宏。某物湖(未测试):

代码语言:javascript
复制
`define PULSEMACRO(id,val) \
   PulseModule pm_``id( \
     .pulse_cnt(pulse_cnt``id), .pulse_width(pulse_width``id), \
     .pulse_start(pulse_start[id]), .start_written(start_written[id]), \
     .pulse_rst(pulse_rst[id]), .start_signal(start_signal[id]), \
     .start_pulse_width(val) \
     .tconClk(tconClk), .tconRst_n(tconRst_n) )

实例化如下所示。请注意,生成for-循环将无法工作。宏在生成块之前进行评估。

代码语言:javascript
复制
`PULSEMACRO(0,START_PW);
`PULSEMACRO(1,OTHER_START_PW);
...
`PULSEMACRO(10,SOME_OTHER_START_PW);

SystemVerilog还可以通过模块端口传递多维数组.因此,您可以将reg [PULSE_CNT_WIDTH-1:0] pulse_cnt0,...,pulse_cnt10重命名为logic [PULSE_CNT_WIDTH-1:0] pulse_cnt [11]。通过这种转换,您可以使用generate循环。

或者,您可以将pulse_cnt折叠成一个大总线reg [PULSE_CNT_WIDTH*11-1:0] pulse_cnt,然后使用位切片来索引pulse_cnt[PULSE_CNT_WIDTH*index +: PULSE_CNT_WIDTH]。位切片也可以与Verilog相媲美。见用+索引向量和数组:

票数 1
EN

Stack Overflow用户

发布于 2015-12-10 14:19:03

always放入generate语句中。您应该会在SO上找到许多示例:例如,这里。您仍然需要修改代码,这可能并不比为模块实例化修改它更容易。

您的代码目前已经崩溃,因为pulse_rst是在时钟边缘之前进行测试的,并且它不在敏感列表中。您应该把它放在列表中,或者重新编码块。请注意,Verilog中存在两个异步控件和一个时钟的问题;查找“具有异步设置和重置的verilog触发器”,或者使用不同的问题再次询问。

票数 0
EN

Stack Overflow用户

发布于 2015-12-11 05:47:30

我觉得你还可以用宏。将这些非公共变量转换为宏,例如将pulse_cnt转换为`pulse_cnt。将它们放入文件中,并将其作为包含文件使用。

例如你的代码,

代码语言:javascript
复制
always @(...) 
begin
  `pulse_cnt <= 0;
  // ...
end

将此模板放入一个名为my_always.v的文件中

然后在其他文件/模块中重用代码,如下所示:

代码语言:javascript
复制
`define pulse_cnt pulse_cnt0
`include "my_always.v"
`undef pulse_cnt

`define pulse_cnt pulse_cnt1
`include "my_always.v"
`undef pulse_cnt

//... and so on
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34201868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档