驱动程序/DUT/监视器之间的系统Verilog同步



我有一个项目是同步FIFO的验证,我已经构建了驱动程序,并且成功了。之后,我构建了监视器和记分牌。运行测试平台时出现的问题是,我无法控制传输到监视器的内容,我从监视器读取的内容是 DUT 获取的内容(输入数据和输出数据(的延迟版本。所以我总是在记分牌上得到数据错过比赛。我是初学者,这是我的第一个项目。起初我没有使用时钟块,后来想过使用它们,但从我的角度来看,它们只会使同步显示器和 DUT 变得更加复杂。

我已经使显示器时钟块的输入和输出偏差为 1ps,与驱动程序时钟块相同。我真的很困惑我该怎么办。 你能推荐我一些相关的阅读材料吗?

波形查看器快照/通知数据实际上以75ps的速度进入FIFO存储器

控制台快照

波形查看器快照

这是我的驱动程序、监视器、记分牌代码。

/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 %hn", $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

首先,你的代码需要更多的结构。您正在监视器中创建记分板对象,并从监视器调用方法。这是错误的编码

首先创建一个顶级环境类,用于创建监视器、驱动程序和记分板的对象。 在驱动程序、监视器和记分板中实现 run(( 方法,并从环境类调用它们以允许它们并行运行。

一旦你有了这个正确的结构,只要你首先写入fifo(这会创建一个推送到记分板(,然后读取应该匹配数据。

最新更新