电力电子转战数字IC20220728day58——uvm入门实验5

目录

UVM入门实验5

实验目标

问题清单

实验任务

1.1 实现reg2mcdf_adapter类的两个方法

1.2 在mcdf_env中声明并例化block、adapter、predictor,最后connect起来

2.1 reg block句柄的传递

2.2 mcdf_data_consistence_basic_virtual_sequence类中原来是由总线seq实现的reg读写,现在改为又rgm操作的reg读写方式

2.3 mcdf_full_random_virtual_sequence做相同的操作

3.1 利用寄存器的内建序列做测试


 

UVM入门实验5

实验目标

 

 

问题清单

  • 什么是uvm_reg类?
    • 用来例化和配置reg中各个field
  • 如何定义uvm_reg?
    • 是一个class,各个子类继承于它。子类(控制寄存器+只读寄存器)在完成field的声明后需要new函数和build函数(例化与配置都在build中)
  • 声明,例化和配置field的语句是什么?
	uvm_reg_field reserved;
	rand uvm_reg_field pkt_len;//声明域,且可以随机化
	rand uvm_reg_field prio_level;
	rand uvm_reg_field chnl_en;

	reserved   = uvm_reg_field::type_id::create("");
	pkt_len    = uvm_reg_field::type_id::create("");
	prio_level = uvm_reg_field::type_id::create("");
	chnl_en    = uvm_reg_field::type_id::create("");//例化

	reserved.configure(this, 26, 6, "RO", 0, 26'h0, 1, 0 , 0);//配置
	pkt_len.configure(this,3,3,"RW",0,3'h0,1,1,0);//前两个表示位,后面的具体数表示默认值
	prio_level.configure(this,2,1,"RW",0,2'h3,1,1,0);
	chnl_en.configure(this,1,0,"RW",0,1'h0,1,1,0);
  • 什么是uvm_reg_block?
    • 一个class包含了map,rgm和mem
  • 什么是uvm_reg_adapter?
    • 完成rgm到硬件reg的桥接,将reg_item转换成总线UVC需要的信息bus_seq_item,再由总线给到硬件reg
  • 如何编写adapter?
    • 主要是定义2个reg和bus之间的函数
class reg2mcdf_adapter extends uvm_reg_adapter;
	`uvm_object_utils()
	function new(string name ="");
		super.new(name);
		provides_responses=1;//enable了provides_responses,总线可以返回rsp的数据
	endfunction
	//预定义的,也是必须实现的,名字一个字都不能差
	function uvm_sequence_item reg2bus (const ref uvm_reg_bus_op rw);
		mcdf_bus_trans t=mcdf_bus_trnas::type_id::create("t");//创建子类对象
		t.cmd=(rw.kind == UVM_WRITE)? `WRITE : `READ;
		t.addr=rw.addr;
		t.wdata=rw.data;
		return t;//做了隐式转换
	endfunction//完成了寄存器级别操作rw到bus上的桥接,下面的func反之

	function void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);
	//从driver将数据写会sequencer,adapter从sqr拿到rsp(t)后自动调用
		mcdf_bus_trans t;
		if(!$cast(t, bus_item)) begin//父类句柄,转换成子类mcdf_bus_trans句柄
		`uvm_fatal("", "")
		return; end
		rw.kind=(t.cmd==`WRITE)? UVM_WRITE : UVM_READ;//转换后才可以访问子类对象
		rw.addr=t.addr;
		rw.data=(t.cmd==`WRITE)? t.wdata : t.rdata;
		rw.status=UVM_IS_OK;
	endfunction
endclass
  • 实现了adapter之后,如何将其集成到环境中?
    • 从test层传入寄存器模型rgm句柄,在顶层例化后通过uvm_config_db进行配置
    • rgm在创建后要调用build()函数,因为uvm_reg_block是object类型,其预定义的build()不会自动执行
    • 顶层连接时,需要将rgm的map组件和bus sequencer和adapter连接(reg信息-总线侧激励驱动-reg级别和硬件总线级别的桥接),adapter的桥接功能才可以工作
class mcdf_bus_env extends uvm_env;
	mcdf_bus_agent agent;
	mcdf_rgm rgm;
	reg2mcdf_adapter reg2mcdf;//先声明
	...//注册+例化
	function void build_phase(u p);
		agent=mcdf_bus_agent::type_id::create("", this);
		if(!uvm_config_db#(mcdf_rgm)::get(this, "", "rgm", rgm)) begin
			`uvm_info()
			rgm=mcdf_rgm::type_id::create("", this);
			end
		rgm.build();//创建,配置reg,调用各个reg的build,以及它们的field
		rgm.map.set_auto_predict();//还没集成predictor,所以调用set_auto_predict(),采用auto prediction方式
		reg2mcdf=reg2mcdf_adapter::type_id::create("");//例化adapter
	endfunction
	
	function void connect_phase(u p);
		rgm.map.set_sequencer(agent.sequencer, reg2mcdf);//!连接:将adapter连接到sequencer上
	endfunction
endclass

class test1 extends uvm_test;
	mcdf_rgm rgm;
	mcdf_bus_env env;
	...//注册+例化
	function void build_phase(u p);
		rgm=mcdf_rgm::type_id::create("", this);
		uvm_config_db#(mcdf_rgm)::set(this, "env*", "rgm", rgm)
		env=mcdf_bus_env::type_id::create("", this);
	endfunction
	task run_phase(u p); ...
endclass
  • uvm_reg_adapter和uvm_reg_block的关系?
    • block>rgm>map>adapter
  • uvm_reg_predictor是什么?
    • 跟踪寄存器值,分为自动预测ap和显式预测ep
    • 显式预测ep其实就是在物理总线上用monitor来捕捉trans,通过analysis port传递给在外部例化的predictor(集成在顶层环境),集成时需要将adapter和map的句柄也传给predictor
//和上一段代码的差别并不大,注释的部分就是新加的
class mcdf_bus_env extends uvm_env;
	mcdf_bus_agent agent;
	mcdf_rgm rgm;
	reg2mcdf_adapter reg2mcdf;
	uvm_reg_predictor mcdf2reg_predictor;//先声明
	...
	function void build_phase(u p);
		agent=mcdf_bus_agent::type_id::create("", this);
		if(!uvm_config_db#(mcdf_rgm)::get(this, "", "rgm", rgm)) begin
			`uvm_info()
			rgm=mcdf_rgm::type_id::create("", this);
			end
		rgm.build();
		mcdf2reg_predictor=uvm_reg_predictor::type_id::create("",this);//例化
		reg2mcdf=reg2mcdf_adapter::type_id::create("");
		mcdf2reg_predictor.map=rgm.map;//把rgm的map给到predictor的map
		mcdf2reg_predictor.adapter=reg2mcdf;//把rgm的adapter给到predictor的map
	endfunction
	
	function void connect_phase(u p);
		rgm.map.set_sequencer(agent.sequencer, reg2mcdf);
		agent.monitor.ap.connect(mcdf2reg_predictor.bus_in);//!连接:将adapter连接到sequencer上
	endfunction
endclass
  • adapter,block,predictor三者的关系是什么?
    • 见示意图

 

  • 如何用uvm_reg的操作方式去发送reg序列?
  • 如何用内建寄存器序列做全面的reg测试?
    • 在body()中例化内建序列,将rgm给到内建序列的model并调用序列的start即可,参数是m_sequencer
    • 放置功能覆盖率covergroup在rgm中,通过reg model generator的功能可以使生成的rgm模型自动包含各个field的功能覆盖率,rgm已经内置了方法来使能covergroup,同时调用读写方法时会自动调用covergroup::sample()完成功能覆盖率的收集
class mcdf_example_seq extends uvm_reg_sequence;
	mcdf_rgm rgm;
	`uvm_object_utils()
	`uvm_declare_p_sequencer()
	...
	task body();
		uvm_status_e status;
		uvm_reg_data_t data;
		uvm_reg_hw_reset_seq reg_rst_seq=new();//先例化
		uvm_reg_bit_bash_seq reg_bit_bas_seq=new();
		uvm_reg_access_seq reg_acc_seq=new();
		if(!uvm_config_db#(mcdf_rgm)::get(null, get_full_name(), "rgm", rgm)) begin
			`uvm_error() end
		@(negedge p_sequencer.vif.rstn);
		@(posedge p_sequencer.vif.rstn);
		`uvm_info()
		reg_rst_seq.model=rgm;//给模型
		reg_rst_seq.start(m_sequencer);//start即可
		`uvm_info()
		`uvm_info()
		reg_bit_bash_seq.model=rgm;
		reg_bit_bash_seq.start(m_sequencer);
		`uvm_info()
		`uvm_info()
		reg_acc_seq.model=rgm;
		reg_acc_seq.start(m_sequencer);
		`uvm_info()
	endtask
endclass
  • reg功能覆盖率收集方式1:内部自动收集
//缺点:默认采样所有field,不够灵活不够智能
class ctrl_reg extends uvm_reg;
	`uvm_object_utils(ctrl_reg)
	uvm_reg_field reserved;
	rand uvm_reg_field pkt_len;
	rand uvm_reg_field prio_level;
	rand uvm_reg_field chnl_en;

	covergroup value_cg;//定义一个覆盖组
			option.per_instance=1;
			reserved: coverpoint reserved.value[25:
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值