A combinational block that misses an assignment on some path keeps its old value. The tool builds storage, and timing through it turns murky.
The cure is structural: assign every output on every path, or move the storage into an explicit clocked block.
Shape | Sign | Fix |
|---|---|---|
Missing else or default | Latch cell in the report on a combinational block | Add the missing default assignment. |
Partial case coverage | Latch on one select value only | Cover all values or add a default arm. |
Read-before-write | Feedback loop through the block | Order writes before reads, or register the state. |
A nested if-else chain tests requests one at a time. The last request waits behind every earlier test, so depth grows with the request count.
The runnable Yosys block below builds an 8-request chain and pins its 7 mux stages with an assertion. The balanced depth beside it is hand arithmetic.
read_verilog <<EOV
module prio_chain(input wire [7:0] req, output wire [2:0] idx);
assign idx = req[0] ? 3'd0 : req[1] ? 3'd1 : req[2] ? 3'd2 : req[3] ? 3'd3 : req[4] ? 3'd4 : req[5] ? 3'd5 : req[6] ? 3'd6 : 3'd7;
endmodule
EOV
hierarchy -check -top prio_chain
proc
opt_clean
select -assert-count 7 t:$mux
log PASS: 8-line priority chain holds 7 mux stageschain stages = 8 requests - 1 = 7 mux stages (pinned by the block above)
balanced tree depth = ceil(log2(8)) = 3 stages
saved stages = 7 - 3 = 4 stagesRestructuring into a tree, a case decode, or a one-hot select removes stages. Exact gains vary between tools and libraries.
Two adders that never fire together still cost two adders unless the source shares them. Area reports show the same operator repeated side by side.
Sharing helps only when the operations exclude each other in time. Forcing it elsewhere adds muxing without removing area.
Pattern | Report sign | Fix |
|---|---|---|
Two adds, one per branch | Two adder cells of the same width | Compute once into a shared adder under a select. |
Add then subtract on one path | Chained arithmetic on the worst path | Reorder or pipeline the datapath instead. |
Three stages, since ceil of log2 of 8 is 3. Restructuring can save 4 stages here.
That value has no assignment, so the output must hold state. Cover it with a default or a full case.