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

This post was written by eli on December 19, 2011
Posted Under: FPGA

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.

reduce_header_credits <= 1 + (effective_end_offset >> (6 + rcb_is_128_bytes – recvbuf_format_shift) )

Reader Comments

Good point. It is always best not to confuse XST. What is the declaration of the reduce register in your example?

Written By Andy on January 13th, 2012 @ 02:40

Actually, I don’t think this should have confused the synthesizer.

The format_shift was either a wire or register with two bits. That’s all.

Written By eli on January 13th, 2012 @ 11:08

Add a Comment

required, use real name
required, will not be published
optional, your blog address