问题描述
我正在尝试在Verilog中编写控制器/数据路径实现的代码,但对于会导致不必要的闩锁的原因我感到困惑.本质上,我在状态时钟上更新了状态机.该状态机根据机器所处的状态将5个控制信号(loadSquare,loadDelta,addDelta等)发送到数据路径.数据路径和控制器的代码如下所示.
I am trying to code a controller/data-path implementation in Verilog, and I am confused on what will cause an unwanted latch. Essentially, I have a state machine updating on the negedge clock. This state machine sends 5 control signals (loadSquare, loadDelta, addDelta, etc.) to the data-path based on what state the machine is in. The code for the data-path and controller is shown below.
数据路径
//Control lines
reg addSquare, addDelta, decDelta;
reg loadSquare, loadDelta;
//Input lines
reg [8:0] square, delta;
//Output register
reg [7:0] outReg;
always @(posedge clk) begin
if (loadSquare)
square = 9'h1; //used on initialization
if (loadDelta)
delta = 9'h3; //used on initialization
if (addSquare)
square = square + delta;
if (addDelta)
delta = delta + 2'h2;
if (decDelta)
outReg = (delta>>1) - 1; //used for output
else
outReg = Input;
end
控制器
//Output of module
assign Output = outReg;
//Finite State Machine
always @(currentState) begin
case(currentState)
2'h0: begin //initialize values, wait for start
{loadSquare, loadDelta} = 2'b11;
{addSquare, addDelta, decDelta} = 3'h0;
end
2'h1: begin
{loadSquare, loadDelta} = 2'b00;
{addSquare, addDelta, decDelta} = 3'b110; //add square and delta
end
2'h2: begin
{loadSquare, loadDelta} = 2'b00;
{addSquare, addDelta, decDelta} = 3'b001; //decrement delta, wait for reset
end
default: ; // unused
endcase
//Next state logic implemented on negedge clk (not shown)
此代码在Xilinx中生成以下警告:
This code generates the following warnings in Xilinx:
WARNING:Xst:737 - Found 1-bit latch for signal <addDelta>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 1-bit latch for signal <decDelta>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 1-bit latch for signal <loadDelta>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:1294 - Latch <loadDelta> is equivalent to a wire in block <ModuleName>.
WARNING:Xst:1294 - Latch <decDelta> is equivalent to a wire in block <ModuleName>.
WARNING:Xst:1294 - Latch <addDelta> is equivalent to a wire in block <ModuleName>.
我了解不完整的if语句会导致闩锁.为了解决这个问题,我尝试了2种不同的实现,但是它们没有删除警告.对于"decDelta"一案,我特别困惑,因为我不明白我在此条件声明中没有解释什么.
I understand that incomplete if statements cause latches. In order to try to account for this, I have tried 2 different implementations but they do not remove the warnings. I am especially confused for the "decDelta" case because I don't understand what I am not accounting for in this conditional statement.
尝试#1
always @(posedge clk) begin
if (loadSquare)
square = 9'h1;
else
square = square;
if (loadDelta)
delta = 9'h3;
else
delta = delta;
//... and so on
尝试#2
always @(posedge clk) begin
square = square;
delta = delta;
if (loadSquare)
square = 9'h1;
if (loadDelta)
delta = 9'h3;
//... and so on
运行模拟时,代码可以按预期工作,但是我想了解更多有关导致这些警告的原因.
The code works as expected when I run a simulation, but I wanted to learn a little more about what causes these warnings.
推荐答案
锁存器是基本的存储元素,它是打开或关闭的,即它是级别敏感的.触发器基本上是两个锁存器,一个锁存器在使能信号的反相信号上工作,这使其对边沿敏感.
A latch is a basic memory element, it is open or closed ie it is level sensitive. A flip-flop is basically two latches with one operating on the invert of the enable signal, this makes it edge sensitive.
使用always @(posedge clk)
时,您隐含了一个在clk
的上升沿加载数据值的触发器.闩锁不会隐含在此过程中(always @(posedge clk)
).
When using always @(posedge clk)
you have implied a flip-flop that loads data values on the rising edge of clk
. Latches do not get implied inside this process (always @(posedge clk)
).
如Sharvil111所述,当您在组合节(即always @*
进程)中留下未定义的状态时,就暗指了锁存器.如果某些东西在条件的一部分中未定义,那么它将保留其值.值保留是状态,并且由于组合部分对边缘不敏感,因此您已强制该工具插入闩锁.
As Sharvil111 has described latches are implied when you have left undefined states in combinatorial sections ie always @*
processes. If some thing is undefined in part of a conditional then it retains its value. Value retention is state, and since combinatorial sections are not edge sensitive you have forced the tool to insert a latch.
为避免这种情况,请完全定义条件输出:
To avoid this fully define the conditional output:
always @(currentState) begin
case(currentState)
2'h0: begin //initialize values, wait for start
{loadSquare, loadDelta} = 2'b11;
{addSquare, addDelta, decDelta} = 3'h0;
end
2'h1: begin
{loadSquare, loadDelta} = 2'b00;
{addSquare, addDelta, decDelta} = 3'b110; //add square and delta
end
2'h2: begin
{loadSquare, loadDelta} = 2'b00;
{addSquare, addDelta, decDelta} = 3'b001; //decrement delta, wait for reset
end
default: begin
{loadSquare, loadDelta} = 2'b00;
{addSquare, addDelta, decDelta} = 3'b000;
end
endcase
这篇关于为什么If语句在verilog中导致闩锁?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!