0% found this document useful (0 votes)
65 views20 pages

SystemVerilog Project

This document describes the implementation and verification of a FIFO module using SystemVerilog. It defines the FIFO module with inputs for clock, read, write, and reset and outputs for full, empty and data. It then defines the testbench with classes for transactions, a generator to generate random transactions, a driver to apply stimuli to the DUT, a monitor to monitor the DUT outputs, and a scoreboard to check for correct behavior. An environment class instantiates and connects these classes to provide a full test and verification of the FIFO module.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
65 views20 pages

SystemVerilog Project

This document describes the implementation and verification of a FIFO module using SystemVerilog. It defines the FIFO module with inputs for clock, read, write, and reset and outputs for full, empty and data. It then defines the testbench with classes for transactions, a generator to generate random transactions, a driver to apply stimuli to the DUT, a monitor to monitor the DUT outputs, and a scoreboard to check for correct behavior. An environment class instantiates and connects these classes to provide a full test and verification of the FIFO module.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

FIFO IMPLEMENTATION AND VERIFICATION USING

THE SYSTEM VERILOG:-


module fifo(
input clock, rd, wr,
output full, empty,
input [7:0] data_in,
output reg [7:0] data_out,
input rst);

reg [7:0] mem [31:0];


reg [4:0] wr_ptr;
reg [4:0] rd_ptr;

always@(posedge clock)
begin
if (rst == 1'b1)
begin
data_out <= 0;
rd_ptr <= 0;
wr_ptr <= 0;
for(int i =0; i < 32; i++) begin
mem[i] <= 0;
end
end
else
begin
if ((wr == 1'b1) && (full == 1'b0))
begin
mem[wr_ptr] <= data_in;
wr_ptr = wr_ptr + 1;
end

if((rd == 1'b1) && (empty == 1'b0))


begin
data_out <= mem[rd_ptr];
rd_ptr <= rd_ptr + 1;
end
end
end

assign empty = ((wr_ptr - rd_ptr) == 0) ? 1'b1 : 1'b0;

assign full = ((wr_ptr - rd_ptr) == 31) ? 1'b1 : 1'b0;

endmodule

Interface

interface fifo_if;

logic clock, rd, wr;


logic full, empty;
logic [7:0] data_in;
logic [7:0] data_out;
logic rst;

endinterface

Testbench Code

class transaction;

rand bit rd ,wr;


rand bit [7:0] data_in;
bit full, empty;
bit [7:0] data_out;

constraint wr_rd {
rd != wr;
wr dist {0 :/ 50 , 1:/ 50};
rd dist {0 :/ 50 , 1:/ 50};

constraint data_con {
data_in > 1; data_in < 5;
}

function void display(input string tag);


$display("[%0s] : WR : %0b\t RD:%0b\t DATAWR : %0d\t DATARD :
%0d\t FULL : %0b\t EMPTY : %0b @ %0t", tag, wr, rd, data_in, data_out,
full, empty,$time);
endfunction

function transaction copy();


copy = new();
copy.rd = this.rd;
copy.wr = this.wr;
copy.data_in = this.data_in;
copy.data_out= this.data_out;
copy.full = this.full;
copy.empty = this.empty;
endfunction

endclass

/*

module tb;

transaction tr;

initial begin
tr = new();
tr.display("TOP");
end

endmodule
*/

class generator;

transaction tr;
mailbox #(transaction) mbx;

int count = 0;

event next; ///know when to send next transaction


event done; ////conveys completion of requested no. of transaction

function new(mailbox #(transaction) mbx);


this.mbx = mbx;
tr=new();
endfunction;

task run();

repeat(count)
begin
assert(tr.randomize) else $error("Randomization failed");
mbx.put(tr.copy);
tr.display("GEN");
@(next);
end

->done;
endtask

endclass

/*
module tb;

generator gen;
mailbox #(transaction) mbx;

initial begin
mbx = new();

gen = new(mbx);

gen.count = 20;
gen.run();

end
endmodule

*/

class driver;

virtual fifo_if fif;

mailbox #(transaction) mbx;

transaction datac;

event next;

function new(mailbox #(transaction) mbx);


this.mbx = mbx;
endfunction;

////reset DUT
task reset();
fif.rst <= 1'b1;
fif.rd <= 1'b0;
fif.wr <= 1'b0;
fif.data_in <= 0;
repeat(5) @(posedge fif.clock);
fif.rst <= 1'b0;
$display("[DRV] : DUT Reset Done");
endtask

//////Applying RANDOM STIMULUS TO DUT


task run();
forever begin
mbx.get(datac);

datac.display("DRV");

fif.rd <= datac.rd;


fif.wr <= datac.wr;
fif.data_in <= datac.data_in;
repeat(2) @(posedge fif.clock);
->next;
end
endtask

endclass

/*
module tb;

generator gen;

driver drv;

event next;

mailbox #(transaction) mbx;

fifo_if fif();

fifo dut (fif.clock, fif.rd, fif.wr,fif.full, fif.empty, fif.data_in, fif.data_out,


fif.rst);

initial begin
fif.clock <= 0;
end

always #10 fif.clock <= ~fif.clock;

initial begin
mbx = new();

gen = new(mbx);

gen.count = 20;

drv = new(mbx);

drv.fif = fif;
gen.next = next;
drv.next = next;

end

initial begin
fork
gen.run();
drv.run();
join
end

initial begin
#800;
$finish();
end

initial begin
$dumpfile("dump.vcd");
$dumpvars;
end

endmodule

*/
class monitor;

virtual fifo_if fif;

mailbox #(transaction) mbx;

transaction tr;

function new(mailbox #(transaction) mbx);


this.mbx = mbx;
endfunction;

task run();
tr = new();

forever begin
repeat(2) @(posedge fif.clock);
tr.wr = fif.wr;
tr.rd = fif.rd;
tr.data_in = fif.data_in;
tr.data_out = fif.data_out;
tr.full = fif.full;
tr.empty = fif.empty;

mbx.put(tr);
tr.display("MON");

end

endtask

endclass

/////////////////////////////////////////////////////

class scoreboard;

mailbox #(transaction) mbx;

transaction tr;

event next;

bit [7:0] din[$];


bit[7:0] temp;

function new(mailbox #(transaction) mbx);


this.mbx = mbx;
endfunction;

task run();
forever begin

mbx.get(tr);

tr.display("SCO");

if(tr.wr == 1'b1)
begin
din.push_front(tr.data_in);
$display("[SCO] : DATA STORED IN QUEUE :%0d", tr.data_in);
end

if(tr.rd == 1'b1)
begin
if(tr.empty == 1'b0) begin

temp = din.pop_back();

if(tr.data_out == temp)
$display("[SCO] : DATA MATCH");
else
$error("[SCO] : DATA MISMATCH");
end
else
begin
$display("[SCO] : FIFO IS EMPTY");
end

end
->next;
end
endtask

endclass
//////////////////////////////////////

/*
module tb;

monitor mon;
scoreboard sco;

mailbox #(transaction) mbx;

event next;

fifo_if fif();

fifo dut (fif.clock, fif.rd, fif.wr,fif.full, fif.empty, fif.data_in, fif.data_out,


fif.rst);

initial begin
fif.clock <= 0;
end
always #10 fif.clock <= ~fif.clock;

initial begin
mbx = new();

mon = new(mbx);
sco = new(mbx);

mon.fif = fif;

mon.next = next;
sco.next = next;
end

initial begin
fork
mon.run();
sco.run();
join
end

initial begin
#200;
$finish();
end

initial begin
$dumpfile("dump.vcd");
$dumpvars;
end

endmodule

*/

class environment;

generator gen;
driver drv;

monitor mon;
scoreboard sco;

mailbox #(transaction) gdmbx; ///generator + Driver

mailbox #(transaction) msmbx; ///Monitor + Scoreboard

event nextgs;

virtual fifo_if fif;


function new(virtual fifo_if fif);

gdmbx = new();
gen = new(gdmbx);
drv = new(gdmbx);

msmbx = new();
mon = new(msmbx);
sco = new(msmbx);

this.fif = fif;

drv.fif = this.fif;
mon.fif = this.fif;

gen.next = nextgs;
sco.next = nextgs;

endfunction

task pre_test();
drv.reset();
endtask

task test();
fork
gen.run();
drv.run();
mon.run();
sco.run();
join_any

endtask

task post_test();
wait(gen.done.triggered);
$finish();
endtask

task run();
pre_test();
test();
post_test();
endtask

endclass
module tb;

fifo_if fif();
fifo dut (fif.clock, fif.rd, fif.wr,fif.full, fif.empty, fif.data_in, fif.data_out,
fif.rst);

initial begin
fif.clock <= 0;
end

always #10 fif.clock <= ~fif.clock;

environment env;

initial begin
env = new(fif);
env.gen.count = 20;
env.run();
end

initial begin
$dumpfile("dump.vcd");
$dumpvars;
end
endmodule

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy