sequence中实现寄存器前门访问的4种方法

uvm_sequence中实现寄存器访问的方法

在芯片的eda仿真过程中,有的场景需要在发包控制的时候对dut的寄存器进行一些动态配置,这就需要通过寄存器模型来对相关寄存器进行读写操作。
小结三种方法如下:

  1. 通过uvm_top这个全局变量来获取;
  2. 通过p_senqencer来获取;
  3. 通过config_db机制来获取。
  4. (补充)通过uvm_reg_block::get_root_blocks方法;

1. 通过uvm_root

通过uvm_root这个uvm树的根节点来访问uvm树,进而访问寄存器模型。
uvm_root基类有一个find()的函数,可以在uvm树进行搜索,返回层级结构中对应的component的句柄。

如下例子中通过uvm_top的find函数获取到env的句柄,然后通过env实现reg_model的前门访问:

class my_seq extends uvm_sequence # (my_trans);
  	uvm_root	uvm_top;
	my_env		env;
	my_trans	trans;
	uvm_status_e	status;
	bit[31:0]		rdata;
	bit[31:0] 		wdata;

	`uvm_object_utils(my_seq)

	extern virtual task pre_body();
	extern virtual task post_body();
	extern virtual task body();
endclass

task my_seq::task body();
	uvm_top = uvm_root::get();	// 本行可以注释掉,因为uvm_top为全局变量。
	void'($cast(env, uvm_top.find("uvm_test_top.env")));

	env.reg_model.xxx_reg.read(status, rdata, UVM_FRONTDOOR);
	env.reg_model.xxx_reg.write(status, wdata, UVM_FRONTDOOR);
	repeat(10) begin
		`uvm_do(trans)
	end
endtask

(以上代码不全,只展示了关键部分)

2. 通过p_sequencer

如果验证环境中有使用了virtual_sequencer,那么可以在TC中指定使用vertual_sequencer通过启动virtual_sequence发出数据包,然后在virtual_sequence中使用p_sequencer可以获取到virutal_sequencer的句柄,进而通过get_parent获取到env的句柄,以此来访问reg_model。

class my_tc extends uvm_test;
	`uvm_component_utils(my_tc)
	my_vsqr		vsqr;
	virtual function void build_phase();
		// xxx;
		`uvm_config_db#(ubm_object_wrapper) :: set(this,
							"env.vsqr.main_phase",
							"default_sequence"
							my_virtual_sequence_base::type_id::get());		
		// xxx;
	endfunction
endclass

class my_seq extends uvm_sequence # (my_trans);
  	my_env		env;
	my_trans	trans;
	`uvm_declare_p_sequencer(my_vsqr)
	uvm_status_e	status;
	bit[31:0]		rdata;
	bit[31:0] 		wdata;

	`uvm_object_utils(my_seq)

	virtual task pre_body();
		// starting_phase.raise_objection
		if($cast(env, p_sequencer.get_parent()))  begin
			`uvm_fatal(get_type_name(), "parent of p_seqencer is not my_env type");
		end
	endtask:pre_body

	virtual task post_body();
	// starting_phase.drop_objection
	endtask:post_body

	virtual task body();
		env.reg_model.xxx_reg.write(status, wdata, UVM_FRONTDOOR);
		repeat(10) begin
			`uvm_do(trans)
		end
	endtask:body
endclass

以上代码中, p_sequencer是环境中virtual_sequencer的句柄,通过get_partent()这个函数得到环境的句柄。

3.通过config_db机制

Q1:如何传递?
一般可以在测试用例(TC)中将环境中的reg_model组件通过config_db机制传递给验证平台中的sequence。

Q2:在哪里开始传递?
build_phase建立起整个验证环境的uvm树结构;
connect_phase完成环境中各个组件的连接;
所以一般在等待uvm树建立,连接完成之后,可以在end_of_elaboration或start_of_simulation这两个function_phase()中实现config_db机制的set操作。

Q3:在哪里接受reg_model
在sequencer的prebody中实现config_db机制的接受操作。

代码:

class my_tc extends uvm_test;
	`uvm_component_utils(my_tc)
	virtual function void build_phase();
		//xxx
		//xxx
	endfunction

	virtual function void start_of_simulation();
		`uvm_cofig_db#(my_reg_model) :: set(this, "*in_agent.sqr.*", "reg_model", this.env.reg_model);
	endfunction
endclass

class my_seq extends uvm_sequence # (my_trans);
  	my_env		env;
	my_trans	trans;
	my_reg_model	reg_model;
	`uvm_declare_p_sequencer(my_vsqr)
	uvm_status_e	status;
	bit[31:0]		rdata;
	bit[31:0] 		wdata;

	`uvm_object_utils(my_seq)

	virtual task pre_body();
		// starting_phase.raise_objection
		if(!`uvm_cofig_db#(my_reg_model) :: get(null, get_full_name(), "reg_model", this.reg_model) begin
			`uvm_fatal(get_type_name(), "config_db get failed");
		end
	endtask:pre_body

	virtual task post_body();
	// starting_phase.drop_objection
	endtask:post_body

	virtual task body();
		this.reg_model.xxx_reg.write(status, wdata, UVM_FRONTDOOR);
		repeat(10) begin
			`uvm_do(trans)
		end
	endtask:body
endclass

4.通过uvm_reg_block::get_root_blocks方法

参考《uvm实战》7.8.1节

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值