为什么此代码被推断为锁存器?



我目前正在 Vivado 中处理一些 Verilog 代码,即使我指定了所有可能的路径,不知何故,我在合成阶段收到了"推断变量锁存器"消息。

`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 条"推断锁存"警告消息中的一些:

[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'

为了不推断锁存器,应该很好地定义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的所有逻辑条件都得到了很好的定义。

对于bin信号,每当以下 3 个信号发生任何变化时,都会触发always块:

we, din, addr

仅当we为 0 时,才为bin分配一个值。 当we为 1 时,bin保留其状态。 这推断出闩锁。

您的模块具有时钟输入 (aclk(,但您没有显示它正在使用。 如果你想推断人字拖,你应该使用类似的东西:

always @(posedge clk)

最新更新