I need to randomly divide a fixed memory size of 4096 bytes into 7 non-overlapping sub-blocks with random start addresses and predefined block sizes. The block sizes must be chosen from {32, 64, 128, 256, 512, 1024, 2048}
and should be unique.
Here’s my current implementation:
module test;
class A;
parameter mem_size = 4096;
rand int unsigned bsize[7];
rand bit[11:0] mem_start_addr[7];
rand bit[11:0] mem_end_addr[7];
constraint c1 { unique {bsize}; foreach(bsize[i]) bsize[i] inside {32,64,128,256,512,1024,2048}; }
constraint c2 {
foreach(mem_start_addr[i]) {
mem_start_addr[i] inside {[ 0 : mem_size-1-bsize[i]]};
mem_end_addr[i] == mem_start_addr[i] + bsize[i];
if(i>0) {
mem_start_addr[i] > mem_end_addr[i-1];
mem_end_addr[i] == (mem_start_addr[i] + bsize[i] ) % mem_size;
}
}
}
function void display();
foreach(mem_start_addr[i]) begin
$display("%0d Start addr: %0d, End addr: %0d, blocksize: %0d", i+1, mem_start_addr[i], mem_end_addr[i], bsize[i]);
end
endfunction
endclass
initial begin
A a = new();
repeat(20) begin
a.randomize();
a.display();
$display("\n");
end
end
endmodule
Is there a more efficient way to enforce non-overlapping constraints?
This code works but would like to know if there is a better way to write constraint or any potential for constraint solver issue?