Procedural Blocks & Races

01

What is the difference between Blocking (=) and Non-Blocking (<=) assignments?

+

This is the most fundamental question in Verilog.

  • Blocking (=): Executed sequentially. The next statement waits until the current assignment is complete. It behaves like software code. Used for Combinational logic.
  • Non-Blocking (<=)< /strong>: Executed concurrently. The RHS is evaluated immediately, but the LHS is updated at the end of the time step. All concurrent statements update "in parallel". Used for Sequential logic (Flip-flops).
Example: Race Condition vs Hardware
// Blocking (Combinational)
always @(*) begin
    a = b & c;
    d = a | e;  // Uses NEW value of 'a' immediately
end

// Non-Blocking (Sequential)
always @(posedge clk) begin
    q1 <= d;    // q1 gets old 'd'
    q2 <= q1;   // q2 gets OLD 'q1' (Shift register behavior)
end
02

Comparison between 'initial' and 'always' blocks?

+
  • initial: Starts at time 0, executes once, and then stops. Not synthesizable (used for Testbenches).
  • always: Starts at time 0, executes repeatedly forever. Synthesizable (used for Design and Clock generation).
03

How is an unwanted latch inferred?

+

A latch is inferred in combinational logic when:

  1. An if statement does not have an else.
  2. A case statement does not cover all possible values (and no default is provided).
  3. A variable is not assigned a value in one of the branches.

This causes the hardware to "remember" the old value, creating a latch, which often causes timing issues.

04

What is a Verilog Race Condition? Give an example.

+

A race condition occurs when the simulation result depends on the order of execution of concurrent blocks, which is non-deterministic.

Example: Two `always` blocks writing/reading the same variable at the same time using blocking assignments.

// Race Condition!
always @(posedge clk) a = 1;
always @(posedge clk) b = a; 
// Will 'b' get the OLD 'a' or the NEW 'a'? It's undefined!
// Solution: Use Non-Blocking (<=) for sequential logic.