如何防止在Verilog中推断出的闩锁和闩锁不安全行为?

问题描述

我在程序的特定部分遇到麻烦,在始终块中:

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]得到了所有这些错误。

解决方法

如果此模块用于仿真目的,则也许您不需要关心警告(我不太确定。如果我错了,请纠正我)。但是,如果用于实现,则需要使用顺序逻辑来生成summax_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

这样,您将摆脱闩锁。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...