Hi All,
I have a 128-bit AXI interface which supports Sparse Writes. Although as per AXI protocol each bit of WStrb corresponds to 1 byte of write data bus, in our case WStrb operates on DWord ( 32-bit ) granularity.
So essentially each 4-bit WStrb would be 4’h0 or 4’hF.
An additional requirement is that "strobes can’t be discontinuous meaning that we can’t have WStrb as 16’hF0F0" i.e we can’ have a 0 between 2 F’s
Eg: 16’hF0F0 would be illegal whereas 16’h0FF0 , 16’hFFF0 would be legal
Here is my attempt
task write_data_axi(input longint my_addr, input bit [127:0] data_in[],input bit[3:0] awlen,output bit[3:0] DWord_strobe[],input bit rand_addr = 1);
bit [3:0] Dword_strb[];
if($test$plusargs("SPARSE_WRITES")) begin
Dword_strb = new[4*data_in.size()]; // For 128-bit Wdata there would be 4 DWords, For 2 beats ( each of 128-bit WData ) there would be 8 DWords
if( !( std::randomize(Dword_strb) with { foreach(Dword_strb[i]) Dword_strb[i] inside { 4'h0 , 4'hF }; } ) )
`uvm_warning(get_type_name(),$sformatf("Randomization failed for Dword_strb"))
else
`uvm_info(get_type_name(),$sformatf("For Sparse Writes,using DWord Strobe as %0p",Dword_strb),UVM_LOW)
DWord_strobe = Dword_strb;
end
.......................
endtask
The above in-line constraint only constraints each nibble of WStrb to either 4’h0 or 4’hF.
I am seeking suggestions to constraint as per “strobes can’t be discontinuous”
One possible solution is that I have a queue ‘valid_q’ ( each element is 16-bit wide ) of all valid combinations and I constraint
Any possible alternative solution without using non-random array ?
( Curious if there is a possible solution using iterative constraint like sum()/and() )
class non_sparse_strb models a non-sparse strobe signal (w_strb) that marks valid portions of dynamically sized data_in. The constraints ensure data_in scales between 128*1 and 128*8 bits while maintaining proper mapping to w_strb. valid_bytes controls how many dwords (32-bit chunks) are valid, and offset_start defines their starting position within bounds. The post_randomize function resets w_strb before correctly marking valid positions.
class non_sparse_strb;
rand bit w_strb[];
randc int valid_bytes;
rand int offset_start;
rand bit [127:0] data_in[];
constraint c_strb {
data_in.size() inside {[1:8]};
w_strb.size() == 4 * data_in.size();
valid_bytes inside {[1:w_strb.size()]};
offset_start inside {[0:w_strb.size() - valid_bytes]};
}
function void post_randomize();
w_strb = '{default: 0};
for (int i = offset_start; i < offset_start + valid_bytes; i++)
w_strb[i] = 1;
endfunction
function void print();
foreach(w_strb[i]) $write("%0d ",w_strb[i]);
$display("\n valid bytes = %0d , offset = %0d strb.size = %0d data_in.size() = %0d", valid_bytes, offset_start, w_strb.size(),data_in.size());
endfunction
endclass
module tb;
non_sparse_strb nstrb;
initial begin
nstrb = new();
repeat(16) begin
nstrb.randomize();
nstrb.print();
end
end
endmodule