### casez and casex

In addition to the regular case statements, verilog provides two variations casez and casex. Before we try to understand casex and casez, we need to understand that there are 4 types of logic levels and in verilog

0 - logic zero
1 - logic one,
z - high impedance state.
x - unknown logic value - can be 0,1,z or transition.

In normal case statement, the case expression needs to EXACTLY match, for one of the case statements to execute. There is no provision of Don't cares.

casez solves this problem by allowing dont cares. If there is a z or ? in the case expression, then it means that the expression can match to 0, 1 or z.

A very good example is the priority encoder. A common use of priority encoders is for interrupt controllers, where we select the most critical out of multiple interrupt requests.

Here is the truth table and block diagram of a 4 input and 3 output priority encodr.

 `// Referencedesigner.com // Priority Encoder Example - Usage of casez// Verilog Tutorial  module priory_encoder_casez(input wire [4:1] A,output reg [2:0] pcode );always @ * casez (A)4'b1zzz :pcode = 3'b100;4'b01zz :pcode = 3'b011 ;4'b001z :pcode = 3'b010;4'b0001 :pcode = 3'b001;4'b0000 : pcode = 3'b000;endcase endmodule `

Note the statement

``` 4'b1zzz : pcode = 3'b100; ```

It means that we don't care if the bits [2:0] are 0, 1 or z. The above statement could also be written as

``` 4'b1??? : pcode = 3'b100; ```

We now suggest that you write a test bench for this code and verify that it works. If you have difficulty, you can check it with following test bench

 ` `timescale 1ns / 1psmodule stimulus; reg [4:1] A; wire [2:0] pcode; // Instantiate the Unit Under Test (UUT) priory_encoder_casez uut ( .A(A), .pcode(pcode) );  initial begin // Initialize Inputs A = 4'b0000;   #20 A = 4'b0001; #20 A = 4'b0010; #20 A = 4'b0011; #20 A = 4'b0100; #20 A = 4'b0101; #20 A = 4'b0110; #20 A = 4'b0111; #20 A = 4'b1000; #20 A = 4'b1001; #20 A = 4'b1010; #20 A = 4'b1011; #20 A = 4'b1100; #20 A = 4'b1101; #20 A = 4'b1110; #20 A = 4'b1111; #40 ;  end   initial begin \$monitor("t=%3d A=%4b,pcode=%3b",\$time,A,pcode ); end endmodule  `

As another example consider a multiplexer, that has 4 input bits and one output bit. The output is connected to one of the inputs depending upon the value of the input bits. Normally you will need only 2 select bits but we have used 3 select bits. Why ?

 `// Reference Designer.com mux example // usage of casez don't care module mux4to1(sel, a0, a1, a2, a3, out); input [2:0] sel; input [3:0] a0, a1, a2, a3; output reg[3:0] c;  always @(sel or a0 or a1 or a2 or a3) begin casez(sel) 3'b000: out = a0; 3'b001: out = a1; 3'b010: out = a2; 3'b011: out = a3; 3'b1??: out = 4'b0000; endcase endendmodule`

If the MSB select bit is 1, the output is forced to 0 no matter what.

Another thing to notice is that, when more there is more than one match, the first match takes effect. Let us say we have the code.
 `module casez_priority1; reg select; always @ (select)casez (select) 1'bz : \$display("CASEZ : Logic z on select"); 1'b1 : \$display("CASEZ : Logic 1 on select"); 1'b0 : \$display("CASEZ : Logic 0 on select");  endcase  initial begin #1 \$display ("\nDriving 0"); select = 1'b0; #1 \$display ("\nDriving 1"); select = 1'b1; #1 \$display ("\nDriving z"); select = 1'bz; #1 #1 \$finish;end  endmodule`

It gives the following output

``` Driving 0 CASEZ : Logic z on select Driving 1 CASEZ : Logic z on select Driving z CASEZ : Logic z on select ```

The reason is that the first case statement

``` 1'bz : \$display("CASEZ : Logic z on select"); ```

which is equivalent to

``` 1'b? : \$display("CASEZ : Logic z on select"); ```

gets selected no matter what the dont care input is - 0,1 or z

However, if we change the order of the case assignment statement as in

 `module casez_priority1; reg select; always @ (select)casez (select) 1'b1 : \$display("CASEZ : Logic 1 on select"); 1'b0 : \$display("CASEZ : Logic 0 on select"); 1'bz : \$display("CASEZ : Logic z on select");  endcase  initial begin #1 \$display ("\nDriving 0"); select = 1'b0; #1 \$display ("\nDriving 1"); select = 1'b1; #1 \$display ("\nDriving z"); select = 1'bz; #1 #1 \$finish;end  endmodule`

The output changes to ``` Driving 0 CASEZ : Logic 0 on select Driving 1 CASEZ : Logic 1 on select Driving z CASEZ : Logic 1 on select ```

The casex is same as the casez execpt that the don't care also include x in addition to 0,1 and z. This is usually helpful in simulation, when we can give out value x to the module and test for the output.

 Exercise

1. .