Friday, March 02, 2012

Creating Verification Environment Using System verilog: Memory Module

//rtl code

module memory_m
#(parameter int unsigned DW = 8,
parameter int unsigned AW = 5
)

(
output logic [DW-1 : 0] data_out,
input logic [DW-1 : 0] data_in,
input logic [AW-1 : 0] addr,
input logic write,
input logic read,
input logic clk
);

timeunit 1ns;
timeprecision 1ns;

logic [DW-1 : 0] mem [2**AW];
always_ff @(posedge clk iff (write && !read))
mem[addr] <= data_in;

always_ff @(posedge clk iff (read && !write))
data_out <= mem[addr];

endmodule : memory_m


//verification

module memory_test_m

#(parameter int unsigned DW = 8,
parameter int unsigned AW = 5,
parameter bit DEBUG = 0
)

(
input logic [DW-1 : 0] data_out,
output logic [DW-1 : 0] data_in,
output logic [AW-1 : 0] addr,
output logic write,
output logic read,
input logic clk
);

timeunit 1ns;
timeprecision 1ns;

task write_mem (input [AW-1 : 0] waddr, input [DW-1 : 0]wdata, input debug = 0);
write <= 1;
read <= 0;
addr <= waddr;
data_in <= wdata;
@(negedge clk)
write <= 0;
if(debug == 1)
$display("%t: write - address: %d data:%h", $time, waddr, wdata);
endtask

task read_mem (input [AW-1 : 0] raddr, output [DW-1 : 0]rdata, input debug = 0);
write <= 0;
read <= 1;
addr <= raddr;
@(negedge clk)
read <= 0;
rdata = data_out;
if(debug == 1)
$display("%t: read - address: %d data:%h", $time, raddr, rdata);
endtask

function void printstatus (input int unsigned status);
$display("MEMORY TEST %s with %0d errors", status? "FAILED":"PASSED", status);
if(status != 0)
$finish;
endfunction

initial
begin
logic [DW-1:0] data_r;
int unsigned errors;
$timeformat (-9, 1, "ns", 9);

@(negedge clk);
$display (" CLEARING THE MEMORY");
errors = 0;

for(int unsigned i = 0; i <= 2**AW-1; ++i)
write_mem (i, 0, DEBUG);
for(int unsigned i = 0; i <= 2**AW-1; ++i)
begin
read_mem(i, data_r, DEBUG);
if(data_r !== 0)
++errors;
end
printstatus(errors);
$display("TEST DATA = ADDRESS");
errors = 0;
for(int unsigned i = 0; i <= 2**AW-1; ++i)
write_mem (i, i, DEBUG);
for(int unsigned i = 0; i <= 2**AW-1; ++i)
begin
read_mem(i, data_r, DEBUG);
if(data_r !== i)
++errors;
end
printstatus(errors);

$finish(0);
end
initial
begin
$recordfile("memory_m.trn");
$recordvars("depth = 0");
end

endmodule : memory_test_m


//top module

module top_m ;
timeunit 1ns ;
timeprecision 1ns ;


localparam time PERIOD = 10;
localparam int unsigned DWIDTH = 8;
localparam int unsigned AWIDTH = 5;
localparam bit DEBUG = 1;


logic [DWIDTH-1 : 0] data_out;
logic [DWIDTH-1 : 0] data_in ;
logic [AWIDTH-1 : 0] addr ;
logic write ;
logic read ;
logic clk ;


memory_m #(DWIDTH, AWIDTH) memory (.*);
memory_test_m #(DWIDTH, AWIDTH, DEBUG) memory_test(.*);

initial clk = 0;
always #(PERIOD/2) clk = ~clk;



endmodule : top_m


No comments:

Post a Comment

Popular Posts