[CU]reg model使用篇-reg model的集成方法(隐式预测&显式预测)

资料来源:

(1) 《Practical UVM step by step with IEEE》

注1: reg_model内有一个镜像值,需要确保镜像值和DUT内的寄存器值同步;无论是通过前门还是后门的方式对DUT内寄存器进行访问,reg_model内的镜像值都需要被更新,这个过程称为prediction;

注2:为了保持reg_model镜像值与DUT内寄存器值一致,存在三种bus agent集成方法,分别是隐式预测(implicit prediction),显式预测(explicit prediction)和被动预测(passive prediction);

1. 隐式预测

(1) 隐式预测仅仅需要将register model和一个或多个bus sequencers集成在一起;

(2) 隐式预测模式下,每当read/write/peek/poke操作完成后,register model会自动更新镜像值; 

(3) 这种模式简单快捷,但是可能会漏掉一些不是由register model发起的总线操作,这种情况下mirror值不会得到合适的更新;

注1:隐式预测即前文提到的auto_predict(auto_predict针对的是寄存器前门访问操作,而非后门访问操作,可查看源代码);

1 //示例1
2 class environment extends uvm_env;
3     virtual function void connect_phase(uvm_phase phase);
4         regmodel.default_map.set_auto_predict(1);
5     endfunction
6 endclass
 1 //示例2:该例子中包含uvm内建register seq的使用;
 2 class test_ral extends test_base;
 3     string                                      seq_name="uvm_reg_bit_bash_seq";
 4     uvm_reg_sequence                 selftest_seq;
 5     virtual reset_sequence  rst_seq;
 6     
 7     virtual function void build_phase(uvm_phase phase);
 8         super.build_phase();
 9         uvm_config_db #(uvm_object_wrapper)::set(this,"*","default_sequence",null);
10     endfunction
11 
12     virtual task run_phase(uvm_phase phase);
13         rst_seq=virtual_reset_sequence::type_id::create("rst_seq",this);
14         phase.raise_objection(this,"starting tests");
15         //run reset;
16         rst_seq.start(env.rst_seqr);
17         clp.get_arg_value("+seq=",seq_name);
18         //create test;
19         $cast(selftest_seq,factory.create_object_by_name(seq_name));
20         //enable auto predict;
21         env.regmodel.default_map.set_auto_predict(1);
22         selftest_seq.model=env.regmodel;
23         //run test;
24         selftest_seq.start(env.m_agent.seqr);
25         phase.drop_objection(this,"Done with tests");
26     endtask
27 endclass
28 
29 +UVM_TESTNAME=test_ral +seq=uvm_reg_hw_reset_seq
 1 //示例3
 2 class hw_reset extends test_base;
 3     reset_sequence       reset_seq;
 4     uvm_reg_hw_reset_seq reset_test;
 5 
 6     ...
 7 
 8     virtual task run_phase(uvm_phase phase);
 9         phase.raise_objection(this,"starting register tests");
10         reset_seq=reset_sequence::type_id::create("reset_seq",this);
11         reset_seq.start(env.reset_seqr);
12     
13         reset_test=uvm_reg_hw_reset_seq::type_id::create("reset_test",this);
14         reset_test.model=env.regmodel;
15         reset_test.model.set_auto_predict(1);
16         reset_test.start(null);
17         phase.drop_objection(this,"Done with register tests");
18     endfunction
19 
20 endclass
21 
22 //+UVM_TESTNAME=hw_reset

2. 显式预测

(1) 显式预测需要将register model, bus sequencers以及相应的bus monitor集成到一起;

(2) 显式预测模式下, 隐式预测被关闭(set_auto_predict(0)),镜像值由uvm_reg_predictor组件进行更新;

(2.1) predictor接收到bus monitor观察到的总线操作;

(2.2) predictor通过观测到的地址反向查找到正在被访问的register(会用到uvm_reg_map);

(2.3) predictor显式调用register的predict函数来更新镜像值;

(3) 显式预测比较复杂,但是可以看到所有的总线操作(无论是通过register model发起的寄存器访问操作,还是通过第三方bus agent发起的寄存器访问操作),因此镜像值总能得到合适的更新;

 1 //示例1
 2 class environment extend uvm_env;
 3     typedef uvm_reg_predictor #(master_data) mreg_predictor;
 4     mreg_predictor mreg_predict;
 5 
 6     virtual function void build_phase(uvm_phase phase);
 7         mreg_predictor=mreg_predictor::type_id::create("mreg_predict",this);
 8     endfunction
 9 
10     virtual function void connect_phase(uvm_phase phase);
11         mreg_predict.map=regmodel.get_default_map();
12         mreg_predict.adapter=adapter;
13         regmodel.default_map.set_auto_predict(0);
14         m_agent.analysis_port.connect(mreg_predict.bus_in);
15     endfunction
16 endclass
 1 //示例2:该例子中包含uvm内建register seq的使用;
 2 class test_ral extends test_base;
 3     string                                      seq_name="uvm_reg_bit_bash_seq";
 4     uvm_reg_sequence                 selftest_seq;
 5     virtual reset_sequence  rst_seq;
 6 
 7     virtual function void build_phase(uvm_phase phase);
 8         super.build_phase();
 9         uvm_config_db #(uvm_object_wrapper)::set(this,"*","default_sequence",null);
10     endfunction
11 
12     virtual task run_phase(uvm_phase phase);
13         rst_seq=virtual_reset_sequence::type_id::create("rst_seq",this);
14         phase.raise_objection(this,"starting tests");
15         //run reset;
16         rst_seq.start(env.rst_seqr);
17         clp.get_arg_value("+seq=",seq_name);
18         //create test;
19         $cast(selftest_seq,factory.create_object_by_name(seq_name));
20         //enable auto predict;
21         env.regmodel.default_map.set_auto_predict(0);
22         selftest_seq.model=env.regmodel;
23         //run test;
24         selftest_seq.start(env.m_agent.seqr);
25         phase.drop_objection(this,"Done with tests");
26     endtask
27 endclass
28 
29 +UVM_TESTNAME=test_ral +seq=uvm_reg_hw_reset_seq

3. 集成所需组件bus sequencer

(1) 所有集成方法(隐式预测和显式预测)都需要为register model配置一个或多个bus sequencers;

(2) uvm_reg_sequence可能直接在一个bus sequencer上发送,也可能作为virtual sequence,还可能在一个通用的sequencer上运行,该通用sequencer位于dowstream bus sequencer之上;

3.1 register sequence running on the bus sequencer

(1) register sequence通过reg model, 使用预先配置好的bus adapter产生bus sequence激励;

(2) 这种情况下, register sequence会和其他在该bus sequencer上运行的sequence竞争;

(3) 这种方式对于只有一个bus interface的情况而言,是很合适的;

(4) 使用这种方法,需要为register model内的address map设置bus adapter与bus sequencer;

 1 //示例1
 2 class block_env extends uvm_env;
 3     block_reg_model regmodel;
 4     subblk_env      subblk;
 5 
 6     virtual function void connect_phase(uvm_phase phase);
 7         ...
 8         if(regmodel.get_parent()==null) begin
 9             reg2apb_adapter reg2apb=reg2apb_adapter::type_id::create("reg2apb",get_full_name());
10             regmodel.APB.set_sequencer(apb.sequencer, reg2apb);
11             regmodel.set_auto_predict(0);
12             ...
13         end
14     endfunction
15     ...
16 
17 endclass
18 
19 class my_reg_sequence extends uvm_reg_sequence;
20     `uvm_object_utils(my_reg_sequence)
21     block_reg_model model;
22 
23     virtual task body();
24         uvm_status_e   status;
25         uvm_reg_data_t data;
26 
27         model.A.write(status,'h33,.parent(this));
28         if(status==UVM_NOT_OK) `uvm_error(...)
29         model.A.read(status,data,.parent(this));
30         if(data!='h33) `uvm_error(...)
31 
32     endtask
33 
34 endclass
35 
36 class my_test extends uvm_test;
37     block_env env;
38     virtual function void run_phase(uvm_phase phase);
39             my_reg_sequence seq=my_reg_sequence::type_id::create("seq",this);
40             seq.start(env.apb.master);
41     endfunction
42 
43 endclass

3.2 register sequence running as a virtual sequence

(1) 当DUT中的register可以通过多组物理总线接口访问, register sequence将会作为virtual sequence启动, 因为每次read/write调用时都不再指明sequencer;

(2) register model会为寄存器操作分配合适的sequencer;

(3) register sequence running as a virtual sequence与register sequence running on the bus sequencer的区别:前者有多个sequencer/adapter在register model中寄存, 此外,在调用register sequence的start method时,不指定sequencer;

 

posted on 2021-09-03 11:11  知北游。。  阅读(994)  评论(0编辑  收藏  举报

导航