I have a project which is a Verification of Synchronous FIFO, I have built the driver, and it was successful. Afterwards, I built the Monitor and Scoreboard. The problems arise when running the testbench.I have no control of what is being transmitted to the monitor, what i read from monitor is delayed version of what the DUT gets (input data, and output data). So I always get data-miss match at scoreboard. I’m a beginner, and this is my first project. At first I wasn’t using clocking blocks, thought of using them later on, but from my perspective they only made it more complex to synchronize the monitor and DUT.
I have made the input and output skew of monitor clocking block to be 1ps same goes for driver clocking block. I’m really confused of what should I do. can you recommend me some relevant reading material?
Figure 1: Waveform Snapshot
Figure 2: Console Snapshot
/DRIVER/
`include "interface.sv"
`define driv_intf vif.driv.driver_cb
`define mon_intf vif.mon.monitor_cb
class driver;
int no_transactions;
transaction trans;
mailbox gen2drive;
virtual intf vif;
function new(virtual intf vif, mailbox gen2drive);
this.vif = vif;
this.gen2drive = gen2drive;
endfunction
task reset();
$display("------[DRIVER] - RESET TASK - Awaiting Reset--------");
wait(vif.reset);
$display("--------- [DRIVER] Reset Started ---------");
`driv_intf.wr <= 0;
`driv_intf.rd <= 0;
`driv_intf.din <= 0;
`driv_intf.en <= 0;
wait(!vif.reset);
$display("--------- [DRIVER] Reset has ended ---------");
endtask;
task enable();
repeat(5) begin
@(posedge vif.driv.clk)
vif.en <= 1'b1;
end
endtask
task drive();
transaction trans;
gen2drive.get(trans);
@(posedge vif.driv.clk);
if(trans.wr && vif.en) begin
`driv_intf.din <= trans.din;
`driv_intf.rd <= trans.rd;
`driv_intf.wr <= trans.wr;
end
if(trans.rd && vif.en) begin
`driv_intf.din <= trans.din;
`driv_intf.rd <= trans.rd;
`driv_intf.wr <= trans.wr;
end
no_transactions++;
endtask
task main();
forever begin
drive();
end
endtask
endclass
/monitor/
`define driv_intf vif.driv.driver_cb
`define mon_intf vif.mon.monitor_cb
class monitor2;
virtual intf vif;
sb scoreboard = new();
function new(virtual intf vif);
this.vif=vif;
endfunction
task mon_push_pop();
begin
logic [31:0] datain;
logic [31:0] dataout;
forever begin
@(posedge vif.driv.clk);
if(vif.rd) begin
dataout = `mon_intf.dout;
scoreboard.compare(dataout);
end
if(vif.wr) begin
datain = `mon_intf.din;
scoreboard.pushItem(datain);
end
end
end
endtask
endclass
/SCOREBOARD/
class sb;
mailbox fifo = new(256);
integer size;
static int error = 0;
function new();
this.size = 0;
endfunction
task pushItem(bit [31:0] data);
if(size == 257)
$write("\nTime: %t | [Scoreboard] -- Over Flow has been Detected | Size = %0d",$time,size);
else
fifo.put(data);
$display("\n[SCOREBOARD]--- |Time:%0dns|Entered Value %h\n", $time, data);
size++;
endtask
task compare(bit [31:0] data);
bit [31:0] fifodata = 0;
if(size == 0) begin
$write("\nTime: %0tns | [Scoreboard -- Underflow has been detected | Size = %0d", $time,size);
end
else begin
fifo.get(fifodata);
if(data != fifodata ) begin
$write("\nTime: %0tns | [Scoreboard -- Data Missmatch | Size = %0d, | Actual Data: %0h | Expected Data: %0h",$time,size,data,fifodata);
this.error++;
end
size--;
end
endtask
endclass
If you have viewed my code, does it make sense?