问题
When incompletely assigning a value I get a latch. But why did I get a latch in the example below? I think there is no need for the latch of F
output because it is defined at all values of SEL
.
Verilog code:
always @ (ENB or D or A or B pr SEL)
if (ENB)
begin
Q=D;
if (SEL)
F=A;
else
F=B;
end
Inferred logic:
回答1:
Although it is defined at all values of SEL
, it is not defined for all values of ENB
. If ENB = 0
, your code says that both Q
and F
should hold the value from the previous cycle. This is also what is inferred in the image you are linking: only update Q
and F
if ENB = 1
.
If you want Q
to be a latch and F
not, you can do this:
always @ (ENB or D or A or B or SEL)
begin
if (ENB)
Q=D;
if (SEL)
F=A;
else
F=B;
end
Edit: additional information
As pointed out in the comments, I only showed how you could realize combinational logic and a latch, without modifying your code too much. There are, however, some things which could be done better. So, a non-TL;DR version:
- Although it is possible to put combinational logic and latches in one procedural block, it is better to split them into two blocks. You are designing two different kinds of hardware, so it is also better to seperate them in Verilog.
Use nonblocking assignments instead of blocking assignments when modeling latches. Clifford E. Cummings wrote an excellent paper on the difference between blocking and nonblocking assignments and why it is important to know the difference. I am also going to use this paper as source here: Nonblocking Assignments in Verilog Synthesis, Coding Styles That Kill!
First, it is important to understand what a race condition in Verilog is (Cummings):
A Verilog race condition occurs when two or more statements that are scheduled to execute in the same simulation time-step, would give different results when the order of statement execution is changed, as permitted by the IEEE Verilog Standard.
Simply put:
always
blocks may be executed in an arbitrary order, which could cause race conditions and thus unexpected behaviour.To understand how to prevent this, it is important to understand the difference between blocking and nonblocking assignments. When you use a blocking assignment (
=
), the evaluation of the right-hand side (in your codeA
,B
, andD
) and assignment of the left-hand side (in your codeQ
andF
) is done without interruption from any other Verilog statement (i.e., "it happens immediately"). When using a nonblocking assignment (<=
), however, the left-hand side is only updated at the end of a timestep.As you can imagine, the latter assignment type helps to prevent race conditions, because you know for sure at what moment the left-hand side of your assignment will be updated.
After an analysis of the matter, Cummings concludes, i.a., the following:
Guideline #1: When modeling sequential logic, use nonblocking assignments.
Guideline #2: When modeling latches, use nonblocking assignments.
Guideline #3: When modeling combinational logic with an always block, use blocking assignments.
A last point which I want to highlight from the aforementioned paper is the "why". Except from the fact that you are sure the right hardware is infered, it also helps when correlating pre-synthesis simulations with the the behaviour of your actual hardware:
But why? In general, the answer is simulation related. Ignoring the above guidelines [about using blocking or nonblocking assignments on page 2 of the paper] can still infer the correct synthesized logic, but the pre-synthesis simulation might not match the behavior of the synthesized circuit.
This last point is not possible if you want to strictly adhere to Verilog2001, but if you are free to choose your Verilog version, try to use
always_comb
for combinational logic andalways_latch
for latches. Both keywords automatically infer the sensitivity list, and it is easier for tools to find out if you actually coded up the logic you intended to design.Quoting from the SystemVerilog LRM:
The
always_latch
construct is identical to thealways_comb
construct except that software tools should perform additional checks and warn if the behavior in an always_latch construct does not represent latched logic, whereas in an always_comb construct, tools should check and warn if the behavior does not represent combinational logic.
With these tips, your logic would look like this:
always_latch
begin
if (ENB)
Q <= D;
end
always_comb
begin
if (SEL)
F = A;
else
F = B;
end
来源:https://stackoverflow.com/questions/57650276/incomplete-assignment-and-latches