Hi,
I am looking to generate non over-lapping 4K address range to each master.
For eg: say if the processor has 64KB of memory which should be assigned to different slaves. If I have 4 slaves each taking 4K addresses, I can assign 0 to 4K-1 for slave 1, 4k to 8k-1 to slave 2 and so on. But the address range 3k to 5k will be invalid because it is overlapping with slave 1.
The same way if I want to create 4K address range to 16 masters without overlapping, I am trying to write the constraint but so far I succeeded only getting a code below which generates unique addresses for each master as shown below.
class address;
randc bit [3:0] addr;
randc bit [3:0] N;
endclass
module allocation;
initial begin
address addr_handle;
addr_handle = new();
repeat(16) begin
addr_handle.randomize();
$display("\t %4b address allocated for %0d master", addr_handle.addr, addr_handle.N);
end
end
endmodule
Can somebody please help me how to write the constraint to generate 4k address range for 16 masters.
Thanks,
Sruthi.
In reply to sruthikrapa:
Try this
class address;
int N = 16;
int memRange = 'h1000;
int memLimit = 'h400_0000;
rand bit [26:0] addrs[];
function new;
addrs = new[N];
endfunction
constraint c{
foreach(addrs[S]) if (S != N-1)
addrs[S] + memRange < addrs[S+1];
else
addrs[S] + memRange < memLimit;
}
endclass
In reply to sruthikrapa:
For master to generate the different 4k address based on its Master number. You should use rand as variable instead of randc. You should also make sure that master address is aligned to its access boundary . In the below code its aligned 4 bytes boundary. You can change to your requirement. For 4K address space you ll need at least 12 bits.
class address;
rand bit [15:0] addr;
rand bit [3:0] N;
constraint c_addr {
(N ==0) -> (addr inside {[0:'h1000]} ) ;
(N ==1) -> (addr inside {['h1001:'h2000]} );
(N ==2) -> (addr inside {['h2001:'h3000]} );
(N ==3) -> (addr inside {['h3001:'h4000]} );
(N ==4) -> (addr inside {['h4001:'h5000]} );
(N ==5) -> (addr inside {['h5001:'h6000]} );
(N ==6) -> (addr inside {['h6001:'h7000]} );
(N ==7) -> (addr inside {['h7001:'h8000]} );
(N ==8) -> (addr inside {['h8001:'h9000]} );
(N ==9) -> (addr inside {['h9001:'ha000]} );
(N ==10) -> (addr inside {['ha001:'hb000]} );
(N ==11) -> (addr inside {['hb001:'hc000]} );
(N ==12) -> (addr inside {['hc001:'hd000]} );
(N ==13) -> (addr inside {['hd001:'he000]} );
(N ==14) -> (addr inside {['he001:'hf000]} );
(N ==15) -> (addr inside {['hf001:'h10000]} );
solve N before addr ;
}
constraint c_addr_aligned {
addr%4 == 0 ;
}
endclass
module allocation;
initial begin
address addr_handle;
addr_handle = new();
repeat(16) begin
addr_handle.randomize();
$display("\t %4h address allocated for %0d master", addr_handle.addr, addr_handle.N);
end
end
endmodule
In reply to kddholak:
Hi kddholak,
Thank you for the response.
But now since we have N limited to 16, we can allocate specific address range for each master as shown in your code. But, if N value increases more than 16, then wouldn’t it become hard to allocate each address range to N. Just wanted to know how can we do in that scenario.
Thanks,
Sruthi.