If statements causing latch inference in Verilog? - verilog

I am writing a Verilog code for synthesis of an algorithm, I am a little confused on what cases might cause latches to be inferred. Below is one such section of the code, though it works fine in simulation, I am worried it might cause problems on hardware.
always#(b1 or b2)
.....
// b1_map,b2_map,m1_map & m2_map are derived from combinational functions using b1 & b2
.....
if(b1_map<=20 && m2_map<=20 && b1_map>=0 && m2_map>=0)
begin
accumulator1[b1_map][m2_map]= accumulator1[b1_map][m2_map] + 1;
end
if(b2_map<=20 && m2_map<=20 && b2_map>=0 && m2_map>=0)
begin
accumulator2[b2_map][m2_map]= accumulator2[b2_map][m2_map] + 1;
end
//accumulator1 & accumulator2 are 2d registers mapped like 2d arrays
So, In this case I want the data to be mapped only if it is in the specified limits. Will a latch be inferred because there is no "else" scenario defined? I didn't add an else statement because there is nothing I want to do with that data if it's not in the limits.

If you write your if statements correctly, you will be fine. Latches are generated when there are paths through the if statement that do not update one or more of the outputs. Code like the following will generate a latch:
always #* begin
if (a) begin
b <= c & d;
e <= f;
end else begin
b <= c | d;
end
end
Notice that e is assigned only when a is true? This requires a latch to implement correctly.
Another posibility that will generate a latch is when the sensitivity list does not contain a signal used in the code.
always #(a) begin
if (a) begin
b <= c & d;
end else begin
b <= c | d;
end
end
This code will generate latches on c and d or on b because it will only allow b to be updated when a changes.

You've misunderstood your problem (and you shouldn't have accepted an answer)
- the issue isn't fundamentally related to 'latches'. Your code doesn't make
sense (for synthesis). Quartus knows this, and it's basically telling you to
rewrite your code.
You've got a combinatorial block that increments a number (immediately) when a
signal changes. Two problems: (1) this is certainly not what you want in real
hardware, and (2) the number must remain the same, and not increment, when b1
and b2 don't change. The second isue is the one Quartus is reporting - your
circuit needs memory of some sort, which it's reporting as a 'latch'. It's not
smart enough to report the first problem, which is the real issue.
Try to draw your circuit as a schematic with real hardware. What does 'any
change on b1 or b2' actually mean? How are you going to maintain the value of
the accumulators when b1 and b2 don't change? The circuit isn't impossible,
but it's way beyond an SO question.
Make you circuit synchronous, triggering on a clock edge, with only a clock
(and possibly a reset) in the sensitivity list, and keep the innards exactly
the same. There's nothing wrong with your if statement, since you actually
want the accumulator to remain unchanged if nothing interesting is happening
on b1/b2.

Inferred latches can come from an incomplete sensitivity list or incomplete assignments.
Sensitivity lists for combinatorial blocks should generally be written with always #*. This avoid coding bugs when updating code. Combinatorial blocks (those not including an edge sensitivity) are once synthesised will perform in the manner of always #*. Specifically naming signals adds more work and will likely lead to RTL to gate level (post synthesis) errors.
Incomplete assignments which imply the value has to be held will infer a latch. Latches are not inherently bad but require careful consideration. Inferred one in this manner removes the thought fullness and control you would otherwise have over it. This can lead to complex timing issues. As the latch is level sensitive rather than edge sensitive. Ideally you want the latch to be open for the first have of the clock cycle so that it is closed when the data will be read from it. Inferred latches remove this control.
Completing if statements with an else, of default for case castanets which sets a sensible value (0's) can help avoid these accidental latches.

Related

Incomplete assignment and latches

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:
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 code A, B, and D) and assignment of the left-hand side (in your code Q and F) 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_combfor combinational logic and always_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 the always_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

verilog coding style for synthesizable code

I coded something like the following:
always #(state or i1 or i2 or i3 or i4) begin
next = 5'bx;
err = 0; n_o1 = 1;
o2 = 0; o3 = 0; o4 = 0;
case (state) // synopsys full_case parallel_case
IDLE: begin
if (!i1) next = IDLE;
else if ( i2) next = S1;
else if ( i3) next = S2;
else next = ERROR;
end
S1: begin
if (!i2) next = S1;
else if ( i3) next = S2;
else if ( i4) next = S3;
else next = ERROR;**strong text**
...
My manager, of course I don't want to argue with him before I have some strong argument, but he reviewed my code and said writing
next = 5'bx;
err = 0; n_o1 = 1;
o2 = 0; o3 = 0; o4 = 0;
in a combinational logic without putting the right side in the sensitivity list will cause problems in synthesis.By not having these 3 lines, I need to explicitly write the else part inside each individual case, and he said yes.
I am wondering is there anything wrong with this coding style? And will it cause a synthesis problem or any sort of problem(maybe some version or old synthesis tool won't synthesize?) by initializing these values in the combinational logic? What he said does make sense to me and I actually never thought about it because he said this is software logic, and every wire gets its initial value from the logic before it with the initial condition. I told him school taught us this, he was like school cares less any synthesis but industry does.
Thank you for your help! Guess I am not trying to convince him anything even I have a answer, since the team need to stick with one style anyways, but i am confused by him since I have seen others doing this all the time and he is also a guy with tons of experience, so...confused
First of all, you should be using always #(*) from Verilog-2001 or even better always_comb from SystemVerilog so the sensitivity list get constructed automatically for you.
The problem with your code is the use of the full case synthesis pragma as described in this paper. Your coding style removes the need for full case as long as you are sure you made assignments to every variable in the always block for all possible flows through the block.
I think what your boss means by "software logic" is that your coding style requires the designer to think sequentially. In other words, when I read your always block, I am first forced to think about all the values being initialized to their default values, then I must evaluate the case logic. In reality, the logic will synthesize into the equivalent of a default case. This causes a disparity between the logic that represents the RTL and the logic of how I evaluate your expression in my mind. If you know what your doing, then this should be fine most of the time. But you are working for a company, so your code should be considerate of the other engineers working on a project. Each different team in the design flow is going to view the same logic through a potentially different lens (for example, the physical design team is not concerned with Verilog but the synthesized RTL). If we write our Verilog to reflect the final RTL (i.e. "hardware logic"), then everyone is analyzing the logic in a similar fashion. If I look at an output in a circuit and I know all the values of the inputs at a given time step, then I can visually trace the output through the circuit and determine its value without giving any consideration to the other logic. Your Verilog code should be written in the same way.
To summarize, your initialization statements are nothing more than another case in the selection mux in the RTL. So, you should write it that way. Use a default case and explicitly assign every output of the block in each case. This is generally considered best practice. It may not be the most clever or elegant way to write Verilog, but it is the most readable and results in far fewer errors (and in industry, people are more concerned with design verification to reduce costs than the cleverness of Verilog).
Also, as #dave_59 brought up, if you use the full_case Synopsis directive, then it will create default output drivers for you where the outputs are set to "don't cares." This is not a result that anyone wants, and it would be flagged by the verification team. To fix it, you would need to make sure every output is being assigned by adding them to all the cases like your boss mentioned. If you are forced to do this anyways, then full_case is redundant because you have explicitly made the case statement full. As for older synthesis tools, I don't see that being as big of an issue for this particular subject, but it is a consideration that is always given in industry. What would be more of an issue is if your company has configured downstream tools to force older constructs in an effort to reduce verification costs.
Trust your manager's experience on this issue. Coding style in industry is largely affected by collaboration with other engineers, costs, and legacy than by technical details. This is where your manager's experience will be valuable.

Will latches occur in sequential logic in verilog

This is a basic question but it seems to lack of clear explanation to me.
In many of code examples,one style to write FSM output is
assign a = (current_state==DONE)?1:0;
I confuse this with definition of latches. Will this combinational logic infer latches as "a" holds its previous value if current_state != DONE? It seems no warnings from my compiler.
sometimes, i would have
always#(posedge clk)
begin
if(reset)
a<= 1'b0;
else
if(current_state == DONE)
a <=1'b1;
end
This is certainly a sequential logic(tho my output does not depend on my chains of past input) and a would keep its previous value until my control signal current_state == DONE.I would guess this logic will synthesize to a mux to the input of a flipflop.
so if in the 2nd case that I actually have a clocked FSM, i would have my mux with FSM states output as the select signal input.
Until now, can i say anything that is not combinational logic will not generate any latches?
However,when i have a structure like the following,
always#(posedge DCO or posedge reset or posedge enable)
begin
if(reset)
begin
end
else if(enable)
begin
end
else
begin
end
end
I get a warning in my FPGA that i have inferred a latch with control signal enable.
Why?
My enable changes based on another state machine for example,
assign enable = (pcurrent_state == START)?1:0;
Moreover, we have unintentional latches and intentional latches. but design rule basically says to avoid latches to avoid timing arches. Can someone give some examples of where intentional latches should be used in design rather than clock gating example?
Plus,
The output of all the storage elements (flip-flops) in the circuit at any given time, the binary data they contain, is called the state of the circuit. The state of a synchronous circuit only changes on clock pulses. At each cycle, the next state is determined by the current state and the value of the input signals when the clock pulse occurs.(from https://en.wikipedia.org/wiki/Sequential_logic)
This sounds like describing a mealy machine to me rather than a typical sequential logic. My simplest sequential logic does not need my output change determined by my current_state
Thank you for any help. I am doing this coding everyday and reading its definition but it seems that i am confusing myself without discuss with others.
To answer your question in parts:
The given assign statement will not infer a latch as a does not retain it's value. It will be 1 if current_state == DONE and otherwise be 0. So it's pure combinational logic.
The second block of code implements a flip-flop with synchronous reset and only loads itself with 1'b1 if current_state == DONE so there is retention in that code. This code shouldn't generate a latch due to the edge sensitivity on a single clock.
The last block would be difficult for any synthesis tool to handle due to the sensitivity on serveral signals, which is not common in hardware. Moreover, if say enable is asserted but not an edge when a positive edge of DC0 comes along, the code would have the body of the else if (enable) run, thus simulating some sort of latching behavior. Synthesis tools generally allow for a single clock and single reset to be specified in the sensitivity list of an always block to indicate a flip-flop with asynchronous reset. While Verilog certainly allows for more complicated sensitivity lists, their physical meaning gets complicated quickly, thus inferring latches. In most designs, you shouldnt ever need these complex sensitivity lists are you are then getting into asynchronous design for which most synthesis tools are not well suited on a behavioral level. FPGA tools especially are poor at asynchronous elements and even latches as the logic cells in the fpga to which the design must be mapped are designed specifically for synchronous designs using flip-flops; that's how fpgas are implemented.
Finally, in non-fpga designs, it is sometimes desirable to use latches if edge sensitivity isn't required, as latches are physically smaller and can allow a design to be smaller, faster and more power efficient in some cases. However, you need to have a firm grasp on what you are designing and understand potential trade offs and timing requirements when doing so. Here's an example of when a latch is a useful element: https://electronics.stackexchange.com/questions/255009/what-is-application-of-latch-in-vlsi-design

Verilog always block

I just want to use some if else statement in verilog.
So I have to use always block.
integer count,index;
reg a=0;
always#(a) begin
a=1;
for(count=0;count<7;count=count+1) begin
index=4*count;
if((significand[index]==1'b0)&&(significand[index+1]==1'b0)&&
(significand[ind‌​ex+2]==1'b0) &&(significand[index+3]==1'b0))
lzero=lzero+1;
end
end
This code does make some sense now. I was able to get the correct simulation result, but I failed to get the correct synthesis on the board. Please help
This is a very typical problem with people who know how to program in C or C++ but forget that Verilog and VHDL are not the same as those.
EVERY signal line of Verilog code inside the ALWAYS block are 'executed' at the same time. The same goes with the combinatorial logic outside of the ALWAYS block.
In your code, both the
assign a=1'b1;
assign a=1'b0;
Will happen at the same time, no matter what.
The only way to change that is to put the last line inside your always block,after the end statement of the for loop.
One page that will give you some help on understanding the difference between C and Verilog is the page:EE-Times: The C Programmers Guide to Verilog
Neither assign 1'b1; nor assign 1'b0; are valid assignments. If you want to constantly drive some net with 1'b1, then you have to write something like assign myvar = 1'b1;.
Also, if your intent was to actually assign to a, then always block doesn't make sense since a is the only thing in its sensitivity list meaning that that block must be executed whenever a changes its value. Since a will essentially never change its value, that block should never be executed.
It is hard to help you out unless you provide a minimal working example demonstrating your problem. The only thing that I can recommend is to use ternary operator in assign right hand side statement. That way you can model a behavioural logic without using always block. For example:
assign a = (b == 1'b1 ? c : 1'b0);
Hope it helps.
UPDATE:
Your second code example is neither complete nor legal as well. You cannot have two combinatorial assignments for the same net.
However, a sensitivity list in always block is now a star, which is Verilog 2001 notation to include all right hand side operands into a sensitivity list automatically. In your case, the block will get executed every time significand or lzero changes.

What's included in a verilog always #* sensitivity list?

I'm a bit confused about what is considered an input when you use the wildcard #* in an always block sensitivity list. For instance, in the following example which signals are interpreted as inputs that cause the always block to be reevaluated? From what I understand clk and reset aren't included because they dont appear on the right hand side of any procedural statement in the always block. a and b are included because they both appear on the right hand side of procedural statements in the always block. But where I'm really confused about is en and mux. Because they are used as test conditions in the if and case statements are they considered inputs? Is the always block reevaluated each time en and mux change value? I'm pretty much a noob, and in the 3 Verilog books I have I haven't found a satisfactory explanation. I've always found the explanations here to be really helpful. Thanks
module example
(
input wire clk, reset, en, a, b,
input wire [1:0] mux,
output reg x,y, z
);
always #*
begin
x = a & b;
if (en)
y= a | b;
case(mux)
2'b00: z = 0;
2'b01: z = 1;
2'b10: z = 1;
2'b11: z = 0;
endcase
end
endmodule
Any signal that is read inside a block, and so may cause the result of a block to change if it's value changes, will be included by #*. Any change on a read signal used must cause the block to be re-evaluated, as it could cause the outputs of the block to change. As I'm sure you know, if you hadn't used #* you'd be listing those signals out by hand.
In the case of the code you've provided it's any signal that is:
Evaluated on the right hand side of an assignment (a and b)
Evaluated as part of a conditional (en and mux)
...but it's any signal that would be evaluated for any reason. (I can't think of any other reasons right now, but maybe someone else can)
clk and reset aren't on the sensitivity list because they aren't used. Simple as that. There's nothing special about them; they're signals like any other.
In your example, the following signals are included in the implicit sensitivity list:
a
b
en
mux
clk and reset are not part of the sensitivity list.
This is described completely in the IEEE Std for Verilog (1800-2009, for example). The IEEE spec is the best source of detailed information on Verilog. The documentation for your simulator may also describe how #* works.
The simplest answer depends on if you are writing RTL, or a testbench. If you are writing RTL then you should try to forget about the concept of Sensitivity lists, as they don't really exist. There is no logic that only updates when an item on the list is triggered. All sensitivity lists can do in RTL is cause your simulation and actual circuit to differ, they don't do anything good.
So, always use "always #*" or better yet "always_comb" and forget about the concept of sensitivity lists. If the item in the code is evaluated it will trigger the process. Simple as that. It an item is in an if/else, a case, assigned to a variable, or anything else, it will be "evaluated" and thus cause the process to be triggered.
But, just remember, in digital circuits, there is no sensitivity list.

Resources