如何在Verilog中防止推断的闩锁和闩锁不安全行为?
我的程序的某个特定部分有问题,在“始终”块中:如何在Verilog中防止推断的闩锁和闩锁不安全行为?,verilog,system-verilog,quartus,Verilog,System Verilog,Quartus,我的程序的某个特定部分有问题,在“始终”块中: module compare_block (clk, reset_n, result, led); parameter data_width = 8; //width of data input including sign bit parameter size = 1024; input clk, reset_n; input [(data_width+2):0] result; //from filt
module compare_block (clk, reset_n, result, led);
parameter data_width = 8; //width of data input including sign bit
parameter size = 1024;
input clk, reset_n;
input [(data_width+2):0] result; //from filter -- DOUBLE CHECK WIDTH
logic [(data_width):0] data_from_rom; //precalculated 1 Hz sine wave
logic [10:0] addr_to_rom;
output reg led;
reg [(data_width + 2):0] ans_sig [size-1:0];
integer i, iii, jj, j, ii;
reg ans_sig_done, filt_sig_done, comp_sig_done;
reg [(data_width+2):0] sum;
reg [data_width:0] max_val, error_val;
initial max_val='b000000000;
...
always @* begin
sum = 0;
if (ans_sig_done) begin
for (j=4; j<(size-1); j=j+2) begin
sum = sum + ans_sig[j];
if (ans_sig[j] > max_val) begin
max_val = ans_sig[j];
end else begin
max_val = max_val;
end//else
end //for
end//if
end//always
...
endmodule
模块比较块(时钟、复位、结果、led);
参数数据_宽度=8//数据输入的宽度,包括符号位
参数大小=1024;
输入时钟,复位;
输入[(数据宽度+2):0]结果//从过滤器--双重检查宽度
逻辑[(数据宽度):0]来自rom的数据//预先计算的1Hz正弦波
逻辑[10:0]添加到rom;
输出reg led;
reg[(数据宽度+2):0]ans_sig[size-1:0];
整数i,iii,jj,j,ii;
注册信号完成、过滤信号完成、补偿信号完成;
reg[(数据宽度+2):0]和;
reg[数据宽度:0]最大值,错误值;
初始最大值为b000000000;
...
总是开始
总和=0;
如果(信号完成)开始
对于(j=4;j最大值)开始
max_val=ans_sig[j];
结束,否则开始
最大值=最大值;
完//else
完//
结束//如果
结束//始终
...
端模
本质上,ansu sig
是一个数组,长度为1024字节,我想将其和为一个数字(sum
),并最终(不在此)取其平均值。当我遍历ansu sig
数组时,我还想确定数组中的最大值(max\u val
),这就是嵌套if语句所做的。但是,当我在Quartus中编译时,会收到以下严重警告:
比较块sv处“最大值[8]”的推断闩锁
“13012闩锁比较_块:比较|最大值[8]具有不安全行为”
“锁存器上的13013个端口D和ENA由同一个信号比较块提供:比较| LessThan473~synth”(用于最大值[8])
我从max_val[0]到max_val[8]得到所有这些错误。如果此模块用于模拟目的,您可能不需要关心警告(我不太确定。如果我错了,请纠正我)。但是,如果是为了实现,则需要使用顺序逻辑生成
sum
和max\u val
,其中ans\u sig\u done
为启用信号。您有1024个11位长的数据,永远不要考虑在零时间消耗的情况下进行这样的计算。让我们谈谈你收到的警告。由于始终
块是组合的,因此当ans_sig_done
为false时,您希望看到什么。缺少分支的组合逻辑会导致锁存行为。顺便说一句,您有一个与ans_sig
数组中的每个数据具有相同位宽的和,这将导致计算过程中的潜在数据丢失,还有一个位宽更窄的最大值
。此代码表示空语句,实际上表示锁存,而不是消除锁存:
end else begin
max_val = max_val; <<< null statement
这样您就可以摆脱闩锁。这是否回答了您的问题?
always @* begin
sum = 0;
max_val = 0;
if (ans_sig_done) begin
for (j=4; j<(size-1); j=j+2) begin
sum = sum + ans_sig[j];
if (ans_sig[j] > max_val) begin
max_val = ans_sig[j];
end
end//else
end //for
end//if
end//always