I want to generate the address for multiple iterations and i want to make sure i don’t generate the starting address within the previous memory regions.
Example : lets say I want to write ten words, we have memory from 32’h0 to 32’h1400. I want to generate address randomly with random size. For the sake of example lets say we randomly choose address 32’h 10 and size 10 words as well in the first iteration. When we are randomizing second time we don’t want to generate the address with in 32’h10 and 32’h10 + 10 *4. I have used cyclic randomization but it still generates the address with the memory region.
In reply to prashanthiyer90:
You will need to build a database of used addresses and make sure that each address in not withing the new range you want add.
module top;
class A;
rand int unsigned start,size;
int used[$];
constraint c{0<size;size<5;start<20;
foreach(used[addr])!(used[addr] inside {[start:start+size-1]});}
function void post_randomize();
for(int addr = start; addr<(start+size); addr++)
used.push_back(addr);
used.sort(); // makes display easier to read
endfunction
endclass
A h = new;
initial repeat(15) begin
if (!h.randomize) $error("no more space to write");
$display("%p",h);
end
endmodule : top
Thanks a lot for the reply. It did help me to extend from your constraints code. since my address is all word aligned i made sure i save only the address which is word boundary in the data structure.
Does this have a performance impact as every time we are trying to randomize the object the foreach has to run for the whole address space that is being allocated.
I am seeing a slow down in simulation during the randomize() call. Trying to figure out if its due to the foreach in the constraint.
Yes, performance degrades as you start to use up addresses.
Another approach to this is generating randomly sized blocks and allocating them sequentially at beginning of your test. Then picking one block randomly during the test.
Thanks for the quick response Dave. While I was thinking about the alternative approach you have mentioned I had a thought:
Since UVM is a powerful methodology is there a class that can actually do the random memory generation for us? I think this a pretty common use case where people need to allocate random non overlapping memory spaces.
Let’s say my use case is the following:
I have 2GB of system memory
I need to allocate random non overlapping space from this memory that will contain data that gets transmitted or can be used to store data that is received by a DMA agent from a packet based protocol (In my case Ethernet).
I also need random non-overlapping chunks of memory space to store my DMA descriptors.
So, if there is such a class in which I can set start address and end address of the memory (0-2GB) and if it has methods something like:
get_buffer(buf_start_addr,buf_size) // Both args are output
get_buffer_of_spec_size(buf_start, req_buf_size) // Buf_start as output and req_buf_size as input
Are you aware of any such class in UVM. I want to reuse such class if it already exists.