I wrote simple code to check if the module function is correct or not.
I tried to input 4 different inputs to check the module's output, but the output is always the first input's result. I have no idea why it is happened.
The following is my module:
module encoder (
input [3:0] in,
output reg [2:0] pos );
always @(*) begin
casez (in)
4'bzzz1: pos = 1;
4'bzz1z: pos = 2;
4'bz1zz: pos = 3;
4'b1zzz: pos = 4;
default: pos = 0;
endcase
end
endmodule
I use the following testbench:
module main();
reg [3:0] in;
wire [2:0] pos;
encoder e(in,pos);
initial begin
#5 in = 4'bzzz1;
#5 in = 4'bzz1z;
#5 in = 4'bz1zz;
#5 in = 4'b1zzz;
#20;
$finish;
end
initial $monitor($time,"in=%b, pos=%b",in ,pos);
endmodule
But, pos
always prints 001
when I simulate it.
The following is what I expect it to print:
0 in=XXXX, pos=XXX
5 in=zzz1, pos=001
5 in=zz1z, pos=010
5 in=z1zz, pos=011
5 in=1zzz, pos=100
May someone tell me where I am wrong?
When I run your code, I get this output:
0in=xxxx, pos=xxx
5in=zzz1, pos=001
10in=zz1z, pos=001
15in=z1zz, pos=001
20in=1zzz, pos=001
pos
is always 1 because the 1st case
item always matches your input value (in
). This is due to the z
bits in your input and the z
bits in your case items.
Refer to IEEE Std 1800-2017, section 12.5.1 Case statement with do-not-cares:
Do-not-care values (
z
values for casez ,z
andx
values for casex ) in any bit of either the case_expression or the case_items shall be treated as do-not-care conditions during the comparison, and that bit position shall not be considered.
The case
statement starts by checking the case_expression (in
) against the 1st case_item, which is 4'bzzz1
. For the comparison, since bit 0 of the case_item is 1, the comparison will always match no matter what the value of in[0]
is. No other case_item comparisons are ever done.
If I change casez
to case
, then I get the expected output:
0in=xxxx, pos=xxx
5in=zzz1, pos=001
10in=zz1z, pos=010
15in=z1zz, pos=011
20in=1zzz, pos=100
However, I don't think this is what you want. It is not customary to drive inputs with z
bits. It is more customary to drive known values. This should work better for you:
module encoder (
input [3:0] in,
output reg [2:0] pos
);
always @(*) begin
casez (in)
4'b???1: pos = 1;
4'b??1?: pos = 2;
4'b?1??: pos = 3;
4'b1???: pos = 4;
default: pos = 0;
endcase
end
endmodule
module main;
reg [3:0] in;
wire [2:0] pos;
encoder e (in, pos);
initial begin
$monitor($time,, "in=%b, pos=%d", in, pos);
repeat (30) #5 in = $random;
#20 $finish;
end
endmodule
Prints:
0 in=xxxx, pos=x
5 in=0100, pos=3
10 in=0001, pos=1
15 in=1001, pos=1
20 in=0011, pos=1
25 in=1101, pos=1
35 in=0101, pos=1
40 in=0010, pos=2
45 in=0001, pos=1
50 in=1101, pos=1
55 in=0110, pos=2
60 in=1101, pos=1
70 in=1100, pos=3
75 in=1001, pos=1
80 in=0110, pos=2
85 in=0101, pos=1
90 in=1010, pos=2
95 in=0101, pos=1
100 in=0111, pos=1
105 in=0010, pos=2
110 in=1111, pos=1
115 in=0010, pos=2
120 in=1110, pos=2
125 in=1000, pos=4
130 in=0101, pos=1
135 in=1100, pos=3
140 in=1101, pos=1
150 in=0101, pos=1
In the casez
case items, it is more common to use ?
instead of z
, although either will work.