为什么这段代码会被推断出锁存器?

Why is this code getting inferred latches?

我目前正在 Vivado 中编写一些 Verilog 代码,尽管我指定了每条可能的路径,但我还是在综合阶段收到了 "inferring latch for variable" 消息。

`timescale 1ns / 1ps //My implementation

module my_pe #(parameter L_RAM_SIZE = 4)
(
    //  clk //reset
    input aclk,
    input aresetn,
    // port A
    input [31:0] ain,
    // peram --> port B
    input [31:0] din,
    input [8-1:0] addr,
    input we,
    // integrated valid signal
    input valid,
    // computation result
    output dvalid,
    output [31:0] dout
);

(*ram_style = "block" *) reg [31:0] peram [0:2**L_RAM_SIZE-1]; // local register 
reg [32-1:0] bin;
reg [31:0] psum;
wire [31:0] result;

always @(we, din, addr) begin
    if (we==1) begin
        peram[addr] = din;
    end
    else begin
        bin = peram[addr];
    end
end

always @(aresetn, dvalid, result) begin
    if (!aresetn) begin
        psum = 0;
    end
    else
        if (dvalid ==1)
            psum = result;
        else
            psum = psum;
end 

警告出现在两个 always 块中。以下是 100 条 "inferring latch" 警告消息中的一些:

[Synth 8-327] inferring latch for variable 'peram_reg[15]'
[Synth 8-327] inferring latch for variable 'psum_reg'
[Synth 8-327] inferring latch for variable 'bin_reg'

对于 bin 信号,只要这 3 个信号发生任何变化,就会触发 always 块:

we, din, addr

bin 仅在 we 为 0 时才被赋值。当 we 为 1 时,bin 保持其状态。这推断出一个闩锁。

你的模块有一个时钟输入(aclk),但你没有显示它正在被使用。如果你想推断触发器,你应该使用类似的东西:

always @(posedge clk)

为了不推断闩锁,reg 变量(如果没有计时)的所有不同状态都应该明确定义,如果缺少逻辑状态,编译器会理解实际值已被锁存并保存,直到遇到下一个条件。例如:

input a, b;
reg c;

always @ (*) begin
  if(a)
    c = 10;
  else if(b)
    c = 12;
end

如果您注意到,缺少条件,其中 ab 为 0,因此,这将推断出一个锁存器对于 reg c。这应该按照以下方式完成:

always @ (*) begin
  if(a)
    c = 10;
  else if(b)
    c = 12;
  else
    c = 0; //..just an example
end

这样,reg c的所有逻辑条件都定义好了。