Constraint For Single Port RAM

     Hello , welcome back. In this blog post we will see examples on constraints for RAM which is single port.constraint contains following conditions for generating different stimulus.

Constraints are following.

1) write in order from 0 to n location and then read from 0 to n       location
2) write 0 value in all locations and read from all locations
3) write FF value in all locations and read from all locations
4) write 0 on odd address and FF on even address
5) write on address and read from same address in order (e.g,           addr=0,1,2,3,4...n)
6) write 2 times on same address and read 1 time from same address
7) write 1 time on address and read 2 times from same address
8) write data on boundary locations (i.e, addr[7:5]==3'b111; )


1) write in order from 0 to n location and then read from 0 to n location 

//-------------------- write in order--------------------
  constraint only_write_in_order{
    addr==write_in_order();
    data_in==addr;
    rdn_wr==1;
  }
  constraint only_read_in_order{
    addr==read_in_order();
    data_in==addr;
    rdn_wr==0;
  }
  //-------------------------------------------------------
function bit[7:0] write_in_order();
      static int ad=0;
    write_in_order=ad;
    ad++;
  endfunction
  
  function bit[7:0] read_in_order();
      static int ad=0;
    read_in_order=ad;
    ad++;
  endfunction
  //-------------------------------------------------------
 
2) write 0 value in all locations and read from all locations
//---------------------- write all 0---------------------
  constraint write_all_0{
      addr==write_in_order();
      data_in==0;
      rdn_wr==1;
  }
  constraint read_all_0{
      addr==read_in_order();
      data_in==2; // it may be anything
      rdn_wr==0;
  }
  //------------------------------------------------------
  function bit[7:0] write_in_order();
    static int ad=0;
    write_in_order=ad;
    ad++;
  endfunction
  
  function bit[7:0] read_in_order();
    static int ad=0;
    read_in_order=ad;
    ad++;
  endfunction
 
 
3) write FF value in all locations and read from all locations
//------------------- write all FF ----------------------
  constraint write_all_ff{
      addr==write_in_order();
      data_in==8'hFF;
      rdn_wr==1;
  }
  constraint read_all_ff{
      addr==read_in_order();
      data_in==2;
      rdn_wr==0;
  }
  //-------------------------------------------------------

 
4) write 0 on odd address and FF on even address

  //---------write 0 and ff in odd even addr---------------
  constraint write_0_ff_in_odd_even{
    addr==write_in_order();
    rdn_wr==1;
    data_in==data_in_value();
  }
  //-------------------------------------------------------
function bit [7:0] data_in_value();
    static int unsigned count=0;
    if(count%2==0)
      data_in_value=0;
    else begin
      data_in_value=8'hFF;
    end
    count++;
  endfunction
 
5) write on address and read from same address in order
for(int i=0;i<20;i++) begin
      temp=i;
      for(int j=0;j<2;j++) begin
        txn.randomize()with{txn.addr==temp; txn.data_in==temp; 
        txn.rdn_wr==flag; };
        txn.print();
        flag=~flag;
      end
end
 
6) write 2 times on same address and read 1 time from same address
for(int i=0;i<20;i++) begin
      temp=i;
      repeat(2) begin // write 2 times on same address
        txn.randomize()with{txn.addr==temp; txn.rdn_wr==1; }; // data_in random
        txn.print();
      end
      repeat(1) begin
        txn.randomize()with{txn.addr==temp; txn.data_in==0; txn.rdn_wr==0;};
        txn.print();
      end
    end
 
7) write 1 time on address and read 2 times from same address
for(int i=0;i<20;i++) begin
      temp=i;
      repeat(1) begin // write 1 time address
        txn.randomize()with{txn.addr==temp; txn.rdn_wr==1; }; // data_in random
        txn.print();
      end
      repeat(2) begin // read 2 times form same address
        txn.randomize()with{txn.addr==temp; txn.data_in==0; txn.rdn_wr==0;};
        txn.print();
      end
end    
 
8) write data on boundary locations
  //----------------- write on boundry of ram -------------
  constraint boundry_of_ram_write{
    addr[7:5]==3'b111;
    rdn_wr==1;
  }
  //-------------------------------------------------------
 
All Together
/* Inputs to DUT

signak name : size   : direction
addr        : 8 bits : input     
data_in     : 8 bits : input
rdn_wr      : 1 bit  : input  :0->read operation, 1-> write operation
rst_p       : 1 bit  : input
clk         : 1 bit  : input
data_out    : 8 bits : output

*/

/* constraints to write

-Single Read and Write behaves correctly,
-Back to Back reads or writes to the same address and different addresses,
-Writes followed by reads to same address back to back,
-Reads followed by writes to same address back to back,
-Verifying the boundary of RAM sizes - reads and writes,
-Verifying the different patterns of writing into memory location like writing all zeros,
  all ones, alternating zero/one, walking ones/zeros patterns.

*/

class ram_sequence_item;
  
  rand bit [7:0] addr;
  rand bit [7:0] data_in;
  rand bit       rdn_wr;
  
  bit rst_p;
  //-------------------- write in order--------------------
  constraint only_write_in_order{
    addr==write_in_order();
    data_in==addr;
    rdn_wr==1;
  }
  constraint only_read_in_order{
    addr==read_in_order();
    data_in==addr;
    rdn_wr==0;
  }
  //-------------------------------------------------------

  //---------------------- write all 0---------------------
  constraint write_all_0{
      addr==write_in_order();
      data_in==0;
      rdn_wr==1;
  }
  constraint read_all_0{
      addr==read_in_order();
      data_in==2; // it may be anything
      rdn_wr==0;
  }
  //------------------------------------------------------

  //------------------- write all FF ----------------------
  constraint write_all_ff{
      addr==write_in_order();
      data_in==8'hFF;
      rdn_wr==1;
  }
  constraint read_all_ff{
      addr==read_in_order();
      data_in==2;
      rdn_wr==0;
  }
  //-------------------------------------------------------

  //---------write 0 and ff in odd even addr---------------
  constraint write_0_ff_in_odd_even{
    addr==write_in_order();
    rdn_wr==1;
    data_in==data_in_value();
  }
  //-------------------------------------------------------

  //----------------- write on boundry of ram -------------
  constraint boundry_of_ram_write{
    addr[7:5]<8;
    rdn_wr==1;
  }
  //-------------------------------------------------------

  //-----------FUNCTIONS USED IN CONSTRAINTS --------------
  function bit [7:0] data_in_value();
    static int unsigned count=0;
    if(count%2==0)
      data_in_value=0;
    else begin
      data_in_value=8'hFF;
    end
    count++;
  endfunction
  
  function bit[7:0] write_in_order();
      static int ad=0;
    write_in_order=ad;
    ad++;
  endfunction
  
  function bit[7:0] read_in_order();
      static int ad=0;
    read_in_order=ad;
    ad++;
  endfunction
  //-------------------------------------------------------
  
  //-------------------------------------------------------
  function void print();
    $display("\t addr=%3d data_in=%3d rdn_wr=%0b",addr,data_in,rdn_wr);
  endfunction
  //-------------------------------------------------------
  
endclass



module tb;
  ram_sequence_item txn;
  bit flag=1;
  int temp;
  initial begin
    write_and_read_in_order();
    // write_read_all_0();
    // write_read_all_ff();
    // write_0_ff();
    // write_and_read();
    // write_2_time_and_read_1_time();
    // write_1_time_and_read_2_time();
    // boundry_write();
  end
  
  task boundry_write();
    txn=new();
    $display("\t-----------------------------------");
    
    txn.only_write_in_order.constraint_mode(0);
    txn.only_read_in_order.constraint_mode(0);
    txn.write_all_0.constraint_mode(0);
    txn.read_all_0.constraint_mode(0);
    txn.write_all_ff.constraint_mode(0);
    txn.read_all_ff.constraint_mode(0);
    txn.write_0_ff_in_odd_even.constraint_mode(0);
    
    for(int i=0;i<20;i++) begin
      txn.randomize();
      txn.print();
    end
  endtask

  task write_and_read();
    txn=new();
    $display("\t--- Write operation all 0---");
    
    txn.only_write_in_order.constraint_mode(0);
    txn.only_read_in_order.constraint_mode(0);
    txn.write_all_0.constraint_mode(0);
    txn.read_all_0.constraint_mode(0);
    txn.write_all_ff.constraint_mode(0);
    txn.read_all_ff.constraint_mode(0);
    txn.write_0_ff_in_odd_even.constraint_mode(0);
    txn.boundry_of_ram_write.constraint_mode(0); 
   
    for(int i=0;i<20;i++) begin
      temp=i;
      for(int j=0;j<2;j++) begin
        txn.randomize()with{txn.addr==temp; txn.data_in==temp; txn.rdn_wr==flag; };
        txn.print();
        flag=~flag;
      end
    end
     
  endtask
  // new task for writing data on same memory address and read once
  task write_2_time_and_read_1_time();
    txn=new();
    $display("\t-----------------------------------");
    
    txn.only_write_in_order.constraint_mode(0);
    txn.only_read_in_order.constraint_mode(0);
    txn.write_all_0.constraint_mode(0);
    txn.read_all_0.constraint_mode(0);
    txn.write_all_ff.constraint_mode(0);
    txn.read_all_ff.constraint_mode(0);
    txn.write_0_ff_in_odd_even.constraint_mode(0); 
    txn.boundry_of_ram_write.constraint_mode(0);
    
    for(int i=0;i<20;i++) begin
      temp=i;
      repeat(2) begin // write 2 times on same address
        txn.randomize()with{txn.addr==temp; txn.rdn_wr==1; }; // data_in random
        txn.print();
      end
      repeat(1) begin
        txn.randomize()with{txn.addr==temp; txn.data_in==0; txn.rdn_wr==0;};
        txn.print();
      end
    end
     
  endtask
  // new task for writing data on same memory address and read two times
  task write_1_time_and_read_2_time();
    txn=new();
    $display("\t-----------------------------------");
    
    txn.only_write_in_order.constraint_mode(0);
    txn.only_read_in_order.constraint_mode(0);
    txn.write_all_0.constraint_mode(0);
    txn.read_all_0.constraint_mode(0);
    txn.write_all_ff.constraint_mode(0);
    txn.read_all_ff.constraint_mode(0);
    txn.write_0_ff_in_odd_even.constraint_mode(0);
    txn.boundry_of_ram_write.constraint_mode(0); 
   
    for(int i=0;i<20;i++) begin
      temp=i;
      repeat(1) begin // write 1 time address
        txn.randomize()with{txn.addr==temp; txn.rdn_wr==1; }; // data_in random
        txn.print();
      end
      repeat(2) begin // read 2 times form same address
        txn.randomize()with{txn.addr==temp; txn.data_in==0; txn.rdn_wr==0;};
        txn.print();
      end
    end
     
  endtask

  task write_0_ff();
    txn=new();
    $display("\t--- Write operation all 0---");
    
    txn.only_write_in_order.constraint_mode(0);
    txn.only_read_in_order.constraint_mode(0);
    txn.write_all_0.constraint_mode(0);
    txn.read_all_0.constraint_mode(0);
    txn.write_all_ff.constraint_mode(0);
    txn.read_all_ff.constraint_mode(0);
    txn.boundry_of_ram_write.constraint_mode(0);
    txn.write_0_ff_in_odd_even.constraint_mode(1);
    
    repeat(20) begin
      txn.randomize();
      txn.print();
    end
    $display("\t--- Read operation ---");
    txn.write_0_ff_in_odd_even.constraint_mode(0);
    txn.only_read_in_order.constraint_mode(1);

    repeat(20) begin
      txn.randomize();
      txn.print();
    end  
  endtask

  task write_read_all_ff();
      txn=new();
      $display("\t--- Write operation all ff---");
      
      txn.only_write_in_order.constraint_mode(0);
      txn.only_read_in_order.constraint_mode(0);
      txn.write_all_0.constraint_mode(0);
      txn.read_all_0.constraint_mode(0);
      txn.write_all_ff.constraint_mode(1);
      txn.read_all_ff.constraint_mode(0);
      txn.write_0_ff_in_odd_even.constraint_mode(0); 
      txn.boundry_of_ram_write.constraint_mode(0);
      
      repeat(20) begin
        txn.randomize();
        txn.print();
      end
      
      $display("\t--- Read operation ---");
      txn.read_all_ff.constraint_mode(1);
      txn.write_all_ff.constraint_mode(0);
      repeat(20) begin
        txn.randomize();
        txn.print();
      end  
  endtask

  task write_read_all_0();
      txn=new();
      $display("\t--- Write operation all 0---");

      txn.only_write_in_order.constraint_mode(0);
      txn.only_read_in_order.constraint_mode(0);
      txn.write_all_0.constraint_mode(1);
      txn.read_all_0.constraint_mode(0);
      txn.write_all_ff.constraint_mode(0);
      txn.read_all_ff.constraint_mode(0);
      txn.write_0_ff_in_odd_even.constraint_mode(0); 
      txn.boundry_of_ram_write.constraint_mode(0);
      
      repeat(20) begin
        txn.randomize();
        txn.print();
      end
      $display("\t--- Read operation ---");
      txn.read_all_0.constraint_mode(1);
      txn.write_all_0.constraint_mode(0);
      repeat(20) begin
        txn.randomize();
        txn.print();
      end  
  endtask
  
  task write_and_read_in_order();
    txn=new();
    $display("\t--- Write operation ---");

    txn.only_write_in_order.constraint_mode(1);
    txn.only_read_in_order.constraint_mode(0);
    txn.write_all_0.constraint_mode(0);
    txn.read_all_0.constraint_mode(0);
    txn.write_all_ff.constraint_mode(0);
    txn.read_all_ff.constraint_mode(0);
    txn.write_0_ff_in_odd_even.constraint_mode(0); 
    txn.boundry_of_ram_write.constraint_mode(0);


    repeat(20) begin
      txn.randomize();
      txn.print();
    end
    $display("\t--- Read operation ---");
    txn.only_read_in_order.constraint_mode(1);
    txn.only_write_in_order.constraint_mode(0);
    repeat(20) begin
      txn.randomize();
      txn.print();
    end  
    
  endtask
  
endmodule

  
 
 
 
Thank you, for reading have a nice day😇😇😀.
 
Share:
Copyright © VLSI Verification Concepts . Designed by OddThemes