Search code examples
verilogxilinx

Slice implicit bus in verilog


I am using Xilinx ISim (ISE)

I have the following assign statement:

assign dwToAlign = {first_aligned >> 3}[7:0]  - {i_address >> 3}[7:0];

When I try to do a behavioral simulation, it throws an internal compiler error. If I comment this specific line, it compiles properly. I am certain that the exact same code compiled yesterday (I commited it to my git repo).

If I synthesize and then do a post-pnr simulation, the code synthesizes and simulates properly.

Is this valid verilog?

EDIT: Code on EDAPlayground http://www.edaplayground.com/x/3wW


Solution

  • No it is not valid. Your example uses {} concatenation operators I think you should just be using brackets ().

    If you need to use part selects then declare the shifts first. It is all combinatorial logic and will result in the same hardware.

    assign temp1     = (first_aligned >> 3);
    assign temp2     = (i_address >> 3);
    assign dwToAlign = temp1[7:0]  - temp2[7:0];
    

    It is worth noting that signed arithmetic will be ignored if part-selects are used, even if the full range is specified.

    ie if temp1 and temp2 are declared as wire signed [7:0] temp1 when you access temp1[7:0] the signed property is ignored. If it is required you can force it using $signed( temp1[7:0] ). Signed shifts (>>>) be used as with signed data types if you need to preserve the sign info.

    The OP has also left in the comments that for their case they could also just use:

    assign dwToAlign = first_aligned[10:3] - i_address[10:3];