verilog always, begin and end evaluation - verilog

I'm trying to learn Verilog using Pong P. Chu's book. I have a question about how an always block is evaluated and implemented. A style in the authors code is confusing me.
In this example he codes an FSM with two output registers 'y1' and 'y2'. The part I'm confused about is in the NEXT STATE LOGIC AND OUTPUT LOGIC always block, where after the begin statement and always#* y1 and y0 are set to 0. I seems that regardless of state, y1 and y0 will toggle to 0 on every clock cycle and signal change. According to state diagram in the book reg y1 should be equal to 1 while in state 0 or 1.
So does y1 toggle to 0 every clock cycle then back to what ever its value at the present state?? I assume that's not the case and that I'm just confused about how the block is evaluated. Can someone explain what that part of the code is doing. I'm lost. Thanks
module fsm_eg_2_seg
(
input wire clk, reset, a, b,
output reg y0, y1
);
//STATE DECLARATION
localparam [1:0] s0 =2'b00,
s1=2'b01,
s2=2'b10;
// SIGNAL DECLARATION
reg [1:0] state_reg, state_next ;
//STATE REGISTER
always #(posedge clk, posedge reset)
if (reset)
state_reg <= s0;
else
state_reg <= state_next;
//NEXT STATE LOGIC AND OUTPUT LOGIC
always #*
begin
state_next = state_reg; // default next state: the same
y1 = 1'b0; // default output: 0
y0 = 1'b0; // default output: 0
case (state_reg)
s0: begin
y1 = 1'b1;
if (a)
if(b)
begin
state_next = s2;
y0 = 1'b1;
end
else
state_next = s1;
end
s1: begin
y1 = 1'b1;
if (a)
state_next = s0;
end
s2: state_next = s0;
default: state_next = s0;
endcase
end
endmodule

The expression
always #* begin : name_of_my_combinational_logic_block
// code
end
describes combinational logic. Typically the clk and rst signals are not read from inside of this type of always block, so they don't appear in the sensitivity list like wisemonkey says. It is best practice to use #* for the sensitivity lists of combinational logic so that you don't forget to include a signal, which would infer some memory and it would no longer be combinational logic.
Inside a combinational logic block, you should use what are called blocking assignments. These look like regular variable assignments in most programming languages and use a single equals. The value that you assign to a variable (a reg) inside of a combinational logic block happens immediately with respect to other statements and expressions in that same combinational logic block, but does not propagate outside of this combinational logic block until you reach the end. The always block must reach the end before any changes are seen outside of the block. Paul S is right that you want to always assign something to your variables whenever the always block is executed, otherwise you will infer memory.

Have to say I disagree with aqua. What he (and wisemonkey) says about #* is right, but the rest is wrong.
Those two lines have nothing to do with an idle state. Those statements are there as good coding practise. They ensure that those two outputs are always assigned to when that always block is evaluated. Let's see why this is important:
Imagine that those two statements aren't there.
Next suppose that state_reg = S0, and a = b = 0
As we evaluate the always block, we enter the case statement, s0 half, and assign 1 to y1
a is zero so we don't enter the if statement, and we drop out of the case, and end the block
At the end of the block y1 == 1 and y0 == ... erm, hang on what does y0 get? I guess it has to keep it's old value. It didn't get a new one.
That means it's possible y0 has to remember it's value from one cycle to the next. That would mean it needs to have some kind of memory involved, like a register or a latch. In this case it would be a latch as it's written in a style that sometimes drives the output and sometimes holds it.
...but we don't want that. y1 and y0 were meant to be simple wires. Therefore we must make sure each of them are always assigned to, no matter what the state or inputs are. We could do that by having assignments in all the branches of the logic, but that becomes a lot of work. Alternatively we can have a default assignment which we later override if necessary.
The reason these statements don't introduce y1 going to 0 in s0 or s1 is because everything that happens inside an always block happens with no time passing. No time passes between the 0 being assigned at the top and the 1 in s0 or s1. All that's visible is the final state.
You'll note the code does exactly the same thing with the state variable. It has a default assignment that the next state is the current state, and then overrides that it the correct conditions are met.
Nice clean state machine. Nothing wrong with it.

This is a poor example of an FSM. I'm not surprised that you are confused. The way I understand it, an always block is scheduled to run only when the inputs in its sensitivity list change.
So for the first always block, it is scheduled to run every clock transition from 0 to 1, and reset is asynchronous.
The second always block has the #* notation, which basically creates a sensitivity list for you based on the logic within the block. Recall that only inputs matter in a sensitivity list. Therefore, this always block will be scheduled if a, b, or state_reg change.
In this example, the
y1 = 1'b0; // default output: 0
y0 = 1'b0; // default output: 0
is trying to model an IDLE state, a state where the FSM is outputting 0. If you do a quick study of how the FSM operates, you'll see that once it starts transitioning through the states, (the case statements) it won't come back out.
Ideally you want your IDLE information within a state of its own, not floating outside the state logic, but I suppose this works as a trivial example.

I don't think other answers directly and correctly addresses the question of whether y0 and y1 toggle to 0 and back on every clock cycle.
Let's say that the state machine changes from s0 to s1. In both states the end value of y1 is 1 but in re-evaluating the always block y1 is first assigned 0. This toggling may happen multiple times per clock, or not at all on a clock cycle depending how many times a, b, and state_reg change. Whether this toggling propagates to the wire attached to output y1 is simulator dependent. Port assignments are treated as continuous assignments in Verilog, which are separately running threads of execution. It is perfectly legal for the simulator to suspend execution of the always block after the y1=0 assignment is made, assign 0 to the wire attached to output y1, and resume execution of the always block afterwards. Practically speaking, it doesn't matter IF good coding styles are practiced because the value of y1 won't get latched into any registers until the next clock cycle, long after all the toggling is done and the final value of y1 is available.
In simulation the toggling happens in zero time but it also happens in real hardware when multiple inputs change. It takes special design practices to build logic that doesn't "glitch" like this.

Related

During simulation, why do flip-flops take the value preceding the transition while conditional(if) statements take the value after the transition?

As you can see in the cursor below, the if statement looks AFTER the transition (it sees rst = 0 and thus sets a equal to in) rather than seeing rst = 1.
BUT it can also be seen that c takes the value of a BEFORE the transition.
I am wondering why this is. Suppose you want to gate a register with an enable that is delayed on clock cycle, then you can not use if (enable_delayed) because (ideally) the falling transition will happen on the rising edge of the clock and thus not be detected in simulation.
I have not had success finding my problem online. It is hard to explain and search for. Thanks for the help.
Code:
module project_test
( input logic clk, rst,
input logic in,
output logic a,
output logic b,
output logic c
);
always#(posedge clk)
if(rst) a <= 1'b0;
else a <= in;
always#(posedge clk)
if(a) b <= a;
always#(posedge clk)
c <= a;
endmodule: project_test
My guess would be you are setting rst earlier than you think and it is already 0 when the logic inside the module observes the positive clk edge.
If you were to set rst to 0 as a result of a #(posedge clk) things would work as you expect, but I suspect rst is being changed in parallel with clk.
When debugging this sort of thing, I always try to delay the assignment of the values. That is, in your module here replace <= with <= #1 .
rst is a wire (an input port is a wire, at least in verilog), so value is continuously assigned to it. So when it was sampled during the positive edge of the clock, its value is already 0.
'a' on the other hand is a reg(a flipflop) so its value when it was sampled on the positive edge of the clock is still its previous value. Its value will only change 'right after the clock'. That's why 'c' still gets the previous value of 'a'.
I think that's what's happening here.

Verilog race with clock divider using flops

I made a basic example on eda playground of the issue I got.
Let s say I have two clocks 1x and 2x. 2x is divided from 1x using flop divider.
I have two registers a and b. a is clocked on 1x, b is clocked in 2x.
b is sampling value of a.
When we have rising edge of 1x and 2x clocks, b is not taking the expected value of a but it s taking the next cycle value.
This is because of this clock divider scheme, if we make division using icgs and en it works fine.
But is there a way to make it work using this clock divider scheme with flops ?
EDA playground link : https://www.edaplayground.com/x/map#
module race_test;
logic clk1x = 0;
logic clk2x = 0;
always
#5ns clk1x = !clk1x;
int a, b;
always #(posedge clk1x) begin
a <= a+1;
clk2x <= !clk2x;
end
// Problem here is that b will sample postpone value of a
// clk2x is not triggering at the same time than clk1x but a bit later
// This can be workaround by putting blocking assignment for clock divider
always #(posedge clk2x) begin
b <= a;
end
initial begin
$dumpfile("test.vcd");
$dumpvars;
#1us
$stop;
end
endmodule
Digital clock dividers present problems with both simulation and physical timing.
Verilog's non-blocking assignment operator assumes that everyone reading and writing the same variables are synchronized to the same clock event. By using an NBA writing to clk2x, you have shifted the reading of a to another delta time*, and as you discovered, a has already been updated.
In real hardware, there are considerable propagation delays that usually avoid this situation. However, you are using the same D-flop to assign to clk2x, so there will be propagation delays there as well. You last always block now represents a clock domain crossing issue. So depending on the skews between the two clocks, you could still have a race condition.
One way of correcting this is using a clock generator module with an even higher frequency clock
always #2.5ns clk = !clk;
always #(posedge clk) begin
clk1x <= !clk1x;
if (clk1x == 1)
clk2x = !clk2x;
Of course you have solved this problem, but I think there is a better way.
The book says one can use blocking assignment to avoid race. But blocking assignemnt causes errors in synopsys lint check. So, one way to avoid race problem without lint error is to use dummy logic, like this
wire [31:0] a_logic;
wire dummy_sel;
assign dummy_sel = 1'b0;
assign a_logic = dummy_sel ? ~a : a;
always #(posedge clk2x) begin
b <= a_logic;
end

What does <= operator do in this code?

module counter (clk,rst,enable,count);
input clk, rst, enable;
output [3:0] count;
reg [3:0] count;
always # (posedge clk or posedge rst)
if (rst) begin
count <= 0;
end else begin : COUNT
while (enable) begin
count <= count + 1;
disable COUNT;
end
end
endmodule
(Source: http://www.asic-world.com/verilog/verilog_one_day2.html#While)
From what I have learnt, <= is a relational operator and it will return 1 if true and 0 if false, but where does it return in this code?
In the context of your code, <= is not a relational operator, it is an assignment operator. There are two types of assignment in Verilog:
blocking : =
non-blocking : <=
In a Verilog design, you
always use blocking assignments for combinational logic
always use non_blocking assignments for sequential logic
If you do not, you simulation will be indeterminate - it will not necessarily behave the same way every time you run it. Which, of course, is not good.
So, why is that? Well, to start you must learn that Verilog has 4 scheduling regions:
from prev time step
|
ACTIVE
|
INACTIVE
|
NBA
|
POSTPONED
|
V
to next time step
Blocking assignments are executed in the ACTIVE region. However, while the right-hand side of a non-blocking assignment is evaluated in the ACTIVE region, the assignment does not occur until the NBA region. This is key to why you need to use them for sequential logic.
So, why do you need to use non-blocking assignments for sequential logic? The reason is because the delay between evaluation of the right-hand side and assignment of the left hand side enables a Verilog simulation to be determinate, ie to behave the same way every time you run it. This delay means that the behaviour of the simulation does not depend on the order in which the always blocks are executed, which it would if only blocking assignments were used.
A simple analogy to the delay between evaluating the right-hand side of a non-blocking assignment and assigning the left-hand side is the clock-to-Q delay of a real flip-flop. In a real flip-flop, there is always a small delay (clock-to-Q delay) between the D input being sampled (by the clock) and the Q output being driven. This is vital to the correct operation of real sequential logic. For example, if there were no clock-to-Q delay in a real flip-flop instead of it taking exactly 4 clocks for the D input of the first flip-flop in a 4-stage shift register to get to the Q output of the fourth flip-flop, it could take any number of clocks between 1 and 4: its behaviour would also be indeterminate.

What is inferred latch and how it is created when it is missing else statement in if condition. Can anybody explain briefly?

I tried to figure out the inferred latch and why it is needed internally, but I couldn't find any resources with enough detail.
A latch is inferred within a combinatorial block where the net is not assigned to a known value. Assign a net to itself will still infer a latch. Latches can also be inferred by missing signals form a sensitivity list and feedback loops.
The proper way of inferring a intended latch in Verilog/SystemVerilog are:
/* Verilog */ //// /* SystemVerilog */
always #* //// always_latch
begin //// begin
if (en) q = d; //// if (en) q = d;
end //// end
Ways latches are accidentally inferred:
Signal(s) missing for the sensitivity list (this is why #* should be used):
always #(a or b) // inferred latch :: "c" missing for the sensitivity list.
begin
out = a + b + c;
end
Missing Condition:
always #*
begin
case(in[1:0])
2'b00: out = 1'b0;
2'b01: out = 1'b1;
2'b10: out = 1'b1;
// inferred latch "out" :: missing condition 2'b11/default
endcase
end
always #*
begin
next0 = flop0;
next1 = flop1;
// inferred latch "next2" :: missing initial condition
next3 = flop3;
case(a[2:0])
3'b001: next0 = in;
3'b010: if(b) next1 = in;
3'b100: if(c) next2 = in;
default: if(!b&&!c) next3 = in;
endcase
end
Feedback Loop:
assign out = en ? in : out; // inferred latch "out" :: feedback to mux
assign a = en ? z : c;
// ... any amount of code between ...
assign z = en ? a : y; // inferred latch "a" :: feedback chain
Feedback loops can traverse through the hierarchy and design.
How to mitigate the risk of unintended latches:
Make intended latches simple and identifiable:
Put intended latches in their own always blocks with as little combinatorial logic as possible; ideally put the latches' combinatorial logic in its own separate always block. Be as explicit and identify intended latches. Use comments, labels, and if possible use the SystemVerilog always_latch.
All combinatorial logic blocks need to be defined with always #* or SystemVerilog's always_comb.
Make sure all variables assigned in a combinatorial logic blocks have an initial or default assignment.
case statements should have a default condition.
if statements should have a corresponding else.
When the combinatorial logic blocks is assigning many variables, giving each variable an initial value at the start of the block (before any case or if).
Know where the inputs are coming from and where the outputs are going to.
The inputs of combinatorial logic should be flops or the outputs combinatorial logic should be flops.
Do code reviews, use linting tools and logical-equivalency-checking tools.
Code review requires the reviewer(s) to know where latches could hide.
Using SystemVerilog's always_comb can help identify inferred latches with linting and logical-equivalency-checking tools.
Worst case scenario, put all logic inside synchronous blocks. All inferred latches become inferred flip-flops. This is usually a bad idea because it can unnecessarily increases the gate count, create more routing, and impact timing.
A latch is inferred when the output of combinatorial logic has undefined states, that is it must hold its previous value.
Combinatorial logic does not have any flip-flop to hold state therefore the output should always be defined by the inputs.
A short example might be:
always #* begin
if (a == 1'b1) begin
b = x|y|z;
end
end
What is b when a == 1'b0. b is not being overridden so it would hold its value. How can something hold its value when it does not have the concept of state. You have to introduce state by inferring a latch. This is normally a really bad thing.
You can imply latches and be carefull about the timing etc but inferred latches are nominally from buggy code.
Latches are only generated with combinational always blocks. Sequential logic will never generate a latch.
For more information read about how transparent latches are created and how to avoid inferring latches

24 bit counter state machine

I am trying to create a counter in verilog which counts how many clock cycles there have been and after ten million it will reset and start again.
I have created a twenty four bit adder module along with another module containing twenty four D Flip flops to store the count of the cycles outputted from the adder.
I then want to have a state machine which is in the count state until ten million cycles have passed then it goes to a reset state.
Does this sound right? The problem is I am not sure how to implement the state machine.
Can anyone point me to a website/book which could help me with this?
thanks
As Paul S already mentioned, there is no need for a state machine if you want your counter to keep counting after an overflow. You can do something like this (untested, might contain typos):
module overflow_counter (
clk,
reset,
enable,
ctr_out
);
// Port definitions
input clk, reset, enable;
output [23:0] ctr_out;
// Register definitions
reg [23:0] reg_ctr;
// Assignments
assign ctr_out = reg_ctr;
// Counter behaviour - Asynchronous active-high reset
initial reg_ctr <= 0;
always # (posedge clk or posedge reset)
begin
if (reset) reg_ctr <= 0;
else if (enable)
begin
if (reg_ctr == 10000000) reg_ctr <= 0;
else reg_ctr <= reg_ctr + 1;
end
end
endmodule
Of course, normally you'd use parameters so you don't have to make a custom module every time you want an overflowing counter. I'll leave that to you ;).
[Edit] And here are some documents to help you with FSM. I just searched Google for "verilog state machine":
EECS150: Finite State Machines in Verilog
Synthesizable Finite State Machine Design Techniques
I haven't read the first paper, so I can't comment on that. The 2nd one shows various styles of coding FSMs, among which the 3 always blocks style, which I highly recommend, because it's a lot easier to debug (state transitions and FSM output are neatly separated). The link seems to be down, so here is the cached Google result.
You don't need a state machine. You already have state in the counter. All you need to do is detect the value you want to wrap at and load 0 into your counter at that point
In pseudo-code:
if count == 10000000 then
nextCount = 0;
else
nextCount = count + 1;
...or...
nextCount = count + 1;
if count == 10000000 then
resetCount = 1;
State machines are not too tricky. Use localparam (with a width, don't forget the width, not shown here because it is just one bit) to define labels for your states. Then create two reg variables (state_reg, state_next). The _reg variable is your actual register. The _next variable is a "wire reg" (a wire that can be assigned to inside a combinational always block). The two things to remember are to do X_next = X_reg; in the combinational always block (and then the rest of the combinational logic) and X_reg <= X_next; in the sequential always block. You can get fancy for special cases but if you stick to these simple rules then things should just work. I try not to use instantiation for very simple things like adders since Verilog has great support for adders.
Since I work with FPGAs, I assign initial values to my registers and I don't use a reset signal. I'm not sure but for ASIC design I think it is the opposite.
localparam STATE_RESET = 1'b0, STATE_COUNT = 1'b1;
reg [23:0] cntr_reg = 24'd0, cntr_next;
reg state_reg = STATE_COUNT, state_next;
always #* begin
cntr_next = cntr_reg; // statement not required since we handle all cases
if (cntr_reg == 24'd10_000_000)
cntr_next = 24'd0;
else
cntr_next = cntr_reg + 24'd1;
state_next = state_reg; // statement required since we don't handle all cases
case (state_reg)
STATE_COUNT: if (cntr_reg == 24'd10_000_000) state_next = STATE_RESET;
endcase
end
always #(posedge clk) begin
cntr_reg <= cntr_next;
state_reg <= state_next;
end
I found this book to be very helpful. There is also a VHDL version of the book, so you can use both side-by-side as a Rosetta Stone to learn VHDL.

Resources