Can you replicate, concatenate a '?' literal somehow? It seems my tools accept it.
Most direct answer: Section 3.5 Numbers of 1364-2005 has a stanza for 'z_digits'. z_digit ::= z | Z | ?
, so it is fine to use either '?' or 'z' as they are equivalent.
I have a list of bits. The text 'EV#' is some appropriately named event. Like ON_HOOK, OFF_HOOK or whatever. Several events are arriving and the intent is to prioritize the translation and insertion to a fifo. My initial coding transposition to stackoverflow has some errors which have been corrected. The code here is intended to be minimal example. Apologies for any confusing in the editing/transposition here.
localparam BIT_EV0 = 0;
localparam BIT_EV1 = 1;
localparam BIT_EV2 = 2;
localparam BIT_EV3 = 3;
localparam BIT_MAX = 4; // Register size.
reg [BIT_MAX-1:0] event_queue;
I would like to define a case constants such as,
`define CASE_VALUE(bit) {{BIT_MAX-bit-1{1'b0}}, 1'b1, {bit{1'b?}}}
localparam [BIT_MAX-1:0] PRI_EV0 = `CASE_VALUE(BIT_EV0);
localparam [BIT_MAX-1:0] PRI_EV1 = `CASE_VALUE(BIT_EV1);
localparam [BIT_MAX-1:0] PRI_EV2 = `CASE_VALUE(BIT_EV2);
localparam [BIT_MAX-1:0] PRI_EV3 = `CASE_VALUE(BIT_EV3);
`undef CASE_VALUE
So that I can construct,
casez(event_queue)
PRI_EV0: ;
PRI_EV1: ;
PRI_EV2: ;
PRI_EV3: ;
/* etc. */
default: ;
endcase
Events are set/cleared with event_queue[BIT_EVx] = 1'b0;
Now, I have to explicitly type the case constants and update all of them when adding and removing a new event bit. Prior was written without the understanding that 1'b?
may exist. The case labels have actions which are not numerically constructed. They aggregate data for a destination message queue/fifo.
Interestingly, I can use a local parameter like,
localparam [BIT_MAX-1:0] PRI_EV2 = 4'b01??;
So the only issue is specifying a '?' constant, which seems to work with 1'b?
, but I was not aware that this was a language construct and had never seen it mentioned in replication and concatenation. It tried to trace the 2001 standard and got stuck with 'constant_expression'.
I am trying to restrict to Verilog-2001.
You should use casez
to support wildcards. You can use z
to represent the don't care bits.
IEEE1364-2001 § 9.5.1 Case statement with don’t-cares
Don’t-care values (z values for casez, z and x values for casex) in any bit of either the case expression or the case items shall be treated as don’t-care conditions during the comparison, and that bit position shall not be considered.
Equivalent statement in latest SystemVerilog IEEE1800-2023 § 12.5.1 Case statement with do-not-cares
Tested with iverilog on EDAplayground https://www.edaplayground.com/x/DxKz
module tb;
localparam BIT_EV0 = 0;
localparam BIT_EV1 = 1;
localparam BIT_EV2 = 2;
localparam BIT_EV3 = 3;
localparam BIT_MAX = 4; // Register size.
reg [BIT_MAX-1:0] event_queue;
localparam [BIT_MAX-1:0] PRI_EV2 = {{BIT_MAX-BIT_EV2-1{1'b0}}, 1'b1, {BIT_EV2{1'bz}}}; // z for wildcard
always @* begin
casez(event_queue)
PRI_EV2: $display("in PRI_EV2 with event_queue=%b", event_queue);
/* etc. */
default: $display("in default with event_queue=%b", event_queue);
endcase
end
integer i;
initial begin
for(i=0; i<2**BIT_MAX; i=i+1)
#1 event_queue = i;
#2 $finish;
end
endmodule
Alternate solution if one priority bit is expected is to use case(1'b1)
case(1'b1) // Note: inline synthesis priority/parallel flag may be needed
event_queue[BIT_EV3]: ; // highest priority
event_queue[BIT_EV2]: ;
event_queue[BIT_EV1]: ;
event_queue[BIT_EV0]: ; // lower priority
default: // catch-all , lowest priority
endcase
I see in the LRMs case(1)
should work the same as case(1'b1)
. My experience over the years with a several Verilog simulators is case(1)
always hit the default
condition. The case(1'b1)
works as expected on all simulators.