System Verilog 验证环境的搭建2

接着上一篇博客,正式开始进行System Verilog验证环境的搭建。依据MCDF的结构图,依次进行MCDF功能模块的验证。代码设计时我们将每一个功能模块里的验证内容都放在一个package中,提高代码的可读性。

  1. arb_pkg
    由于Arbiter模块并没有与外部信号进行交互,其内部信号都已经划分至其余功能模块内,这里暂时先不对此模块进行验证,只会在测试案例中添加一些通道优先级的测试。
  2. chnl_pkg
    channel模块的功能是向三个通道发送数据。
 package chnl_pkg;
     class chnl_trans;
     	constraint cstr{
		};
		//-------------------------------------------------
		fuction chnl_trans clone();
		endfunction
		
		fuction string sprint();
		endfunction
	 endcalss
     class chnl_driver;
     	local string name;
     	local virtual chnl_intf intf;
     	mailbox#(chnl_trans)req_mb;
     	mailbox#(chnl_trans)rsq_mb;
     	//-------------------------------------------------
     	function new(string name = "");
     	endfunction
     	
     	fuction viod set_interface(virtual chnl_inft intf)
     	endfunction
     	//-------------------------------------------------
     	task tun();
     		this.do_driver(();
		endtask
     class chnl_gennerator;
     	mailbox#(chnl_trans)req_mb;
     	mailbox#(chnl_trans)rsq_mb;
     	constraint cstr{
		};
		//-------------------------------------------------
		function new(string name = "");
     	endfunction
     	task start();
     		repeat(ntrans) send_trans();
     class chnl_monitor;
     	local string name;
     	local virtual chnl_intf intf;
     	mailbox#(mon_data_t)mon_mb;
     	//-------------------------------------------------
     	function new(string name = "");
     	endfunction
     	
     	fuction viod set_interface(virtual chnl_inft intf)
     	endfunction
     	//-------------------------------------------------
     	task tun();
     		this.mon_trans();
		endtask
     class chnl_agent;
     	local string name;
     	chnl_driver driver;
     	chnl_monitor monitor;
     	local virtual chnl_intf intf;
     	//-------------------------------------------------
     	function new(string name = "");
     	endfunction
     	
     	fuction viod set_interface(virtual chnl_inft intf)
     	endfunction
     	//-------------------------------------------------
     	task tun();
     		fork
     			driver.run();
     			monitor.run();
     		jion
		endtask
 endpackage
  1. fmt_pkg
    formater模块的功能是模拟一个与设计相符的buffer。
 package fmt_pkg;
     class fmt_transclass fmt_driverclass fmt_genneratorclass fmt_monitorclass fmt_agent;
 endpackage
  1. reg_pkg
    reg模块的功能是向寄存器发送读写数据。
 package reg_pkg;
     class reg_transclass reg_driverclass reg_genneratorclass reg_monitorclass reg_agent;
 endpackage
  1. rpt_pkg
    report模块的功能是提供一些打印消息的函数,若使用UVM则无须此模块。
  2. mcdf_pkg
    mcdf模块是验证环境的顶层模块,包括env的搭建与测试案例的编写。
 package mcdf_pkg;
     class mcdf_refmod;
      	local string name;
     	local virtual mcdf_intf intf;
     	mcdf_reg_t regd[3];
     	mailbox#(reg_trans)reg_mb;
     	mailbox#(mon_data_t)in_mb[3];
     	mailbox#(fmt_trans)out_mb[3];
     	//-------------------------------------------------
     	function new(string name = "");
     	endfunction
     	
     	fuction viod set_interface(virtual chnl_inft intf)
     	endfunction
		//-------------------------------------------------
		task run();
			fork 
			jion
		endtask
     class mcdf_checker;
     	local string name;
    	local virtual chnl_intf intf;
    	local virtual arb_intf intf;
     	local virtual mcdf_intf intf;
     	local mcdf_refmod refmod;
     	mcdf_reg_t regd[3];
     	mailbox#(mon_data_t)chnl_mbs[3];
     	mailbox#(fmt_trans)fmt_mb;
     	mailbox#(reg_trans)reg_mb;
     	mailbox#(fmt_trans)exp_mbs[3];
     	//-------------------------------------------------
     	function new(string name = "");
     		this.fmt_mb = new();
     		this.reg_mb = new();
     		this.fmt_mb = new();
     		foreach(this.chnl_mbs[i])this.chnl_mbs[i] = new();
     		//================================================
     		foreach(this.refmod.in_mbs[i])
     			this.chnl_mbs[i] = new();
     			this.chnl_mbs[i] = new();
     		this.refmod.reg_mb = this.reg_mb;
     	endfunction
     	
     	fuction viod set_interface(virtual mcdf_inft mcdf_vif, virtual chnl_inft intf[3], virtual arb_inft arb_vif)
     	endfunction
     	//-------------------------------------------------
     	task run();
     	endtask
     class mcdf_coverage;
     	local -----------------;
     	fuction viod set_interface(virtual mcdf_inft mcdf_vif, virtual chnl_inft intf[3], virtual arb_inft arb_vif, virtual reg_inft reg_vif, virtual fmt_inft fmt_vif)
     	endfunction
     	//-------------------------------------------------
		covergroup cg_mcdf_reg_write_read;
			addr: coverpoint reg_vif.mon_vk.cmd_addr{
			
			}
		endgroup
		task run();
			fork
				this.do_reg_sample();
			join
		endtask
     class mcdf_env;
     	chnl_agent chnl_agts[3];
    	reg_agent reg_agt;
    	fmt_agent fmt_agt;
    	mcdf_checker chker;
    	mcdf_coverage cvrg;
    	protected string name;
    	//-------------------------------------------------
    	function new(string name = "mcdf_env");
      		this.name = name;
      		this.chker = new();
     		 foreach(chnl_agts[i]) begin
        		this.chnl_agts[i] = new($sformatf("chnl_agts[%0d]",i));
        		this.chnl_agts[i].monitor.mon_mb = this.chker.chnl_mbs[i];
      		end
      		this.reg_agt = new("reg_agt");
      		this.reg_agt.monitor.mon_mb = this.chker.reg_mb;
      		this.fmt_agt = new("fmt_agt");
      		this.fmt_agt.monitor.mon_mb = this.chker.fmt_mb;
      		this.cvrg = new();
    	endfunction
    	virtual function void do_report();
    	endfunction
    	//-------------------------------------------------
    	virtual task run();
    		this.do_config();
      		fork
        		this.chnl_agts[0].run();
        		this.chnl_agts[1].run();
        		this.chnl_agts[2].run();
        		this.reg_agt.run();
        		this.fmt_agt.run();
        		this.chker.run();
        		this.cvrg.run();
      		join
    	endtask
     class mcdf_tc_base;
     	chnl_generator chnl_gens[3];
    	reg_generator reg_gen;
    	fmt_generator fmt_gen;
    	mcdf_env env;
    	protected string name;
    	//-------------------------------------------------
    	function new(string name = "mcdf_base_test");
      		this.name = name;
      		this.env = new("env");
      		foreach(this.chnl_gens[i]) begin
        		this.chnl_gens[i] = new();
        		this.env.chnl_agts[i].driver.req_mb = this.chnl_gens[i].req_mb;
        		this.env.chnl_agts[i].driver.rsp_mb = this.chnl_gens[i].rsp_mb;
      		end
      		this.reg_gen = new();
      		this.env.reg_agt.driver.req_mb = this.reg_gen.req_mb;
      		this.env.reg_agt.driver.rsp_mb = this.reg_gen.rsp_mb;
      		this.fmt_gen = new();
      		this.env.fmt_agt.driver.req_mb = this.fmt_gen.req_mb;
      		this.env.fmt_agt.driver.rsp_mb = this.fmt_gen.rsp_mb;
    	endfunction
    	virtual task run();
    		fork 
    			env.run();
    		join_none
    			this.do_reg();
				this.do_formatter();
    	endtask
    	class mcdf_data_consistence_basic_test extends mcdf_tc_base;
    		function new(string name = "mcdf_data_consistence_basic_test");
      			super.new(name);
    		endfunction
    		//-------------------------------------------------
    		task do_reg();
    		 	void'(this.diff_value(wr_val, rd_val, "SLV2_WR_REG"));
    		endtask
    		task do_formatter();
    			void'(fmt_gen.randomize() with {fifo == LONG_FIFO; bandwidth == HIGH_WIDTH;});
      			fmt_gen.start();
    		endtask
    		task do_data();
      			void'(chnl_gens[0].randomize() with {ntrans==100; ch_id==0; data_nidles==0; pkt_nidles==1; data_size==8; });
      			void'(chnl_gens[1].randomize() with {ntrans==100; ch_id==1; data_nidles==1; pkt_nidles==4; data_size==16;});
      			void'(chnl_gens[2].randomize() with {ntrans==100; ch_id==2; data_nidles==2; pkt_nidles==8; data_size==32;});
      			fork
        			chnl_gens[0].start();
        			chnl_gens[1].start();
        			chnl_gens[2].start();
      			join
      			#10us; // wait until all data haven been transfered through MCDF
    	endtask
 endpackage
  1. tb
    tb在最顶层的模块,负责例化dut与选择使用的测试案例。
interface chnl_intf(input clk, input rstn);
	logic   ---------------;
	clocking drv_ck@(posedeg clk);
	endclocking
	clocking mon_ck@(posedeg clk);
	endclocking
endinterface

interface reg_intf(input clk, input rstn);
	logic   ---------------;
	clocking drv_ck@(posedeg clk);
	endclocking
	clocking mon_ck@(posedeg clk);
	endclocking
endinterface

interface arb_intf(input clk, input rstn);
	logic   ---------------;
	clocking mon_ck@(posedeg clk);
	endclocking
endinterface

interface fmt_intf(input clk, input rstn);
	logic   ---------------;
	clocking drv_ck@(posedeg clk);
	endclocking
	clocking mon_ck@(posedeg clk);
	endclocking
endinterface

interface mcdf_intf(input clk, input rstn);
	logic   ---------------;
	clocking mon_ck@(posedeg clk);
	endclocking
endinterface

module top;

	initial begin 
		if($value$plusargs("TESTNAME=%s", name)) begin
        	tests[name].set_interface(chnl0_if, chnl1_if, chnl2_if, reg_if, arb_if, fmt_if, mcdf_if);
        	tests[name].run();
     	end
endmodule
  1. MCDF 中任意一个功能模块的验证结构如下图所示。这里需要说明的是:将1/2号邮箱的连接放在测试案例中是为了在顶层操作方便,便于设计。
    在这里插入图片描述
    整个mcdf的验证流程如下图:
    在这里插入图片描述
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值