haithamx15
haithamx15

Reputation: 3

SystemVerilog Synchronization Between Driver/DUT/Monitor

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, is that 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?

Waveform Viewer Snapshots/notice data actually gets into the fifo memory at 75ps

Console Snapshot

Waveform Viewer Snapshot

Here is my code for driver, monitor, scoreboard.

/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

Upvotes: 0

Views: 1724

Answers (1)

Ramdas M
Ramdas M

Reputation: 86

First thing, your code needs more structure. You are creating an object of scoreboard inside monitor and calling the methods from monitor. This is bad coding

First create a top environment class that creates objects of monitor, driver and scoreboard. Implement a run() method inside driver, monitor and scoreboard and fork calling them from the environment class to allow them running in parallel.

Once you have this proper structure, as long as you first write into the fifo (which creates a push into scoreboard) and then the read should match data.

Upvotes: 1

Related Questions