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:
- An
ifstatement does not have anelse. - A
casestatement does not cover all possible values (and nodefaultis provided). - 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.