|
楼主 |
发表于 2009-2-5 11:24:56
|
显示全部楼层
The example below is one of those easy coding mistakes to make in Verilog. Even after using Verilog for more than 20 years, I can still stare at this code for 10 minutes before I see the mistake. The example code is a simple 4 input multipexer. But, when the model is simulated, only the values for the a and b inputs are ever passed to the output. The c and d inputs are never selected, no matter what the value of the select input is. Why?
module mux4to1 (
input [ 1:0] select,
input [31:0] a, b, c, d,
output [31:0] y);
always @(select, a, b, c, d)
case (select)
00: y = a;
01: y = b;
10: y = c;
11: y = d;
endcase
endmodule
Need a hint? Think of the classic engineering joke, "There are 10 types of people in the world, those that know binary and those that don't."
Answer
The problem is that even though we, as engineers, often think in binary or hexadecimal, the default base in Verilog is decimal. The lines in the case statement:
10: y = c;
11: y = d;
are decoding the decimal values of ten and eleven, not the binary values of two and three. Since the select variable is only two bits wide, it cannot store a value of ten (1010 in binary) or eleven (1011 in binary). Therefore, the c and d inputs of the mux will never be selected and assigned to the y output. Gotcha!
The correct code for this case statement is to specify binary values, as shown below:
always @(select, a, b, c, d)
case (select)
2'b00: y = a;
2'b01: y = b;
2'b10: y = c;
2'b11: y = d;
endcase
The faulty model will get warning messages from lint programs (coding style checkers) and synthesis compilers. The warning will be that there is a size mismatch between the select input (2 bits wide) and the sizes of the case expressions (32 bits). These warnings give a clue that something is wrong, but the coding error is still not obvious.
SystemVerilog has a construct that is useful for this example. The "unique case" and "priority case" statements will cause a run-time warning message to be generated any time a case statement is entered and none of the case expressions match. In SystemVerilog, the following code would generate an warning message each time select has value of two or three:
always_comb
unique case (select)
00: y = a;
01: y = b;
10: y = c;
11: y = d;
endcase
But be careful! Using "unique" and "priority" case statements would be the right thing to do in this 4-to-1 mux example, but it is not the right thing for every case statement. These constructs can affect how the model will be synthesized, and the effect might not be what you want in your hardware design. But that is a topic for some future Quiz and Tip (and a good reason to take a good SystemVerilog training course)! |
|