Understanding Verilog Code with two Clocks - verilog

I am pretty new to Verilog
and I use it to verify some code from a simulation program.
Right now I am struggeling if a verilog code snippet because the simulation programm uses 2 clocks ( one system clock and a pll of this ) where two hardware componentes work together, thus synchronize each other:
module something (input data)
reg vid;
always #(posegde sys_clk)
vid <= data;
always #(posegde pll_clk)
if (vid)
// do something
When reading about non blocking assignments it says the evaluation of the left-hand side is postponed until other evaluations in the current time step are completed.
Intuitive I thought this means they are evaluated at the end of the time step, thus if data changes from 0 to 1 in sys_clk tick "A", this means at the end of "A" and the beginning of next sys_clk tick this value is in vid and so only after "A" the second always block ( of pll_clk) can read vid = 1
Is this how it works or did i miss something ?
Thank you :)

In this particular case it means that
if posedge sys_clk and pll_clk happen simultaneously then vid will not have a chance to update before it gets used in the pll_clk block. So, if vid was '0' before the clock edges (and is updated to '1' in the first block), it will still be '0' in the if statement of the second block. This sequence is guaranteed by use of the non-blocking assignment in the first block
if the posedges are not happening at the same time, then the value of vid will be updated at posedge sys_clk and picked up later at the following posedge of pll_clk.
In simulation non-blocking assignment guarantees that the assignment itself happens after all the blocks are evaluated in the current clock tick. It has nothing to do with the next clock cycle. However, the latter is often used in tutorials to illustrate a particular single-clock situation, creating confusion.
Also being simultaneous is a simulation abstraction, meaning that both edges happen in the same clock tick (or within a certain small time interval in hardware).

Related

verilog flop RTL simulation

Assume we have a D-flip-flop.
in RTL simulation (No t_hold and t_setup here), If its data input and clk changes at the same time, what the output should be ? The value before clk rise or the value after it ?
To make it even harder,
If a data_in and clock are connected to same wire. what should be the flop's output be ? zero all time ? or one all time ?
I tried the last case in ModelSim, and I get that the output is 1 all the time, while I expect it to be 0.
I expect that the flop in RTL-simulation should simulate the value before the clock edge.
When you use a simulation you will see results depend on how this case interpreted in the simulator what you use.
As you wrote in simulation t_setup = 0, it means that you don't need to keep signal in that level (what should be caught by flip flop) some time before rising (or falling) edge of clock signal, but can be applied exactly in the same time with the rising (or falling) edge of clock.
Because you see all time of the simulation '1' on the output of flip flop

Use of Non-Blocking Assignment in Testbench : Verilog

I have two questions regarding the use of Non-Blocking assignments in testbench.
Can we use blocking assignment in always #(posedge clk) w.r.t testbench? I think we can use as we dont have to worry about hardware. But I need confirmation.
I have used the following code in my testbench but it doesn't work as expected.
always #(posedge clk)
begin
while((state==2'd3) && (x!=OUT_MAX_SIZE_32) && (count_done==4'd4))
begin
$display("a[%d] :%h, %d",l,a[l],x);
a[l] <= {b[x][31], b[x][30], b[x][29], b[x][28], b[x][27], b[x][26], b[x][25], b[x][24]};
a[l+1] <= {b[x][23], b[x][22], b[x][21], b[x][20], b[x][19], b[x][18], b[x][17], b[x][16]};
a[l+2] <= {b[x][15], b[x][14], b[x][13], b[x][12], b[x][11], b[x][10], b[x][9], b[x][8]};
a[l+3] <= {b[x][7], b[x][6], b[x][5], b[x][4], b[x][3], b[x][2], b[x][1], b[x][0]} ;
x <= x+1;
l <= l+4;
end
end
What is happening is x and l are not incrementing if I use non-blocking assignments. But if I use blocking assignments, it works as expected. I need help in analyzing it.
You can and should use non-blocking assignments in your testbench. A simulator does not know the difference between what is you design and your testbench. You need to code both in a way to prevent race conditions.
From the code that you show, I can't see why it would make any difference unless there are other assignments to x and l elsewhere that you are not showing.
Non-blocking assignments can always be used in test bench code. This becomes an infinite loop by use of non-blocking assignments.
Referring to SystemVerilog LRM 1800-2012 section 10.4.2,
The non blocking procedural assignment allows assignment scheduling without blocking the procedural flow.
Referring to section 4.9.4,
A non blocking assignment statement (see 10.4.2) always computes the updated value and schedules the update as an NBA update event, either in the current time step if the delay is zero or as a future event if the delay is nonzero.
Here, at the posedge of clock, lets say x=0 so it is assuming while loop is executed. The RHS of non-blocking assignments are evaluated in active region, while the actual assignments are done in NBA region.
So, increment of x to 1 is scheduled in NBA region of the same time-stamp. Also, since it is a non-blocking statement, the condition of while loop is checked again in active region without blocking anything (getting x=0 again). Again, x is scheduled to be incremented in NBA region and this loop goes on forever. Hence you are not able to increment x. Similar comments applies to l.
While, using blocking assignments, the value is immediately assigned to the LHS of expression, hence x/l increases.
Also, $display executed in Active region, so you'll not be able to get value of x as 1. Following image shall give you clear idea about this.
For more information on event regions, refer to CummingsSNUG2006Boston_SystemVerilog_Events paper.

Non-blocking and blocking assignments don't work as expected

I'm having problems with understanding such a simply looking thing: blocking and non-blocking assignments.
I created a small test bench just to simulate the behavior of this code:
module ATest(clk, out);
input wire clk;
output reg [7:0] out;
reg [7:0] A;
initial begin
A <= 8'b0;
end
always #(posedge clk) begin
A = A + 1;
out = A;
end
endmodule
After simulation, I got this wave:
I expected the same value under both A and out, as I assigned values to them sequentially. Why is out "don't care" during the first clock?
Then I tried to use non-blocking assignment. I changed a part of my code into:
always #(posedge clk) begin
A <= A + 1;
out <= A;
end
And I got this wave:
I didn't expect anything here, because non-blocking statements are kind of mystery to me. Why is both A and out set to "don't care"?
Also, I found different names on every page I got to, so please help me out:
Are blocking and non-blocking interchangeable with sequential and concurrent as terms? Which one is right: non-blocking statement or concurrent statement?
Without diving too deep into the simulation cycles used by Verilog Simulators, you can think of non-blocking vs blocking assignment simply as this:
Blocking assignment happens inline at the time the given assignment is executed, so that means if I have a line like A = A + 1, that means we take the present value of A, add 1 and assign A that new value. So, the assignment "blocks" execution until it is done.
Non-blocking assignment (NBA) happens at a time slightly later than while the line is executed. You can think of non-blocking assignments as lines telling the simulator to schedule this assignment for a little bit later (note, later is still with the same simulation time step, so all of this is still happening in simtime t). So, if you have something like A <= A + 1, this means take the value of A at the time of executing this line, add 1 and schedule A to be updated to that value in a little bit, but keep moving on with the lines following that one. So, if the next line after is out = (A == 1) ? 1 : 0, this line will execute using the old value of A, not the incremented one. Once the simulator finished with the active code, it can move on to perform all the non-blocking assignments. Now, A will get the incremented value and all other non-blocking assignments will take effect.
So, to your examples. In case one, we see the delayed effect of NBA. In the initial block, A is assigned to 0, which means A will take on the value of 0 a little bit later (still within sim time 0 remember); ie the assignment is scheduled to take place after all blocking assignments have run (Not strictly true but it works in this case). Also, you have the clock's posedge happen so the always block runs. Here, A takes on the value A + 1, but remember, the assignment of A to 0 hasnt happened, so A still has its initial value of 8'bx. so, A + 1 is also 8'bx. And since this is a blocking assignment, it happens right away. So, A doesnt change from don't care. Continuing on, out gets the current value of A, which is 8'bx. So, we get the don't cares on out. After these and other blocking assignments are done, now we finish up the NBAs, in this case, A to become 0. So, still within sim time 0, A becomes 0 and we are done. At the next posedge of the clock, A is 0, out is don't care and your always block runs as expected, incrementing A and assignment out to the same value.
If you change the always block to use NBA (which it should if it is suppose to be a register), things change slightly. The initial block still results in a NBA scheduled for A to become 0. But now, the always block does something different. Now, A <= A + 1 instead of assigning A to don't cares right away, it schedules A to become 8'bx (remember, the right-hand side expression for what value to assign is evaluated inline, so A + 1 still uses A as don't care just as before; whats changed is when A takes on this new value) and this is scheduled after A to become 0. So, both the NBAs of A are set up, but the one telling A to be 0 happens first and is wiped out by the later assignment of A to 8'bx. out is similarly scheduled to take on 8'bx but now, A never becomes 0. As such, both A and out get stuck at 8'bx.
You can look through the Verilog or SystemVerilog LRM's to get a better understanding of sim cycles and what really goes on, but I hope this helps you better understand the difference!
Your issue come from using a non-blocking assignment in your initial block. Use initial A = 8'b0; instead.
The casue for this is likely how the two assignments are processed. = assignments are done incrementally, with any new values being available to subsequent assignments. Changes made via <= assignments are only available once all assignments have been processed.
Because your first edge is at t = 0 (when intial blocks are processed), in the first example A is assigned 0, but that 0 isn't available to out until after it is processed. That's while the first cycle looks weird, but everything else is OK. In the second, A is assigned both 0 and A+1, so the simulator uses the always block instead of the initial, going with A+1, when A is still an unknown value. As such, the values for A and out are never known.
The terms are equivalent. "Blocking" is the same as "sequential" because "blocking" means that the assignment must be done before the simulator moves to the next line (in sequence). "Non-Blocking" means that all the lines may be done at once. As everything with Verilog, it helps to imagine the hardware intended, so you may think of it as "parallel" vs. "serial" sometimes.
Is there a positive clock edge at time 0 in your simulation?

Always block not behaving as expected

I am making a state machine in verilog to implement certain arithmetic functions based on user input. I've run into a snag, however; my first always block, the one that handles my reset and maintains the correct state, is not behaving as expected; it is not updating the state correctly. The code is as follows:
always # (posedge CLOCK_50 or negedge RESET) begin
if(RESET == 1'b0)
STATE <= BASE;
else
STATE <= NEXT_STATE; // this always block, and specifically this line, is //not executing correctly.
end
Here is the general output of the file when reset and then following three button presses (KEY[1]) with SW = 0000:
EDIT: waveform with actual CLOCK_50 and RESET signals added
http://imgur.com/0DUka21
As for my question, I just want to know what I am doing incorrectly with this section of code. I can think of no reason for it to behave this way. Thanks for any help you can provide.
EDIT2: FFS, I changed the block to negedge CLOCK_50 and now it's working. I'd really like to know why if you can tell.
Ah, I see what you did now. You're assigning STATE in both of your two always blocks (STATE <= STATE in the default of the case block). This is bad, as it's a race condition between the two blocks as to which gets actually assigned. In your case, the second block is overriding the first, such that STATE <= STATE gets executed every clock. You should not assign the same variable in more than one always block.
Also you should pay attention to those warnings, but they are referring to the always #(ENABLE) block. This is complaining because you are inferring weird latched behavior, because the output is depending on STATE and SW, but they are not in the sensitivity list. You should probably just make this a combinational block, and use the auto-sensitivity list always #*.
Every always block, as well as every statement outside of an always block, effectively runs in parallel.
Since you have "state" being driven by two always blocks, you're effectively having two wires feed into a single wire. In digital logic design, you just can't do that. (Excluding pull-up resistors and such, but that's another topic.)
In simulation, if the multiple wires driving that single wire have the same logical value, you can get the output you desire; but if they have different values, you'll get invalid or unpredictable output.
In synthesis, this will simply fail with a "multiple drivers" error.
Also, the sensitivity list for an always block should have one of three things in it:
A clock
A clock and an asynchronous reset
Every wire/reg that is used as an input to that always block (*)
Anything else can result in an unintentional latch, which will cause problems.
In case 3, you need to make sure that every wire driven in the always block has a default value. Anything else can result in an unintentional latch.
Lastly, you can't have circular assignments or you risk a logic loop. You have one by assigning next_state to itself. Anything "circular" requires a flip-flop, aka an always block of type 1 or 2 outlined above.

About verilog flip flop delay

I want to buffer a single-bit signal "done" with two single-bit flip-flops. The done signal will rise for only one clock cycle in my design. So I wrote the following code.
//first level buffer done signal for one cycle to get ciphertext_reg ready
always #(posedge clk or posedge rst) begin
if(rst)
done_buf_1 = 1'b0;
else
done_buf_1 = done;
end
//second level buffer
always #(posedge clk or posedge rst) begin
if(rst)
done_buf_2 = 1'b0;
else
done_buf_2 = done_buf_1;
end
In functional simulation, I discover the done_buf_1 rises one cycle after done, but done_buf_2 rises at the same time as done_buf_1.
What is the explanation for this?
Thank you!
You've already got answers with the solution ("use non-blocking assignments"), but here's an attempt at why you need to do that.
Both of your always statements have the same event, so they could run in any order. What seems to be happening is that the first one is running first. When the line...
done_buf_1 = done;
... is hit, it will block until the assignment is complete (it's a "blocking" assignment). Therefore done_buf_1 takes the new value immediately. This differs from the non-blocking version...
done_buf_1 <= done;
... which says 'give done_buf_1 the value of done (which I'll evaluate now) at the end of the time slice'.
Now we move on, and done_buf_2 is assigned.
done_buf_2 = done_buf_1;
Now, if done_buf_1 was updated with a blocking assignment it already has the current value of done, and you'll see both signal rise at the same time. If it was a non-blocking assignment then done_buf_1 still has the previous value of done, as it won't be updated until the end of the time-slice, the result being a 2 cycle delay for done_buf_2.
There's also another problem though. Remember that I said that the always statements could be run in either order because the events were the same? Well if the second one was executed first the code would appear to work as intended (db2 = db1; db1 = done; No problem). So it's worth knowing that using blocking assignments like this gives erratic results especially between tools. That can lead to some subtle bugs.
You're using blocking assignments = to model synchronous logic. You need to use non-blocking assignments <=.
As others have said: don't use blocking assignments (=) for this.
The key point is that "this" is the job of communicating between different processes. The race conditions inherent in blocking assignments make this unpredictable. VHDL takes this so seriously that it separates these types of assignment such that you can't use the wrong one (as long as you keep away from shared variables).
Some interesting writings on the subject from Jan Decaluwe:
Verilog's major flaw
VHDL's crown jewel

Resources