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.
Related
I am new to verilog and have a doubt concerning the race conditions in the following code which is taken from FPGA Prototyping by Veriloog Examples by Pong P. Chu. The code is:
always #(posedge clk)
a = b;
always #(posedge clk)
b = a;
This will infer races depending on which always block gets executed first. But always blocks should get executed in parallel. Correct me if I am wrong. I know there is blocking assignment but how does it affect the first statement of the block, which is the always statement?
The second code using the non-blocking assignment is:-
always #(posedge clk)
begin //b(entry) = b
a <= b; //a(exit) = b(entry)
end //a = a(exit)
always #(posedge clk)
begin //a(entry) = a
b <= a; //b(exit) = a(entry)
end //b = b(exit)
This will work fine according to the book but I couldn't understand why? Is it because the always blocks are executed in parallel in this case because of non-blocking assignment?
Because the Verilog "stratified event queue" has different regions, the type of assignment operator used makes a difference in how the code is executed. The details can be found in section 5 of the IEEE Verilog standard, but in terms of your question, it boils roughly down to this:
The blocking assignments (in your first example) are evaluated immediately, i.e. when the always block they're in is activated. Since both blocks are parallel, order of their activation is undefined.
The non-blocking assignments are not executed immediately but rather scheduled after all blocks of the same time step have finished executing.
So when encountering a rising clk edge, in your first example a simulator would
Pick at random one of the always blocks
Find that the assignment is a blocking one and execute it immediately, therefore changing the left-hand variable in that assignment.
Pick the other always block and do the same, at which point the value of the first variable was already changed.
In your second example, the simulator would
Pick at random one of the always blocks
Find that the assignment is a non-blocking one and therefore
evaluate the right-hand side of the = sign and schedule the value it found there as a non-blocking assign update event to the variable left of the =.
Pick the other always block and do the same. Note that both variables still have their values from before the rising clk edge.
Since all blocks are done executing, update all variables which were scheduled for non-blocking assign update events, effectively swapping their values.
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?
I am trying to assign a state to a register in a FSM machine #(posedge clk) and reset = 1. However, statement: state <= 2'b00; simply couldn't set state = 2'b00. I checked by debugging that this statement state <= 2'b00 did have been stepped over. I really don't know where the problem is.
I met similar problems in other situations when some registers couldn't be assigned a value using "<=", but some can be in the same always block.
These registers that couldn't take the values simply show as 2'bxx if they have two bits.
Does anybody know what could cause the problem?
Looking at your explanation, i suppose your code is something like this.
always#(posedge clk and reset = 1)
state <= 2'b00;
These are the mistakes you are doing.
1. Sensitivity list can't be a combination of edge triggered and level triggered signals.
2. For conditional operation, you should use "==", not "=".
Ideal code for your operation is,
always#(posedge clk)
if (reset == 1)
state <= 2'b00;
I actually used the same way as you use the clock and reset signal in my code. However, my problem is that I reset the state at the beginning of the always block. Then, in the case statement inside the same always block, I used the default case to put the state back to arbitrary state. I am still a little bit confused by this mistake. But, anyway, after I removed this default statement, everything goes back to normal.
Thanks.
I'm running into some problems implementing a synthesizeable state machine to output the results from several lower-level modules I've already implemented. As far as I can tell, the structure I have so far wants nested always blocks, but that can't be done in Verilog. I'm not sure how to circumvent this problem.
EDIT: code taken down as at least one classmate has turned in identical (and non-functioning, lol) portions of my own code.
If you think you need nested always blocks then you are likely not thinking about hardware design, while RTL gives some abstraction from the electronic components it has to be written in such away that represent possible hardware behaviour.
always #* represents a combinatorial block.
always #(posdege clk) represents sequential logic, where the outputs are driven by flip-flops.
always blocks tell the simulator when to trigger the block for simulation, as everything is happening at once, it is all parallel. The simulator could not know when to schedule code not contained in these blocks.
You need to have always #(posedge KEY[0] and always #(posedge KEY[1] which each contain the case statement. If they are not to do anything for a particular case then hold or Zero the current values. You can have a default: case as a catch all for those unspecified.
Update
Regarding the rotate function you should be able to take the MSB to indicate if negative.
Use >>> to preserve sign bits. you might need to declare the reg/wires assigned or add $signed function
reg signed [msb:0] data_in;
always #(posedge clk) begin
if (data_in[msb] == 1'b0) begin
data_out <= data_in <<< 1;
end
else begin
data_out <= data_in >>> 1;
end
end
// or use $signed(data_in) >>> 1;
You appear to have everything inside an initial block, so looking for a posedge doesn't even make sense. In general, initial blocks are not synthesizable.
No, you can't nest always blocks and you shouldn't need to.
You should have a single always #(posedge KEY[1]) that contains all of the possible assignments to STATE. You can't make assignments to the same reg in different always blocks. Be sure to use non-blocking assignments.
Create additional always blocks for your other reg signals, ideally using one always block per signal.
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