问题描述
我在程序的特定部分遇到麻烦,在始终块中:
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
本质上,ans_sig
是一个数组,长1024个字节,我想将其求和为一个数字(sum
),最后(不在此处)取其平均值。在遍历ans_sig
数组时,我还想确定数组(max_val
)中的最大值,这就是嵌套的if语句的作用。但是,当我在Quartus中编译时,会收到以下严重警告:
“在compare_block.sv处推断为“ max_val [8]”的锁存器”
“ 13012闩锁compare_block:compare | max_val [8]具有不安全的行为”
“锁存器上的13013端口D和ENA由相同的信号compare_block馈送:compare | LessThan473〜synth”(对于max_val [8])
我从max_val [0]到max_val [8]得到了所有这些错误。
解决方法
如果此模块用于仿真目的,则也许您不需要关心警告(我不太确定。如果我错了,请纠正我)。但是,如果用于实现,则需要使用顺序逻辑来生成sum
和max_val
,其中ans_sig_done
是使能信号。您有1024个11位长的数据,永远不要考虑以零时间消耗进行这种计算。让我们谈谈收到的警告。由于always
块是组合的,因此当ans_sig_done
为false时会发生什么。分支丢失的组合逻辑导致闩锁行为。顺便说一下,您有一个sum
,其位宽与ans_sig
数组中的每个数据相同,这会导致在计算过程中潜在的数据丢失;而一个max_val
的位宽更窄
此代码表示一个空语句,实际上表示一个锁存器,而不是消除它:
end else begin
max_val = max_val; <<< null statement
除非您要表明它具有闩锁行为,否则使用这样的语句没有多大意义。
您仅在初始块中初始化max_val
一次。闩锁行为是一种预期的行为:在max_val
for 循环的多次调用之间保留sum
。
如果不是这种情况,那么您每次都需要重新计算max_val时,应该始终使用与sum
相同的方式对其进行初始化。
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
这样,您将摆脱闩锁。