下面是始终块的代码。
我需要有相同的代码11次,具有相同的功能,但对不同的变量。那么,我如何重用代码呢?
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命名模式-
tconClk,tconRst_n很常见,pulse_cnt0,pulse_cnt1 upto 10,pulse_width0,pulse_width1 upto 10,pulse_start[0:10] (阵列)start_written[0:10] (阵列)pulse_rst[0:10] (阵列)start_signal[0:10] (阵列)START_PW (没有模式,每个11块都有不同的名称)注-
发布于 2015-12-11 19:19:16
您可以使用emacs脚本verilog模式,使用模块中的RTL并利用AUTO_TEMPLATE。然后在(或批)emacs中执行类似于以下(未测试)的verilog-batch-auto:
/* 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作为一个宏放置,但我强烈建议将其放在模块中,并让宏实例化宏。某物湖(未测试):
`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-循环将无法工作。宏在生成块之前进行评估。
`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相媲美。见?和用+索引向量和数组:
发布于 2015-12-10 14:19:03
将always放入generate语句中。您应该会在SO上找到许多示例:例如,这里。您仍然需要修改代码,这可能并不比为模块实例化修改它更容易。
您的代码目前已经崩溃,因为pulse_rst是在时钟边缘之前进行测试的,并且它不在敏感列表中。您应该把它放在列表中,或者重新编码块。请注意,Verilog中存在两个异步控件和一个时钟的问题;查找“具有异步设置和重置的verilog触发器”,或者使用不同的问题再次询问。
发布于 2015-12-11 05:47:30
我觉得你还可以用宏。将这些非公共变量转换为宏,例如将pulse_cnt转换为`pulse_cnt。将它们放入文件中,并将其作为包含文件使用。
例如你的代码,
always @(...)
begin
`pulse_cnt <= 0;
// ...
end将此模板放入一个名为my_always.v的文件中
然后在其他文件/模块中重用代码,如下所示:
`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 onhttps://stackoverflow.com/questions/34201868
复制相似问题