When more than one select can be true, hardware must pick a winner. if / else if is a priority mux. unique case says the labels are mutually exclusive.
flowchart LR r3[req3] --> pri[priority_mux] r2[req2] --> pri r1[req1] --> pri r0[req0] --> pri pri --> g[grant]
Priority chain
always_comb begin
grant = 2'd0;
if (req[3]) grant = 2'd3;
else if (req[2]) grant = 2'd2;
else if (req[1]) grant = 2'd1;
else if (req[0]) grant = 2'd0;
end
Earlier branches win. That is correct for interrupt / arbiter style decode.
Wrong vs right
Wrong — overlapping case labels with no unique/priority and no default (latch + X in sim):
always_comb
case (1'b1)
req[1]: grant = 2'd1;
req[0]: grant = 2'd0;
endcase
Right — state the intent:
always_comb begin
grant = 2'd0;
unique case (1'b1)
req[1]: grant = 2'd1;
req[0]: grant = 2'd0;
default: grant = 2'd0;
endcase
end
Use priority case when overlaps are legal and you want the first match. Use unique case when two hits are a bug.