Latch inference and how to avoid it in Verilog - Time & Space Complexity
When writing Verilog, sometimes unintended latches are created. This affects how the hardware behaves and how long it takes to run.
We want to understand how the design's execution steps grow when latches appear or are avoided.
Analyze the time complexity of this Verilog code that may cause latch inference.
always @(*) begin
if (enable) begin
out = in1;
end else begin
out = out; // Explicitly hold value to avoid latch
end
end
This code assigns out only when enable is true, otherwise it keeps previous value, causing a latch.
Look for repeated actions that affect timing.
- Primary operation: The conditional check inside the always block runs every time inputs change.
- How many times: This check happens continuously as signals change, but the latch holds state without extra operations.
Consider how the hardware reacts as input signals increase.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 conditional checks, latch holds state |
| 100 | 100 conditional checks, latch holds state |
| 1000 | 1000 conditional checks, latch holds state |
Pattern observation: The number of checks grows linearly with input changes, but the latch itself does not add extra operations.
Time Complexity: O(n)
This means the number of operations grows linearly with the number of input changes, but the latch holds state without extra repeated work.
[X] Wrong: "Leaving out an else branch won't affect timing or hardware behavior."
[OK] Correct: Missing else causes latch inference, which changes hardware behavior and can cause unexpected delays or bugs.
Understanding latch inference shows you know how hardware timing and behavior relate to code. This skill helps you write clear, predictable designs.
"What if we add an else branch that assigns a default value? How would the time complexity change?"
Practice
Solution
Step 1: Understand latch inference context
Latch inference occurs when outputs inside combinational blocks are not assigned in every possible condition.Step 2: Identify cause of latch inference
If an output is missing assignment in some branches, Verilog infers a latch to hold the previous value.Final Answer:
Not assigning output signals in all possible conditions -> Option DQuick Check:
Missing assignments cause latch inference [OK]
- Thinking clocked blocks cause latch inference
- Believing non-blocking assignments cause latches
- Ignoring missing else branches
Solution
Step 1: Check for default assignment
always @(*) begin out = 0; if (sel) out = 1; end assigns a default value to 'out' before conditional checks, preventing latch inference.Step 2: Compare other options
always @(*) begin if (sel) out = 1; end misses assignment when 'sel' is false, causing latch. always @(posedge clk) begin if (sel) out <= 1; end is clocked, not combinational. always @(*) begin if (sel) out = 1; else if (sel) out = 0; end misses assignment when 'sel' is false since both conditions require sel true, causing latch.Final Answer:
Assigning default value before conditions to avoid latches -> Option AQuick Check:
Default assignment prevents latch [OK]
- Omitting default assignments
- Confusing clocked and combinational blocks
- Using incomplete else branches
always @(*) begin if (a) out = 1; else if (b) out = 0; // no assignment if neither a nor b end
Solution
Step 1: Analyze assignment coverage
The code assigns 'out' only when 'a' or 'b' is true; no assignment otherwise.Step 2: Understand latch inference
Missing assignment in some conditions causes Verilog to infer a latch to hold the last value.Final Answer:
Latch inferred to hold previous value when neither a nor b is true -> Option AQuick Check:
Missing else branch causes latch [OK]
- Assuming no latch because of if-else
- Confusing latch with flip-flop
- Thinking synthesis error occurs
always @(*) begin if (enable) out = data; // no else branch endHow can it be fixed?
Solution
Step 1: Identify missing assignment
The code assigns 'out' only when 'enable' is true; no assignment otherwise causes latch.Step 2: Fix by adding else branch
Adding an else branch with a default assignment ensures 'out' is assigned in all cases, avoiding latch.Final Answer:
Add an else branch assigning a default value to 'out' -> Option CQuick Check:
Complete assignments prevent latch [OK]
- Thinking clocked block fixes latch in combinational logic
- Ignoring missing else branch
- Confusing blocking and non-blocking assignments
always @(*) begin
case ({x,y})
2'b00: result = 0;
2'b01: result = 1;
2'b10: result = 1;
// missing 2'b11 case
endcase
endSolution
Step 1: Identify incomplete case coverage
The case statement misses the 2'b11 input combination, so 'result' is not assigned in that case.Step 2: Add default case to assign 'result'
Adding a default case ensures 'result' is assigned for all inputs, preventing latch inference.Final Answer:
Add a default case assigning 'result' a value -> Option BQuick Check:
Complete case coverage avoids latch [OK]
- Assuming missing case won't cause latch
- Switching to clocked block unnecessarily
- Ignoring default case importance
Ready to prove it?
Pass the test and this pattern moves unknown
