verilogsystem-verilog

How to fix this part-select error? Illegal operand for constant expression


I'm having a input called tx_empty, and 255 bits data. My code is:

assign lastIndex  = (tx_eop)?  (tx_empty + 3'd4)*8 : lastIndex_xq;
wire [255:0] tmp1 = tx_data_xq[(tx_empty - 5'd16)*8-1 : 0];
wire [255:0] tmp2 = tx_data_xq[255:lastIndex];
wire [255:0] tmp3 = tx_data_xq[lastIndex +: 7'd96];

tx_empty is the input signal of this module, and "lastIndex_xq" is just the output of the D register of lastIndex. I want to change the index value when tx_eop is high.

tmp3 works fine. I'm getting error like "Illegal operand for constant expression" for tmp1 and tmp2, I know tmp2 is wrong because I cannot have a variable on the right hand side of a : in a part select. But how about tmp1? I have to use this part-select logic, is there any other way to do it?


Solution

  • verilog does not allow you to use variable widths in part select. Width must always be a constant. In your case it is not, because of tx_emtpty and last_index.

    However, you can use bit shifts, masks and loops to handle it. Something like the following.

    reg [255:0] mask1, mask2;
    reg [255:0] tmp1, tmp2;
    always @* begin
        // create mask of '1' of the required width
        mask1 = (256'b1 << (tx_empty - 5'd16)*8) - 1;
        tmp1 = tx_data_xq & mask1;
        mask2 = ~((256'b1 << lastIndex) - 1);
        tmp2 = (tx_data_xq & mask2) >> lastIndex;
    end