Constraining address for the memory making sure the Offset is not within the previous memory regions

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

In reply to dave_59:

Hi Dave,

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.

Regards,
Prash

In reply to dave_59:

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.

In reply to yasaswi93:

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.

In reply to dave_59:

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:

  1. I have 2GB of system memory
  2. 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).
  3. 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:

  1. get_buffer(buf_start_addr,buf_size) // Both args are output
  2. 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.

In reply to yasaswi93:
https://verificationacademy.com/forums/uvm/uvm-memory-manager-uvmmemmam-still-around

In reply to dave_59:

Thanks Dave.