I want to generate random regions in memory such that they do not overlap. Below code is generating such regions but they are in order (i.e., region-0 is before region-1, region-1 is before region-2).
But I want to have the regions in random order. I can use shuffle() in post_randomize, but I want to know if we can do this using just constraints ?
class test;
typedef struct{
rand int unsigned indx;
rand bit [31:0] addr_s;
rand bit [31:0] addr_e;
rand bit [31:0] sz;
} regions_t;
rand regions_t regions[];
constraint c_regions{
regions.size() == 3;
foreach(regions[i]) {
regions[i].indx == i;
regions[i].sz inside {10, 20}; // size of each region
regions[i].addr_e == regions[i].addr_s + regions[i].sz - 1;
regions[i].addr_s < regions[i].addr_e;
regions[i].addr_e < 60; // uppler limit of all memory regions
foreach(regions[j]) {
//if(i!=j) !((regions[i].addr_s >= regions[j].addr_s) && (regions[i].addr_s <= regions[j].addr_e));
if(i<j) (regions[i].addr_e < regions[j].addr_s);
}
}
}
function void post_randomize();
//regions.shuffle();
$display($sformatf("post_randomize(): regions = %0p", regions));
endfunction : post_randomize
endclass: test
program prog;
test tst;
initial begin
tst = new();
repeat(10) begin
tst.randomize();
end
end
endprogram: prog
This constraint if(i!=j) !((regions[i].addr_s >= regions[j].addr_s) && (regions[i].addr_s <= regions[j].addr_e));
seems to be working, but wanted to sure if it will have issues.
Change your last inner foreach
loop to what I show below. You were very close/
typedef bit [7:0] addr_t;
class test;
typedef struct{
int unsigned indx;
addr_t addr_s;
addr_t addr_e;
int sz;
} regions_t;
rand regions_t regions[];
constraint c_regions{
regions.size() == 3;
foreach(regions[i]) {
regions[i].indx == i;
regions[i].sz inside {10, 20}; // size of each region
regions[i].addr_e == regions[i].addr_s + regions[i].sz - 1;
regions[i].addr_s < regions[i].addr_e;
regions[i].addr_e < 80; // upper limit of all memory regions
foreach(regions[j]) // start address cannot be inside another range
i!=j -> !(regions[i].addr_s inside {[regions[j].addr_s:regions[j].addr_e]});
}
}
function void post_randomize();
$display($sformatf("post_randomize(): regions = %p", regions));
endfunction : post_randomize
endclass: test
module prog;
test tst;
initial begin
tst = new();
repeat(10) begin
assert(tst.randomize());
end
end
endmodule: prog