为什么这段代码会被推断出锁存器?
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
如果您注意到,缺少条件,其中 a 和 b 为 0,因此,这将推断出一个锁存器对于 reg c。这应该按照以下方式完成:
always @ (*) begin
if(a)
c = 10;
else if(b)
c = 12;
else
c = 0; //..just an example
end
这样,reg c的所有逻辑条件都定义好了。
我目前正在 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
如果您注意到,缺少条件,其中 a 和 b 为 0,因此,这将推断出一个锁存器对于 reg c。这应该按照以下方式完成:
always @ (*) begin
if(a)
c = 10;
else if(b)
c = 12;
else
c = 0; //..just an example
end
这样,reg c的所有逻辑条件都定义好了。