Illegal range in part select

I have created one task in which I am passing msb, lsb and w_data as an argument, and this task will do read modify write. For variable data we want to modify its bits from msb to lsb.

I am getting error as Illega range in part select. Here is the code below.


module tb;
  reg [31:0] data = 32'hA5A5; // Initial data

  // Read-Modify-Write function for part selection
    
  task rmw(int msb, int lsb, int wdata);
    bit [31:0] read_value;
    read_value[msb:lsb] = wdata;

    
    //data = {data[31:(msb+1'b1)],temp,data[lsb-1:0]};
    data = {data[31:(msb+1'b1)],read_value,data[lsb-1:0]};

  endtask

  initial begin
    $display("Initial data: 32'h%h", data);

    // Call the RMW function
    rmw(7,4,'hAB);

    $display("Modified data: 32'h%h", data);

    $finish;
  end
endmodule

Is there any alternative solution for this problem?

Thanks.

In reply to Abuzar Gaffari:

The concatenation you wrote would be more than 32 bits assigning to data. You need to create a mask to select the bits you want inserted.

module tb;
  reg [31:0] data = 32'hA5A5_A5A5; // Initial data
 
  // Read-Modify-Write function for part selection
 
  task rmw(int msb, int lsb, int wdata);
    bit [32:0] mask; // need one extra bit when msb-lsb = 32
    mask = ((33'h2 << msb-lsb)-1)<<lsb;
    wdata <<= lsb;
    data = data & ~mask | wdata & mask;
  endtask
 
  initial begin
    $display("Initial data: 32'h%h", data);
 
    // Call the RMW function
    rmw(11,4,'hCC);
 
    $display("Modified data: 32'h%h", data);
 
    $finish;
  end
endmodule