Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.

Pitfall with mixing of blocking and non-blocking assignments in SystemVerilog

Skip to first unread message


Feb 20, 2022, 5:05:24 PM2/20/22
VHDL has a clear distinction between signals and variables. Variables are always updated as soon as we assign a value to them. However, a signal is only updated at the end of the process block.

In Verilog and SystemVerilog there is no distinction like variable and signal found in the VHDL. However, here we have the concept of blocking and non-blocking assignment. The non-blocking assignment behaves like the variable in VHDL while the blocking assignment behaves like the signal in VHDL. Atleast this is my conclusion.

Now the issue is that, it is allowed to mix blocking and non-blocking assignment for the same reg or logic type in Verilog/SystemVerilog. This brings me to my question (about synthesizeable code):

1. I assume that mixing blocking and non-blocking assignments for synthesis code for the same reg or logic type, is a bad idea. Why is it allowed in the language?
2. How does one make sure that mixing of blocking and non-blocking assignment for the same reg or logic type does not happen (by mistake)?
3. Is it a good practice to have blocks of code that combine reg or logic types like we can have signal and variable in the same VHDL process?


Jun 2, 2022, 11:21:08 AM6/2/22
Mixing these assignments in Verilog is often a good idea, despite what people say, because it keeps the relevant code in a single process and makes it easier to follow. Observe these rules:

1. Declare the combinational variable inside the process so it can't be used outside the process.
2. Ensure that it always gets assigned so that latches aren't inferred.
3. Name it with a suffix like "_var".
4. Use blocking assignments for it.

always@(posedge clk) begin
int sum_var; // declare inside
sum_var = 0; // give it a default
for (int kk=0; kk<8; kk++)
sum_var += input_bus[kk]; // blocking assignment
out_reg <= sum_var; // transfer to clocked reg using nonblocking

0 new messages