Verilog and bit shifting (‘<<' and '>>’): Don’t push your luck

In Verilog there’s a bit shifter operator, which isn’t used a lot, since FPGA designers prefer to state exact bit vectors. But sometimes bit shifting makes the code significantly more readable. Too bad that Xilinx’ XST synthesizer doesn’t get it right in a specific case.

Namely, the following statement is perfectly legal:

always @(posedge clk)
reduce <= 1 + (end_offset >> (6 + rcb_is_128_bytes - format_shift) );

But it turns out that Xilinx ISE 13.2 XST synthesizer gets confused by the calculation of the shift rate, and creates something wrong. I can’t even tell what it did, but it was wrong.

So the rule is simple: It’s fine to have the shift number being a register (even combinatoric) or a wire, but no inline calculations. So this is fine:

always @(format_shift or rcb_is_128_bytes)
if (rcb_is_128_bytes)
case (format_shift)
0: shifter <= 7;
1: shifter <= 6;
default: shifter <= 5;
case (format_shift)
0: shifter <= 6;
1: shifter <= 5;
default: shifter <= 4;

always @(posedge clk)
reduce <= 1 + (end_offset >> shifter );

(assuming that format_shift goes from zero to 2).

Actually, I would bet that it’s equally fine to calculate the number of shifts and put the result in a wire. I went for the case statement hoping that the synthesizer will take the hint that not all values that fit into the registers are possible, and will hence avoid implementing impossible shift values.

Needless to say, I know about this because something went horribly wrong all of the sudden. I believe XST version 12.2 handled the shift calculation OK. And then people ask me why I don’t like upgrades.

No comments:

Post a Comment

Please provide valuable comments and suggestions for our motivation...

Popular Posts