Reputation: 1101
If I understand latch correctly, it is created in combinational block in which not all possible conditions are declared when assigning a variable to a value. How am I getting a latch in my sequential block?
When I compiled my code via Quartus, it retured 2 Fmax, which indicates I have a latch.
always@(posedge clk or negedge nreset) begin
case(counter)
0: begin
if(state == IDLE) begin
// DOES SOMETHING
end
end
1: begin
// DOES ASSIGNMENT
end // PROLOG
81: begin
// DOES ASSIGNMENT
end // EPILOG
82: begin
// DOES ASSIGNMENT
end // POSTPROC
default: begin
// DOES ASSIGNMENT
end // ROUNDS
endcase
I have checked each of the cases, and made sure all assignments are non-blocking. Any idea why I might be latching?
My code is computing SHA1
I have 2 always@(posedge clk), one computes the next Wt, and the above computes the next A,B,C,D,E value.
Upvotes: 0
Views: 1601
Reputation: 469
More information needed for a short, specific answer: What reg
type variables are you setting / writing to in that always block?
Any circumstances where you fail to ensure there is at least one assignment for each such variable, will infer a latch for that variable, because you have a circumstance where it would have to just stay unchanged.
If you want it to stay unchanged but be a proper clock-driven register and not be a latch, you can just have something like
myreg <= myreg;
Which can be at the top of the always block, because any subsequent non-blocking assignments within the same always block will safely override it.
There will be no glitchs from having more than one <=
assignment to the same variable within the block, because while it is interpreted as sequential code, it's actual 'run time'/'as implemented' behaviour is instantaneous if combinational, or clock delayed if sequential, but either way dependent only on the last effective <=
assignment. If there was no <=
statement in some circumstance for a particular variable... well, that's how we get inferred latches.
Therefore all possible cases are covered in all possible circumstances, trivially.
You can even have just a one-liner like:
{reg1, reg2, reg3} <= {reg1, reg2, reg3};
Where the {,}
list (identical on both sides!) has all the registers you intend to control in this always block, at the top of the always block (before your if statements or case statement) to categorically prevent any latch-inference of the mentioned variables.
This works because it ensures that in all possible circumstances, every reg type has a explicit value. It is this complete coverage which disables latch inference.
Otherwise you have to set all regs once in every case, either to the new value they will have, or to 'themselves' to express that they should not change.
If you have signals which are one-hot or flag outputs intended to be high in one state case only, it is better to just pre-set them to default to zero (rather than 'themselves' as above), and then set them to 1'b1
only in the specific cases before they are supposed to be high (if synchonous block), and this will work also. (It's more usual to have a combinational block always @*
that does that but for cases where they are high, because it is easier to read - they will be high on the same state they are mentioned in, done that way. Setting them with <=
in a posedge block really sets what they will be when the next clk posedge arrives: So it's generally better to make this explicit by setting outputs and a 'next_state' reg in an combinational case block, then just have a single posedge block that just sets state <= next_state;
).
The other thing that can get you an inferred latch, is having a combinational block with a input variable missing from the sensitivity list. Avoid that by preferring always @*
to make it always include all in-scope variables in the sensitivity list.
PS. There are two types of synthesizable variable: wire
and reg
. In verilog, reg
just indicates it will be set in some kind of combinational block (initial
or always
), and wire is outside of those, either by connection, by a expression when defined, or with a single later assign wirevar = expr;
line.
A reg
variable is only a register if it is assigned in a synchronous block AND it doesn't get inferred to be a latch.
Upvotes: -1
Reputation: 26
There is no else
on your if
statement.The synthesizer is confused as to what needs to happen next, thus inferring latches.
If that is not intended but instead simply what you wrote for the stack overflow example then the problem may be in your other always block.
A latch is simply a Flip Flop without a clock. The reason synthesizers think they are bad is because they can potentially cause timing errors. Latches are not always a problem either, in fact sometimes as you probably already know, they are intentional.
Check your assign
statements, and see if you have any regs declared outside of an always
block which is initialized to 0 or some value.
In that case you might like to try the initial block. Syntax:
initial
begin
value = 0;
input = 0; // or something
end
Upvotes: 1