I am looking into the difference between a regular SR latch and a level sensitive SR Latch.
Level - sensitive SR Latch
I am aware that what we want to avoid in an SR latch is the configuration (1,1) because it can cause an oscillation and when it finally settles on a 0 or 1 we can't be certain which one due to the oscillation. Thus, we use a level sensitive SR latch. But can someone elaborate on the behavior of this level-sensitive SR latch. Because if S,R, and C(usually a clock) are all 1, it seems to me that we can still end up with the same (1,1) configuration that we are trying to avoid.
I have found this post and it talks about the difference between a latch and a flip-flop. But just to re-iterate, my main question is if clk = 1 and if S =1, R =1, then can't we still end up in a loop of oscillations.
The SR flipflop is designed so that C is only 1 when S and R are stable. It is designed very carefully as to prevent C from being 1 when S=R=1. However, this is not apparent at all given the basic diagram of the flip flop.
An improvement to this is the D flipflop. It inverts one of the signals from the SR flipflop. This ensures that S and R are never the same. This can be seen in the image below.
Related
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
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
I am trying to debug my code shown below. I am fairly new to SystemVerilog and hopefully I can learn from this. Let me know of any suggestions.
The errors I am receiving are:
Error-[ICPD] Invalid procedural driver combination
"divide.v", 2
Variable "Q" is driven by an invalid combination of procedural drivers.
Variables written on left-hand of "always_comb" cannot be written to by any
other processes, including other "always_comb" processes.
"divide.v", 2: logic [7:0] Q;
"divide.v", 8: always_comb begin
if (x <= R) begin
...
"divide.v", 5: Q = 8'b0;
Error-[ICPD] Invalid procedural driver combination
"divide.v", 2
Variable "R" is driven by an invalid combination of procedural drivers.
Variables written on left-hand of "always_comb" cannot be written to by any
other processes, including other "always_comb" processes.
"divide.v", 2: logic [7:0] R;
"divide.v", 8: always_comb begin
if (x <= R) begin
...
"divide.v",6: R = y;
My SystemVerilog Code is:
module divider(input logic [7:0] x,y,
output logic [7:0] Q,R);
initial
begin
Q = 8'd0;
R = y;
end
always_comb
begin
if (x<=R)
begin R <= R - x; Q <= Q + 8'd1; end
end
endmodule
module test1;
logic [7:0] x,y,Q,R;
divider Divider1 (x,y,Q,R);
initial
begin
x = 8'd2;
y = 8'd8;
end
endmodule
Generally, in Verilog/SystemVerilog you cannot assign to a variable from two parallel blocks (with some exceptions). You are assigning to R and Q from two places: the initial block and the always_comb block.
Although the initial block only runs once, it runs in parallel with the always_comb block at the beginning of the simulation, which is a violation of this rule.
Why don't you get rid of the initial block and do everything in always_comb?
always_comb
begin
Q = 8'd0; // set initial value of Q
R = y; // set initial value of R
.... //THE REST OF THE ALGORITHM
end
Also, you are missing using a loop!
An important distinction between writing System Verilog (or any HDL) and writing in any software language (C/C++, Java, etc) is that System Verilog is designed to facilitate describing hardware structures while allowing for software-like testbenches, while software languages are designed to allow users to give instructions to an interpreter, VM or actual hardware. That being said, you need to think first about the hardware you are trying to describe and then write the associated HDL code. There are numerous posts describing the differences between HDLs and software languages (ex: Can Verilog/Systemverilog/VHDL be considered actor oriented programming languages?).
Looking at your code and flow chart you were given, it appears you are trying to use System Verilog as a programming language rather than a HDL. For example, initial blocks are generally only used in test benches and not in modules themselves. Also, as your algorithm is sequential, it is likely you will need a clock signal and registers, but the way your code lacks both.
Ideally, you should have a good idea of how to design digital hardware systems before trying to code any HDL, as this is the mentality you should have using HDLs. The goal is generally to translate a hardware design into HDL, so understanding digital design will help clarify alot.
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.
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.