Blocked and non-blocking assignment error in verilator - verilog

I'm testing SystemVerilog code using verilator, and it looks like below.
output [31:0] data_out1;
reg [31:0] data_out1;
always #(rst_b or addr1 or data_in1 or write_mask1)
begin
if((write_mask1 != 32'b0) && (rst_b == 1'b1))
begin
data_out1 <= 32'hxxxxxxxx;
... do something ....
end
always #(posedge clk)
begin
if((write_mask1 != 32'b0) && (rst_b == 1'b1))
begin
data_out1 <= 32'hxxxxxxxx;
... do something ..
end
It has two always blocks, and in each block, data_out1 is assigned in non-blocking. But, it shows a "Blocked and non-blocking assignments to same variable" error.
I do not use blocking assignment, and I can't understand why such an error occurs. I would appreciate if anyone can help.

When I run verilator on your code snippet, I get messages like the following:
%Warning-COMBDLY: Delayed assignments (<=) in non-clocked (non flop or latch) block; suggest blocking assignments (=).
%Warning-COMBDLY: *** See the manual before disabling this,
%Warning-COMBDLY: else you may end up with different sim results.
%Error-BLKANDNBLK: Unsupported: Blocked and non-blocking assignments to same variable: data_out1
The 1st warning message indicates that verilator interprets your 1st always block as combinational logic, not sequential logic, and it treats the nonblocking assignment operator (=>) as a blocking assignment.
Since your 1st block does not use #(posedge clk), it is treated as combinational logic.
Also, you should not make assignments to the same signal from multiple blocks.
Lastly, you should not use nonblocking assignment to infer combinational logic.

There are two issues:
The code in the post is assigning the same signal from two always blocks. This can't be done, data_out1 must be driven from a single always block.
The always block without the clock infers combinational logic. The correct way to model combinational logic is by using blocking assignments (=).

The 2nd always block is ok (but not clean, because the rst_b is not at the first condition alone, it might cause problem for some simulator), working as a FF with sync low-active reset. The problem is the 1st always block.
Based on your modeling with <= in the 1st block, if write_mask1 changes to trigger the sensitivity list, you want to assign data_out1 depending on the old value of write_mask1 at the time point that write_mask1 has been updated with the new value. This behavior is inferred latch, because it needs the memory to hold the old value before the event, but it is also not a valid behavior of a FF. It seems that Verilator interprets this inferred latch still as "blocking assignment". (By the way, latch itself won't cause error, because it is indeed a right way to model if you have latches for purposes like clock gating)
If it is SystemVerilog (instead of Verilog), i would try to use always_comb for combinational logic, and always_ff for sequential. (and always_latch for latch). In your case, the simplest clean way to model is to be aware of which part is combitional and which sequential. I'd model it as:
always_ff #(posedge clk) // to add "or negedge rst_b" if you want async reset
begin
if(!rst_b)
begin
data_out1 <= 32'hxxxxxxxx; // some reset value
end
else if(write_mask1 != 32'b0)
begin
data_out1 <= 32'hxxxxxxxx; // the value you want to update
end
end
// if there is no other condition, it will keep the old value based on the FF behavior
... do something ..
end
If you really mean to have 2 blocks, one doing combinational, one sequential, here we are:
always_comb begin
if(write_mask1 != 32'b0) begin
data_out1_next = 32'hxxxxxxxx;
end
else begin
// now it's necessary to write else-clause because it's not a FF -- it has no memory
data_out1_next = data_out1;
end
end
always_ff #(posedge clk) // to add "or negedge rst_b" if you want async reset
begin
if(!rst_b) begin
data_out1 <= 32'hxxxxxxxx; // some reset value
end
else begin
data_out1 <= data_out1_next;
end
end

Related

Verilog: Re-assigning a variable in an always block

I want to create a logic where I update the value of a register whenever there is a pulse.
In this, I need to update the all the register bits (8) to 1 except for one variable bit (x in below snippet) which needs to be set to 0.
For this I have a simple logic in place but I am not sure if this is synthesizable. I have not run lint yet.
always #(posedge clk or negedge resetn)
begin
if (resetn == 1'b0) begin
mask <= 8'b1;
end
else begin
if (pulse) begin
mask[7:0] <= 8'hFF;
mask[x] <= 1'b0;
end
else
mask[7:0] <= mask[7:0];
end
end
Is this the best way to do it. I don't think so. Please suggest what should be the right way to do it.
Yes, you can make multiple assignments to the same variable (whole or a select of the variable) in the same always block. The last assignment wins.
Also, you should remove the mask[7:0] <= mask[7:0]; statement. It is unnecessary any sequential always block retains the value of any unassigned variable. This dummy assignment can interfere with a testbench's attempt to override the behavior for debugging or error injection.
looks good,
as mentioned you can remove:
else
mask[7:0] <= mask[7:0];
you might consider also adding synchronized reset in a form of "kill" or something so you wouldn't have to use the a-synchronized reset "resetn"

<= Assignment Operator in Verilog

What does the <= do in Verilog?
For example:
always #(posedge Clock) begin
if (Clear) begin
BCD1 <= 0;
BCD0 <= 0;
end
end
"<=" in Verilog is called non-blocking assignment which brings a whole lot of difference than "=" which is called as blocking assignment because of scheduling events in any vendor based simulators.
It is Recommended to use non-blocking assignment for sequential logic and blocking assignment for combinational logic, only then it infers correct hardware logic during synthesis.
Non-blocking statements in sequential block will infer flip flop in actual hardware.
Always remember do not mix blocking and non-blocking in any sequential or combinational block.
During scheduling process of simulator:
There are four regions and order of execution of commands as follows
1) Active region
--Blocking assignments
--Evaluation of RHS of non-blocking assignments(NBA)
--Continuous assignment
--$display command
--Evaluate input and output of primitives
2) Inactive region
--#0 blocking assignments
3) NBA(non-blocking assignment update)
--update LHS of non-blocking assignments (NBA)
4) Postponed
--$monitor command
--$strobe command
Using of blocking assignment "=" for two variable at the same time slot causes race condition
eg: Verilog code with race condition,
always #(posedge Clock)
BCD0 = 0; // Usage of blocking statements should be avoided
always #(posedge Clock)
BCD1 = BCD0;
In order to avoid race condition use non-blocking statement "<="
eg:
always #(posedge Clock)
BCD0 <= 0; // Recommended to use NBA
always #(posedge Clock)
BCD1 <= BCD0;
When this block is executed, there will be two events added to the non blocking assign update queue.
Hence, it does the updation of BCD1 from BCD0 at the end of the time step.
Using Non-blocking "<=" assignment in continuous assignment statement is not allowed according to verilog LRM and will result in compilation error.
eg:
assign BCD0 <= BCD1; //Results in compilation error
Only use NBA in procedural assignment statements,
- initial and
- always blocks
This is called a 'non-blocking' assignment. The non-blocking assignment allows designers to describe a state-machine update without needing to declare and use temporary storage variables.
For example, in this code, when you're using a non-blocking assignment, its action won't be registered until the next clock cycle. This means that the order of the assignments is irrelevant and will produce the same result.
The other assignment operator, '=', is referred to as a blocking assignment. When '=' assignment is used, for the purposes of logic, the target variable is updated immediately.
The understand this more deeply, please look at this example (from Wikipedia):
module toplevel(clock,reset);
input clock;
input reset;
reg flop1;
reg flop2;
always # (posedge reset or posedge clock)
if (reset)
begin
flop1 <= 0;
flop2 <= 1;
end
else
begin
flop1 <= flop2;
flop2 <= flop1;
end
endmodule
In this example, flop1 <= flop2 and flop2 <= flop1 would swap the values of these two regs. But if we used blocking assignment, =, this wouldn't happen and the behavior would be wrong.
Since people have already explained the blocking/non blocking situation, I'll just add this here to help with understanding.
" <= " replaces the word "gets" as you read code
For example :
.... //Verilog code here
A<=B //read it as A gets B
When does A get B? In the given time slot, think of everything in hardware happening in time slots, like a specific sampled event, driven by clock. If the "<=" operator is used in a module with a clock that operates every 5ns, imagine A getting B at the end of that time slot, after every other "blocking" assignments have resolved and at the same time as other non blocking assignments.
I know its confusing, it gets better as you use and mess up bunch of designs and learn how it works that way.
"<=" is a non-blocking assignment operator in verilog."=" is a blocking assignment operator.
Consider the following code..
always#(clk)
begin
a=b;
end
always#(clk)
begin
b=a;
end
The values of a and b are being exchanged using two different always blocks.. Using "=" here caused a race-around condition. ie. both the variables a and b are being changes at the same time..
Using "<=" will avoid the race-around.
always#(clk)
begin
a<=b;
end
always#(clk)
begin
b<=a;
end
Hope i helped too..
<= is a non blocking assignment. The <= statements execute parallely. Think of a pipelined architecture, where we come across using such assignments.
A small exammple:
// initialise a, b, c with 1, 2 and 3 respectively.
initial begin
a <= 1
b <= 2
c <= 3
end
always#(clock.posedge)
begin
a <= b
b <= c
c <= a
end
After the first posedge clock:
a = 2, b = 3, c = 1
After the second posedge clock:
a = 3, b = 1, c = 2
After third posedge clock:
a = 1, b = 2, c = 3
As most told, it is a "Non Blocking <=" assignment widely used for Sequential logic design because it can emulate it best.
Here is why :
Mostly involving a delay(here posedge clock) it is something like it schedules the evaluation of the RHS to LHS after the mentioned delay and moves on to the next statement(emulating sequential) in flow unlike "Blocking = " which will actually delay the execution of the next statement in line with the mentioned delay (emulating combinational)

Verilog: functionality like always & synthesizable

Is there any other functionality like always (that would only run if the sensitive signal changes and won't iterate as long as signal stays the same) which can be cascaded, separately or within the always , but is synthesizable in Verilog.
While I don't think there's a construct specifically like this in Verilog, there is an easy way to do this. If you do an edge detect on the signal you want to be sensitive to, you can just "if" on that in your always block. Like such:
reg event_detected;
reg [WIDTH-1:0] sensitive_last;
always # (posedge clk) begin
if (sensitive_signal != sensitive_last) begin
event_detected <= 1'b1;
end else begin
event_detected <= 1'b0;
end
sensitive_last <= sensitive_signal;
end
// Then, where you want to do things:
always # (posedge clk) begin
if (event_detected ) begin
// Do things here
end
end
The issue with doing things with nested "always" statements is that it isn't immediately obvious how much logic it would synthesize to. Depending on the FPGA or ASIC architecture you would have a relatively large register and extra logic that would be instantiated implicitly, making things like waveform debugging and gate level synthesis difficult (not to mention timing analysis). In a world where every gate/LUT counts, that sort of implicitly defined logic could become a major issue.
The assign statement is the closest to always you you can get. assign can only be for continuous assignment. The left hand side assignment must be a wire; SystemVerilog also allows logic.
I prefer the always block over assign. I find simulations give better performance when signals that usually update at the same time are group together. I believe the optimizer in the synthesizer can does a better job with always, but this might depend on the synthesizer being used.
For synchronous logic you'll need an always block. There is no issue reading hardware switches within the always block. The fpga board may already de-bounce the input for you. If not, then send the input through a two phase pipe line before using it with your code. This helps with potential setup/hold problems.
always #(posedge clk) begin
pre_sync_human_in <= human_in;
sync_human_in <= pre_sync_human_in;
end
always #* begin
//...
case( sync_human_in )
0 : // do this
1 : // do that
// ...
endcase
//...
end
always #(posedge clk) begin
//...
if ( sync_human_in==0 ) begin /* do this */ end
else begin /* else do */ end
//...
end
If you want to do a hand-shake having the state machine wait for a human to enter a multi-bit value, then add to states that wait for the input. One state that waits for not ready (stale bit from previous input), and the other waiting for ready :
always #(posedge clk) begin
case(state)
// ...
PRE_HUMAN_IN :
begin
// ...
state <= WAIT_HUMAN__FOR_NOT_READY;
end
WAIT_HUMAN_FOR_NOT_READY :
begin
// ready bit is still high for the last input, wait for not ready
if (sync_human_in[READ_BIT])
state <= WAIT_HUMAN_FOR_NOT_READY;
else
state <= WAIT_HUMAN_FOR_READY;
end
WAIT_HUMAN_FOR_READY :
begin
// ready bit is low, wait for it to go high before proceeding
if (sync_human_in[READ_BIT])
state <= WORK_WITH_HUMAN_INPUT;
else
state <= WAIT_HUMAN_FOR_READY;
end
// ...
endcase
end

IF with ternary operator - Verilog

I am trying to write a program in Verilog that should "move" a light LED on an array of LEDs. With a button the light should move to the left, with another one it should move to the right. This is my code:
module led_shift(UP, DOWN, RES, CLK, LED);
input UP, DOWN, RES, CLK;
output reg [7:0] LED;
reg [7:0] STATE;
always#(negedge DOWN or negedge UP or negedge RES)
begin
if(!RES)
begin
STATE <= 8'b00010000;
end
else
begin
STATE <= UP ? STATE>>1 : STATE<<1;
end
end
always # (posedge CLK)
begin
LED <= STATE;
end
endmodule
The problem is in STATE <= UP ? STATE>>1 : STATE<<1; and the error the following:
Error (10200): Verilog HDL Conditional Statement error at led_shift.v(34): cannot match operand(s) in the condition to the corresponding edges in the enclosing event control of the always construct
I tried to modify the code without using that kind of if:
always#(negedge DOWN or negedge UP or negedge RES)
begin
if(!RES)
STATE <= 8'b00010000;
else
begin
if(!DOWN)
STATE <= STATE<<1;
else
begin
if(!UP)
STATE <= STATE>>1;
else
STATE <= STATE;
end
end
end
It compiles, but does not work: the LED "moves" only to the left, when I press the other button all LEDs shut down. Probably there is a problem in my code, but I cannot understand why my first code does not compile at all.
Thank you for any help!
harrym
It is not clear for the synthesizer to know how to control STATE with the 3 asynchronous control signals.
Most likely your your synthesizer is trying to map STATE to a D flip flop with asynchronous active low set and reset. For example it might be trying to synthesize to something like:
dff state_0_(.Q(STATE[0], .CLK(DOWN), .SET_N(UP), .RST_N(RES(, .D(/*...*/));
In a real flop with asynchronous set and reset, the default should be consent and would explain the error in your first code. In your second attempt, UP becomes part of the combination logic cloud along with DOWN. DOWN is also being used as a clock. Since UP is not a clock, shifting continuously happens while UP is low, completely shifting the on bit out instantly. Another error for the second case would actually be more appropriate.
For the synthesizer to do a better job, you first need to synchronize your asynchronous control signals. Use the same technique as CDC (clock domain crossing; A paper by Cliff Cummings goes into detains here). A basic example:
always #(posedge clk) begin
pre_sync_DOWN <= DOWN;
sync_DOWN <= pre_sync_DOWN;
end
Now that the controls signals are synchronized, make STATE the output of your combination logic. Example:
always #* begin
if(!sync_RES)
STATE = 8'b00010000;
else
case({sync_UP,sync_DOWN})
2'b01 : STATE = LED>>1;
2'b10 : STATE = LED<<1;
default: STATE = LED;
endcase
end
With everything running on one clock domain and explicitly defined combination logic, the synthesizer can construct equivalent logic using flops and basic gates.
FYI:
To shift only on a negedge event you need to keep the last sync value and check for the high to low transition. Remember to swap sync_ with do_ in the combination logic that drives STATE.
always #(posedge clk)
keep_DOWN <= sync_DOWN;
always #*
do_DOWN = (keep_DOWN && !sync_DOWN);

Verilog code simulates but does not run as predicted on FPGA

I did a behavioral simulation of my code, and it works perfectly. The results are as predicted. When I synthesize my code and upload it to a spartan 3e FPGA and try to analyze using chipscope, the results are not even close to what I would have expected. What have I done incorrectly?
http://pastebin.com/XWMekL7r
Your problem is with lines 13-16, where you set initial values for state registers:
reg [OUTPUT_WIDTH-1:0] previousstate = 0;
reg [OUTPUT_WIDTH-1:0] presentstate = 1;
reg [6:0] fib_number_cnt = 1;
reg [OUTPUT_WIDTH-1:0] nextstate = 1;
This is an equivalent to writing an "initial" statement assigning these values, which isn't synthesizable -- there is no such thing as a default value in hardware. When you put your design inside an FPGA, all of these registers will take on random values.
Instead, you need to initialize these counters/states inside your always block, when reset is high.
always #(posedge clk or posedge reset)
if (reset) begin
previousstate <= 0;
presentstate <= 1;
... etc ...
end
Answer to the follow-up questions:
When you initialize code like that, nothing at all happens in hardware -- it gets completely ignored, just as if you've put in a $display statement. The synthesis tool skips over all simulation-only constructs, while usually giving you some kind of a warning about it (that really depends on the tool).
Now, blocking and non-blocking question requires a very long answer :). I will direct you to this paper from SNUG-2000 which is probably the best paper ever written on the subject. It answers your question, as well as many others on the topic. Afterward, you will understand why using blocking statements in sequential logic is considered bad practice, and why your code works fine with blocking statements anyway.
http://cs.haifa.ac.il/courses/verilog/cummings-nonblocking-snug99.pdf
More answers:
The usual "pattern" to creating logic like yours is to have two always blocks, one defining the logic, and one defining the flops. In the former, you use blocking statements to implement logic, and in the latter you latch in (or reset) the generated value. So, something like this:
wire some_input;
// Main logic (use blocking statements)
reg state, next_state;
always #*
if (reset) next_state = 1'b0;
else begin
// your state logic
if (state) next_state = some_input;
else next_state = 1'b0;
end
// Flops (use non-blocking)
always #(posedge clock)
if (reset) state <= 1'b0;
else state <= next_state;
Note that I'm using a synchronous reset, but you can use async if needed.
Lines 13-16 are correct. "reg [6:0] fib_number_cnt = 1;" is not the same as using "initial" statement. Read Xilinx synthesis guide for more detailed description of how to initialize the registers.

Resources