Modulo operation inside foreach loop throws fatal error

Hi, Thanks for helping out.
I have written a small code for 10 random 32 bit memory address generators.
There are two constraints → 1) Memory address has to be <1GB which works fine.
2) Select Memory address such that it doesn’t cross boundaries of 4kB.

My constraints work well if I do it for a single 32 bit memory. When I do it for 10 random 32 bit memory with foreach loop, the #2 constraint with modulo in it fails in it. It throws a Fatal Error: Unhandled exception (std): .

Please help me understand why.

 
//1GB memory with 4kB memory boundary. Cache lines are 0.5kB each. 

class Memory_address;
  
  rand bit [31:0] store_mem_addr [10]; //Store all the memory address
  
  int cache_line = 500;   // constant cache line size = 500 Bytes
  
  // constraints for memory address
  constraint c {
    foreach (store_mem_addr[i]) 
    {
       //1. Memory address has to be within 0 to 1GB
      store_mem_addr[i] inside {[0:1000000000]};
      
      //2. Assume 4kB memory boundary. Prevent mem_addr such that memory crosses boundary. This line of code below throws fatal error.
     store_mem_addr[i]%4000 + cache_line < 4000;
  }

  }
  
  
  function void print();
    begin
      for (int j=0; j<10; j++)
        $display("Memory address %d): %d", j, store_mem_addr[j]);
    end
  endfunction


endclass: Memory_address

module memory;
  initial begin
    
    Memory_address addr1;

    addr1 = new;
    
    //Generate 10 cache lines with constraints
    assert(addr1.randomize());
    addr1.print();
    
  end
endmodule

In reply to anidea:

Thanks, I got it!
Chris Spear book on page 149 example 6-15 (Chapter: Randomization) clearly tells how to division or modulo operations are expensive. And, we should use advantage of bit extraction since 4kb is 4096 bytes, I went for this line of code inside the foreach loop which works perfectly now.

store_mem_addr[i][11:0] + cache_line < 4000;

instead of

store_mem_addr[i]%4000 + cache_line < 4000;

Thanks!