SystemVerilog Project
SystemVerilog Project
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
endmodule
Interface
interface fifo_if;
endinterface
Testbench Code
class transaction;
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;
}
endclass
/*
module tb;
transaction tr;
initial begin
tr = new();
tr.display("TOP");
end
endmodule
*/
class generator;
transaction tr;
mailbox #(transaction) mbx;
int count = 0;
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;
transaction datac;
event next;
////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
datac.display("DRV");
endclass
/*
module tb;
generator gen;
driver drv;
event next;
fifo_if fif();
initial begin
fif.clock <= 0;
end
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;
transaction tr;
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;
transaction tr;
event next;
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;
event next;
fifo_if fif();
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;
event nextgs;
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
environment env;
initial begin
env = new(fif);
env.gen.count = 20;
env.run();
end
initial begin
$dumpfile("dump.vcd");
$dumpvars;
end
endmodule