Weixu Pan
Weixu Pan

Reputation: 71

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?

Upvotes: 1

Views: 4063

Answers (1)

Serge
Serge

Reputation: 12384

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

Upvotes: 1

Related Questions