??? 10/17/07 00:21 Read: times |
#145831 - challenge Responding to: ???'s previous message |
Russ Cooper said:
For reference: case (in) 8'b00110001: out = 2'b01; 8'b10101100: out = 2'b10; 8'b11110101: out = 2'b11; default: out = 2'dx; endcaseMaybe my problem is that I have a faulty understanding of what it means in Verilog to say "out = 2'dx;" In any case, I think we can get to the bottom of this if you will undertake this challenge: Please give an input vector where the above circuit doesn't do what the Verilog code says, and explain how the circuit needs to be modified to work correctly for that vector. I think I see the problem. You have a faulty understanding of what it means in Verilog to say, out = 2'dx, when used as a default in a case statement ;) and case doesn't work the way you think it works. First and foremost, assigning an x to a wire or reg is NOT the same thing as assigning it a "don't care." x means "unknown." (For instance, you could care that you don't know the value.) Unknown may mean that it has not been initialized, or there's a conflict (two drivers trying to drive different values onto the same net). Clearly in your three specific patterns, one can map in[7] to out[1] and in[0] to out[0]. But that would only work if all of the other bits in your patterns were the same. (Draw it out! Simulate it!) But that also doesn't matter because that's not how a case statement works. So to answer your challenge: if in is assigned the value 8'b00000000, none of the three cases specified matches, so the output vector out is assigned 2'bxx. Why? Because you are telling it to do so. default simply says, "if none of the specific case patterns match, then do this." With your case statement, you are specifying that when in matches a particular 8-bit pattern, out gets assigned a specific two-bit value. You have defined only three patterns to match. Nothing else matches, and when nothing else matches, you're explicit about it by forcing out to be unknown. But, as I said, unknown is not don't-care! I think you really want to specify specific bits in your case patterns as don't-cares, not the default. As such, you need to use the casex statement, not case. Consider: casex (in) 8'b0xxxxxx1 : 2'b01; 8'b1xxxxxx0 : 2'b10; 8'b1xxxxxx1 : 2'b11; default : 2'b00; // must specify endcase;Think carefully about this. casex is a special case of case. Note that above, I wrote that x is not a don't-care. Using casex lets you consider that, yes, an x DOES indicate don't-care. If you do NOT specify casex instead of case, none of three specific cases shown will match. Why? Normally, any expression which includes an unknown (x) will evaluate to unknown. For example, if you have an expression assign foo = bar & bletch;and bar was assigned 1'b1 and bletch is unknown, then foo will be assigned unknown (actually, since it's a driven net, it will be assigned a "strong unknown"). Similarly, if a case pattern in a case statement includes unknowns, like 8'b1xxxxxx0, then unless the vector in has unknowns -- x -- in bits [6:1], then you will NOT get a match and the default case is selected. When an x occurs in a case pattern in a casex statement, it means that part of the pattern doesn't matter and always matches the selector. In other words, a true don't-care. In the above casex statement, if you changed the default case assignment from 2'b00 to 2'bxx, then when both in[7] and in[0] are both 0, then out gets assigned XX. And that's probably not what you want ... I hope this helps clear things up! -a |