警告:推断变量 'w_addra_t' 的闩锁(在 Verilog/SystemVerilog 中使用 FOR 循环)
Warning: Inferring latch for variable 'w_addra_t' (in Verilog/SystemVerilog with FOR loop)
当我设计一个简单的双端口 RAM 块时,我在综合后推断出锁存器问题。由于代码量较大,我刚刚嵌入了这个 always 块代码如下:
integer i;
always_latch
begin
for (i=0;i<NUM_RAMS;i=i+1) begin
if (ena_t == 1) begin
w_addra_t[i] = w_addra[i];
end
else begin
w_addra_t[bank_addra[i]] = w_addra[i];
end
end
end
我的 RAM 块包括 NUM_RAMS 个库。各个输入数据的地址存储在w_addra.
具有给定w_addra地址的数据被加扰到w_addra_t取决于各自bank_addra(取决于访问模式)当 ena_t = 0.
我尝试用 if...else、switch...case[= 替换 for 循环40=], generate 但问题是一样的。在我的代码中使用不同的 always 块,左侧只有 w_addra_t[i] 在两个 if.else of ena_t,没有错误.
如果您有任何想法,我想听取您的建议。我确实寻找过类似的问题,但没有得到任何结果。
非常感谢:)
我猜 bank_addra
的条目不能保证是唯一的。如果两个或多个条目具有相同的值,则会为 w_addra_t
创建一个索引空洞;这将推断出一个闩锁。
以下是三种可能的解决方案:
在功能上保证 bank_addra
条目将具有唯一值,然后合成器不应推断出锁存器。这可能具有挑战性。
将地址变化从左轴移到右轴,这样w_addra_t
的每个索引都保证被赋值。例如将 w_addra_t[bank_addra[i]] = w_addra[i];
更改为 w_addra_t[i] = w_addra[bank_addra_lookup[i]];
.
在其他逻辑之前将w_addra_t
的所有条目分配给一个已知值(常量、触发器或确定性值)。您可以将此默认赋值放在 always 块的顶部(选项 1 示例)或将要推断锁存器的逻辑上方(选项 2 示例)。这是最简单的解决方案,假设它仍然满足与您的其他代码的关系要求。
// NOTE: SystemVerilog supports full array assignments (Verilog requires a for-loop)
always_comb
begin
w_addra_t = '{default:'0}; // <-- default assignment : option 1
if (ena_t == 1) begin
w_addra_t = w_addra;
end
else begin
w_addra_t = w_addra_t_ff; // <-- default assignment : option 2
for (i=0;i<NUM_RAMS;i=i+1) begin
w_addra_t[bank_addra[i]] = w_addra[i];
end
end
end
always_ff @(posedge clk) begin
w_addra_t_ff <= w_addra_t; // assuming w_addra_t should hold it current values
end
TL;DR
always_latch
是一个 SystemVerilog 关键字,用于标识显式锁存器。某些工具会在使用关键字时自动放弃警告,但如果使用关键字且未检测到闩锁,则会抛出 error/warning。
如果您知道它应该是组合逻辑,那么请使用 always_comb
SystemVerilog 关键字。使用 always_comb
,如果综合检测到锁存器,则它应该报告错误。
阅读相关问题:
What is inferred latch and how it is created when it is missing else statement in if condition. Can anybody explain briefly?
不知道改成
能不能解决你的问题
int i
always_comb
相反。当您使用像整数这样的 4 态变量时,该工具可能会变得很糟糕?
当我设计一个简单的双端口 RAM 块时,我在综合后推断出锁存器问题。由于代码量较大,我刚刚嵌入了这个 always 块代码如下:
integer i;
always_latch
begin
for (i=0;i<NUM_RAMS;i=i+1) begin
if (ena_t == 1) begin
w_addra_t[i] = w_addra[i];
end
else begin
w_addra_t[bank_addra[i]] = w_addra[i];
end
end
end
我的 RAM 块包括 NUM_RAMS 个库。各个输入数据的地址存储在w_addra.
具有给定w_addra地址的数据被加扰到w_addra_t取决于各自bank_addra(取决于访问模式)当 ena_t = 0.
我尝试用 if...else、switch...case[= 替换 for 循环40=], generate 但问题是一样的。在我的代码中使用不同的 always 块,左侧只有 w_addra_t[i] 在两个 if.else of ena_t,没有错误.
如果您有任何想法,我想听取您的建议。我确实寻找过类似的问题,但没有得到任何结果。
非常感谢:)
我猜 bank_addra
的条目不能保证是唯一的。如果两个或多个条目具有相同的值,则会为 w_addra_t
创建一个索引空洞;这将推断出一个闩锁。
以下是三种可能的解决方案:
在功能上保证
bank_addra
条目将具有唯一值,然后合成器不应推断出锁存器。这可能具有挑战性。将地址变化从左轴移到右轴,这样
w_addra_t
的每个索引都保证被赋值。例如将w_addra_t[bank_addra[i]] = w_addra[i];
更改为w_addra_t[i] = w_addra[bank_addra_lookup[i]];
.在其他逻辑之前将
w_addra_t
的所有条目分配给一个已知值(常量、触发器或确定性值)。您可以将此默认赋值放在 always 块的顶部(选项 1 示例)或将要推断锁存器的逻辑上方(选项 2 示例)。这是最简单的解决方案,假设它仍然满足与您的其他代码的关系要求。// NOTE: SystemVerilog supports full array assignments (Verilog requires a for-loop) always_comb begin w_addra_t = '{default:'0}; // <-- default assignment : option 1 if (ena_t == 1) begin w_addra_t = w_addra; end else begin w_addra_t = w_addra_t_ff; // <-- default assignment : option 2 for (i=0;i<NUM_RAMS;i=i+1) begin w_addra_t[bank_addra[i]] = w_addra[i]; end end end always_ff @(posedge clk) begin w_addra_t_ff <= w_addra_t; // assuming w_addra_t should hold it current values end
TL;DR
always_latch
是一个 SystemVerilog 关键字,用于标识显式锁存器。某些工具会在使用关键字时自动放弃警告,但如果使用关键字且未检测到闩锁,则会抛出 error/warning。
如果您知道它应该是组合逻辑,那么请使用 always_comb
SystemVerilog 关键字。使用 always_comb
,如果综合检测到锁存器,则它应该报告错误。
阅读相关问题: What is inferred latch and how it is created when it is missing else statement in if condition. Can anybody explain briefly?
不知道改成
能不能解决你的问题int i
always_comb
相反。当您使用像整数这样的 4 态变量时,该工具可能会变得很糟糕?