以下是始终阻止代码。
我需要使用相同的代码11次,具有相同的功能但是在不同的变量上。那么我该如何重用代码?
call setx -m ORACLE_HOME "C:\Servers\oc4j_extended_101350"
call C:\Servers\oc4j_extended_101350\bin\oc4j -start
call REG delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /F /V ORACLE_HOME
命名模式 -
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
,10
,pulse_width0
至pulse_width1
,10
(数组),pulse_start[0:10]
(数组),start_written[0:10]
(数组),pulse_rst[0:10]
(数组),start_signal[0:10]
(没有模式,每个11个总块的名称不同)注意 -
定义宏不起作用,因为此代码包含许多verilog标记。
我无法生成代码模块,因为always块中使用的信号也用于代码的其他部分。因此,如果我制作模块,那么我将无法确保正确的寄存器或电线连接到模块。 (就像模块输出端口必须是导线一样,但是相同的信号已被用作代码其他部分的reg)
答案 0 :(得分:1)
您可以使用emacs脚本verilog-mode来封装模块中的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 / ruby_it,Python的prepro等),可以生成所需的代码。< / p>
SystemVerilog增强了宏的功能。对您而言,``
功能将使您的工作更轻松。见IEEE Std 1800-2012§22.5.1`define。
多行宏很难调试。虽然可以将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]
。通过此转换,您可以使用生成循环。
或者,您可以将pulse_cnt
折叠为大型总线reg [PULSE_CNT_WIDTH*11-1:0] pulse_cnt
,然后使用位切片进行索引pulse_cnt[PULSE_CNT_WIDTH*index +: PULSE_CNT_WIDTH]
。位切片也与Verilog兼容。请参阅What is `+:` and `-:`?和Indexing vectors and arrays with +:
答案 1 :(得分:0)
将always
放在generate
语句中。你应该在SO上找到很多例子:here。您仍然需要修改代码,这可能比修改模块实例化更容易。
您的代码此刻已被破坏,因为pulse_rst
在时钟边缘之前进行了测试,并且它不在敏感度列表中。您应该将其放在列表中,或重新编码块。请注意,Verilog中存在两个异步控件和一个时钟的问题;通过异步设置查看&#34; verilog flops并重置&#34;,或者再问一个不同的问题。
答案 2 :(得分:0)
我认为你仍然可以使用宏。将这些非公共变量更改为宏,例如将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 on