Synthesis warnings and how to fix them in Verilog - Time & Space Complexity
When we write Verilog code, synthesis tools check it and may give warnings.
We want to understand how these warnings relate to the code's execution steps.
Analyze the time complexity of the following Verilog code snippet.
module counter(input clk, input rst, output reg [3:0] count);
always @(posedge clk or posedge rst) begin
if (rst)
count <= 4'b0000;
else
count <= count + 1;
end
endmodule
This code counts up on each clock cycle and resets when rst is high.
Look for loops or repeated actions in the code.
- Primary operation: The always block triggers on every clock edge.
- How many times: It runs once per clock cycle, repeating indefinitely.
The code runs once every clock cycle, so the number of operations grows linearly with time.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 cycles | 10 updates |
| 100 cycles | 100 updates |
| 1000 cycles | 1000 updates |
Pattern observation: The operations increase directly with the number of clock cycles.
Time Complexity: O(n)
This means the work done grows in a straight line as the input (clock cycles) increases.
[X] Wrong: "Synthesis warnings mean the code runs slower or uses more time steps."
[OK] Correct: Warnings point to potential design issues, not how many times the code runs. The clock cycles still control execution speed.
Understanding synthesis warnings helps you write clear, efficient hardware code and shows you care about quality designs.
"What if we added a nested loop inside the always block? How would the time complexity change?"
Practice
case statements in Verilog?Solution
Step 1: Understand synthesis warnings for
Synthesis tools warn when acasestatementscasestatement does not cover all possible input values, which can cause unintended latches or hardware behavior.Step 2: Reason why incomplete coverage is problematic
If some input values are not handled, the hardware may hold previous values or behave unpredictably, which is why the tool warns.Final Answer:
Because not all possible input cases are covered, which may cause unintended hardware behavior. -> Option DQuick Check:
Incompletecasecoverage = synthesis warning [OK]
case to avoid warnings [OK]- Thinking syntax errors cause incomplete case warnings
- Ignoring default cases in
casestatements - Assuming tools don't check for all input values
Solution
Step 1: Identify unassigned signals in each snippet
module example(input clk, input a, output reg q); always @(posedge clk) q <= a; endmodule assignsqon clock edge, so no unassigned output. module example(input clk, input a, output reg q); always @(posedge clk) ; endmodule has an empty always block, soqis never assigned. module example(input clk, input a, output reg q); reg temp; always @(posedge clk) temp <= a; endmodule assignstempbutqis unassigned output. module example(input clk, input a, output reg q); reg temp; always @(posedge clk) q <= temp; endmodule assignsqfromtemp, buttempis never assigned.Step 2: Determine which code avoids unassigned signals
Only module example(input clk, input a, output reg q); always @(posedge clk) q <= a; endmodule properly assigns the outputqand has no unassigned signals, so no synthesis warning.Final Answer:
module example(input clk, input a, output reg q); always @(posedge clk) q <= a; endmodule -> Option AQuick Check:
All outputs assigned = no warnings [OK]
- Ignoring that outputs must be assigned to avoid warnings
- Assuming internal regs cause warnings if unassigned
- Confusing blocking and non-blocking assignments
module test(input wire [1:0] sel, output reg out);
always @(*) begin
case(sel)
2'b00: out = 1'b0;
2'b01: out = 1'b1;
// Missing cases for 2'b10 and 2'b11
endcase
end
endmoduleSolution
Step 1: Analyze the
Thecasestatement coveragecasecovers only 2 of 4 possible values ofsel. Missing 2'b10 and 2'b11 cases.Step 2: Understand synthesis implications of missing cases
Because not all cases are covered and no default is provided, synthesis infers a latch to holdoutvalue for missing cases, causing a warning.Final Answer:
Warning about incompletecasestatement causing inferred latch. -> Option AQuick Check:
Incompletecase= inferred latch warning [OK]
- Assuming no warning if some cases are missing
- Confusing unused input warnings with case coverage
- Ignoring latch inference from incomplete cases
module fixme(input clk, input a, output reg q);
reg temp;
always @(posedge clk) begin
temp <= a;
end
always @(posedge clk) begin
q <= temp;
end
endmoduleSolution
Step 1: Check signal usage and assignments
tempis assigned fromaon clock edge, thenqis assigned fromtempon next clock edge. Both signals are used properly.Step 2: Verify if multiple drivers or unused signals exist
Only one always block drivestemp, and one drivesq. No multiple drivers or unused signals.Final Answer:
No synthesis warnings; code is correct. -> Option BQuick Check:
All signals assigned and used properly = no warnings [OK]
- Assuming temp is unused because it is intermediate
- Thinking multiple always blocks cause multiple drivers if signals differ
- Ignoring proper signal flow over clock cycles
Solution
Step 1: Understand why inferred latches occur in combinational blocks
If outputs are not assigned in all possible paths, synthesis infers latches to hold previous values, causing warnings.Step 2: Fix by adding default assignments
Assign default values to all outputs at the start of the always block to ensure they are always driven, preventing latch inference.Final Answer:
Add a default assignment to all outputs at the start of the always block. -> Option CQuick Check:
Default assignments prevent inferred latches [OK]
- Thinking sensitivity list affects latch warnings
- Assuming changing output type fixes latch inference
- Removing always block without replacing logic
Ready to prove it?
Pass the test and this pattern moves unknown
