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
Link For Code : https://www.edaplayground.com/x/8xXE
Thank you, for reading have a nice day😇😇😀.