Illegal range in part select

I have below code.


task my_check(bit [19:0] addr, bit [31:0] expect_data, int shift, int width);
    bit [31:0] my_data;
    int msb = shift+width-1;
    int lsb = shift;
    my_env.my_ral_mdl.read(status, value, UVM_BACKDOOR);       // use ral backdoor method to read register
    my_data = value[msb:lsb];
    ......
endtask

but hit below error.

Error-[IRIPS] Illegal range in part select
The range of the part select is illegal:
Unknown range in part select.this.value[msb:lsb]

Thanks in advance for any help on this issue.

In reply to zz8318:

I don’t think we can use variables in both [msb:lsb] for range select , but plz see if below solution might help

task my_check(bit [19:0] addr, bit [31:0] expect_data, int shift, int width);
    bit [31:0] my_data;
    bit [31:0] local_my_data;
    int msb = shift+width-1;
    int lsb = shift;
    for(int i=0; i < width; i++) local_my_data[i] = 1'b1;
    my_env.my_ral_mdl.read(status, value, UVM_BACKDOOR);       // use ral backdoor method to read register
    my_data = (value >> lsb) & local_my_data;
    ......
endtask

In reply to zz8318:

Variable slicing is not allowed in sv bit locations have to be constant. Of you explain what you are planning to achieve maybe we could give a fix.

If you are just planning to compare exp_data with data you do not need to slice it. Anyway woth regards of register access usually fields are compared eachother so it might depend on the result you are trying to get.

Do you wanna compare fields? Do you wanna compare just random bits? Regards

In reply to Rsignori92:

I would need to compare the variant bits in each cases. (it’s not random but it’s not constant also)

In reply to Desam:

Yes, this is what I tried before and it works. But I am thinking if there is any better solution for this so I ask it here. Thank you.

In reply to zz8318:

What do you mean by variant bits ?

Anyway you can always create a mask like:

Mask = {width{1’b1}}; // init to zero initially

Then shift to the lsb: mask = mask << lasb.

After you will be & the result to get the desiderd values.

Regards

In reply to Rsignori92:

everytime when we call this task the shift and width are changed. anyway, I use the original method to make it pass. thanks everyone for your great help

In reply to zz8318:

Sorry then why the proposed method won’t work? I might’ve missed some datails probably

In reply to Rsignori92:

your proposed method also works.

module tb;
  int splitbit;
  bit [35:0] address = 35'h123456789;
  bit [35:0] arranged_addr;

  initial begin
    splitbit = $urandom_range(1, 31);
    $display("SPLITBIT=%0d", splitbit);
    
    
    arranged_addr[35:31] = address[(splitbit+4) -: 5];
    arranged_addr[30:0] = {address[35 : (splitbit + 5)], address[(splitbit - 1) : 0]};
    $display("arranged_addr=%b",arranged_addr);
  end
endmodule

My requirement is that the splitbit signal in this code randomly range from 1 to 31. and I’m rearranging address bits based on the splitbit value. since I wish to move five bits from the splitbit value in the arranged_addr’s MSB. if the splibit value is randomized to 10 then, arranged_addr[35:31] = address[14:10] and arranged_addr[30:0] = {address[35:15], address[9:0]} .

Although you could probably do this in a single expression of shifts and masks, it’s probably much easier to understand and maintain as a for loop.

for(int i=0;i<31;i++)
  arranged_addr[i] = i<splitbit ? address[i] : address[i+5];