[CU]uvm lab6-router

注1:uvm lab1 - __见贤思齐 - 博客园 (cnblogs.com)

注2:uvm lab2 - __见贤思齐 - 博客园 (cnblogs.com)

注3:uvm lab3 - __见贤思齐 - 博客园 (cnblogs.com)

注4:uvm lab4 - __见贤思齐 - 博客园 (cnblogs.com)

注5:uvm lab5 - __见贤思齐 - 博客园 (cnblogs.com)

注6:synopsys uvm1.2 lab guide - IC验证资料 - EETOP 创芯网论坛 (原名:电子顶级开发网) -

注7:uvm1.2 lab链接UVM1.2 Lab验证资料(入门必备) - IC验证资料 - EETOP 创芯网论坛 (原名:电子顶级开发网) -

学习目标

(1) register model的构建与使用;

1.test.sv

(1) config_db::set()或resource_db::set()的使用;

 1 program automatic test;
 2 import uvm_pkg::*;
 3 
 4 `include "test_collection.sv"
 5 
 6 initial begin
 7   //interface的config_db::set()/resource_db::set()可以放置到该initial begin end块中;
 8   uvm_resource_db#(virtual router_io)::set("router_vif","",router_test_top.router_if);
 9   uvm_resource_db#(virtual reset_io)::set("reset_vif","",router_test_top.reset_if);
10   uvm_resource_db#(virtual host_io)::set("host_vif","",router_test_top.host_if);
11   uvm_reg::include_coverage("*", UVM_CVR_ALL);
12   $timeformat(-9, 1, "ns", 10);
13   run_test();
14 end
15 
16 endprogram

2.test_collection.sv

(1) hdl_path的config_db::set();

(2) 注意raise_objection与drop_objection的第二个参数;

  1 `ifndef TEST_COLLECTION__SV
  2 `define TEST_COLLECTION__SV
  3 
  4 `include "router_env.sv"
  5 
  6 class test_base extends uvm_test;
  7   `uvm_component_utils(test_base)
  8 
  9   router_env env;
 10   virtual router_io router_vif;
 11   virtual reset_io  reset_vif;
 12   virtual host_io   host_vif;
 13     
 14   top_reset_sequencer top_reset_sqr;
 15     
 16   function new(string name, uvm_component parent);
 17     super.new(name, parent);
 18     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
 19   endfunction
 20 
 21   virtual function void build_phase(uvm_phase phase);
 22     super.build_phase(phase);
 23     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
 24     env = router_env::type_id::create("env", this);
 25     uvm_resource_db#(virtual router_io)::read_by_type("router_vif",router_vif,this);
 26     uvm_resource_db#(virtual reset_io)::read_by_type("reset_vif",reset_vif,this);
 27 
 28     uvm_config_db#(virtual router_io)::set(this,"env.i_agt[*]","vif",router_vif);
 29     uvm_config_db#(virtual router_io)::set(this,"env.o_agt[*]","vif",router_vif);
 30     uvm_config_db#(virtual reset_io)::set(this,"env.r_agt","vif",reset_vif);
 31 
 32     top_reset_sqr=top_reset_sequencer::type_id::create("top_reset_sqr",this);
 33 
 34     uvm_resource_db#(virtual host_io)::read_by_type("host_vif",host_vif,thif);
 35     uvm_config_db#(virtual host_io)::set(this,"env.h_agt","vif",host_vif);
 36 
 37     uvm_config_db#(uvm_object_wrapper)::set(this,"env.*.sqr.reset_phase", "default_sequence",null);
 38     uvm_config_db#(uvm_object_wrapper)::set(this,"top_reset_sqr.reset_phase", "default_sequence", top_reset_sequence::get_type());
 39 
 40     uvm_config_db#(string)::set(this,"env","hdl_path","router_test_top.dut");
 41   endfunction
 42 
 43     virtual function void connect_phase(uvm_phase phase);
 44         super.connect_phase(phase);
 45 
 46         foreach(env.i_agt[i]) begin
 47             top_reset_sqqr.pkt_sqr.push_back(env.i_agt[i].sqr);
 48         end
 49     
 50         top_reset_sqr.r_sqr=env.r_agt.sqr;
 51         top_reset_sqr.h_sqr=env.h_agt.sqr;
 52     endfunction
 53 
 54     virtual function void end_of_elaboration_phase(uvm_phase phase);
 55         super.end_of_elaboration_phase(phase);
 56         env.regmodel.set_coverage(UVM_CVR_ALL);
 57     endfunction
 58 
 59     virtual task shutdown_phase(uvm_phase phase);
 60       super.shutdown_phase(phase);
 61       phase.raise_objection(this);
 62       env.sb.wait_for_done();
 63       phase.drop_objection(this);
 64     endtask: shutdown_phase
 65         
 66   virtual function void final_phase(uvm_phase phase);
 67     super.final_phase(phase);
 68     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
 69     if(uvm_report_enabled(UVM_DEBUG, UVM_INFO, "TOPOLOGY")) begin
 70         uvm_top.print_topology();
 71     end
 72     if(uvm_report_enabled(UVM_DEBUG, UVM_INFO, "FACTORY")) begin
 73         uvm_factory::get().print();
 74     end
 75   endfunction
 76 endclass
 77 
 78 `include "packet_da_3.sv"
 79 
 80 class test_da_3_inst extends test_base;
 81   `uvm_component_utils(test_da_3_inst)
 82 
 83   function new(string name, uvm_component parent);
 84     super.new(name, parent);
 85     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
 86   endfunction
 87 
 88   virtual function void build_phase(uvm_phase phase);
 89     super.build_phase(phase);
 90     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
 91     set_inst_override_by_type("env.i_agent*.seqr.*", packet::get_type(), packet_da_3::get_type());
 92   endfunction
 93 endclass
 94 
 95 class test_da_3_type extends test_base;
 96   `uvm_component_utils(test_da_3_type)
 97 
 98   function new(string name, uvm_component parent);
 99     super.new(name, parent);
100     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
101   endfunction
102 
103   virtual function void build_phase(uvm_phase phase);
104     super.build_phase(phase);
105     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
106     set_type_override_by_type(packet::get_type(), packet_da_3::get_type());
107   endfunction
108 endclass
109 
110 class test_da_3_seq extends test_base;
111   `uvm_component_utils(test_da_3_seq)
112 
113   function new(string name, uvm_component parent);
114     super.new(name, parent);
115     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
116   endfunction
117 
118   virtual function void build_phase(uvm_phase phase);
119     super.build_phase(phase);
120     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
121     uvm_config_db#(bit[15:0])::set(this, "env.i_agent*.seqr", "da_enable", 16'h0008);
122     uvm_config_db#(int)::set(this, "env.i_agent*.seqr", "item_count", 20);
123   endfunction
124 endclass
125 
126 class test_host_bfm extends test_base;
127     `uvm_component_utils(test_host_bfm)
128     function new(string name, uvm_component parent);
129         super.new(name,parent);
130     endfunction
131 
132     virtual function void build_phase(uvm_phase phase);
133         super.build_phase(phase);
134 
135         uvm_config_db#(uvm_object_wrapper)::set(this,"env.*.configure_phase","default_sequence",null);
136         uvm_config_db#(uvm_object_wrapper)::set(this,"env.*.main_phase","default_sequence",null);
137         uvm_config_db#(uvm_object_wrapper)::set(this,"env.h_agt.sqr.main_phase","default_sequence",host_bfm_sequence::get_type());
138     endfunction: build_phase
139 endclass: test_host_bfm
140 
141 class test_host_ral extends test_base;
142     `uvm_component_utils(test_host_ral)
143     function new(string name, uvm_component parent);
144         super.new(name,parent);
145     endfunction
146 
147     virtual function void build_phase(uvm_phase phase);
148         super.build_phase(phase);
149 
150         uvm_config_db#(uvm_object_wrapper)::set(this,"env.*.configure_phase","default_sequence",null);
151         uvm_config_db#(uvm_object_wrapper)::set(this,"env.*.main_phase","default_sequence",null);
152         uvm_config_db#(uvm_object_wrapper)::set(this,"env.h_agt.sqr.main_phase","default_sequence",host_ral_test_sequence::get_type());
153     endfunction: build_phase
154 endclass: test_host_ral
155 
156 class test_ral_selftest extends test_base;
157     `uvm_component_utils(test_ral_selftest)
158     string seq_name="uvm_reg_bit_bash_seq";
159     uvm_reg_sequence selftest_seq;
160     top_reset_sequence top_reset_seq;
161 
162     function new(string name, uvm_component parent);
163         super.new(name,parent);
164     endfunction
165 
166     virtual function void build_phase(uvm_phase phase);
167         super.build_phase(phase);
168 
169         uvm_config_db#(uvm_object_wrapper)::set(this,"*","default_sequence",null);
170     endfunction: build_phase
171 
172     virtual task run_phase(uvm_phase phase);
173         phase.raise_objection(this, "starting reset tests");
174         top_reset_seq=top_reset_sequence::type_id::create("top_reset_seq",this);
175         top_reset_seq.start(top_reset_sqr);
176         clp.get_arg_value("+seq=",seq_name);
177         $cast(selftest_seq, uvm_factory::get().create_object_by_name(seq_name));
178         selftest_seq.model=env.regmodel;
179         selftest_seq.start(env.h_agt.sqr);
180         phase.drop_objection(this,"Done with register tests");
181     endtask: run_phase
182 
183 endclass: test_ral_selftest

3.router_env.sv

(1) regmodel, adapter, predictor的声明及例化;

(2) connect_phase内,建立regmodel的uvm_reg_map与uvm_reg_adapter, bus_sequencer的联系,建立predictor与uvm_reg_map, uvm_reg_adapter以及bus_agent的联系;

 1 `ifndef ROUTER_ENV__SV
 2 `define ROUTER_ENV__SV
 3 
 4 `include "input_agent.sv"
 5 `include "reset_agent.sv"
 6 `include "output_agent.sv"
 7 `include "ms_scoreboard.sv"
 8 
 9 `include "host_agent.sv"
10 
11 
12 class router_env extends uvm_env;
13   `uvm_component_utils(router_env)
14 
15   reset_agent  r_agent;
16   input_agent  i_agent[16];
17   scoreboard   sb;
18   output_agent o_agent[16];
19   host_agent   h_agent;
20 
21 ral_block_host_regmodel regmodel; //regmodel
22 reg_adapter  adapter;                //adapter23 
24   typedef uvm_reg_predictor #(host_data) hreg_predictor;
25 hreg_predictor hreg_predictor;       //predictor26 
27   function new(string name, uvm_component parent);
28     super.new(name, parent);
29     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
30   endfunction
31 
32   virtual function void build_phase(uvm_phase phase);
33     super.build_phase(phase);
34     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
35 
36     r_agent = reset_agent::type_id::create("r_agent", this);
37     uvm_config_db #(uvm_object_wrapper)::set(this, {r_agent.get_name(), ".", "seqr.reset_phase"}, "default_sequence", reset_sequence::get_type());
38 
39     foreach (i_agent[i]) begin
40       i_agent[i] = input_agent::type_id::create($sformatf("i_agent[%0d]", i), this);
41       uvm_config_db #(int)::set(this, i_agent[i].get_name(), "port_id", i);
42       uvm_config_db #(uvm_object_wrapper)::set(this, {i_agent[i].get_name(), ".", "seqr.main_phase"}, "default_sequence", router_input_port_reset_sequence::get_type());
43       uvm_config_db #(uvm_object_wrapper)::set(this, {i_agent[i].get_name(), ".", "seqr.main_phase"}, "default_sequence", packet_sequence::get_type());
44     end
45 
46     sb = scoreboard::type_id::create("sb", this);
47 
48     foreach (o_agent[i]) begin
49       o_agent[i] = output_agent::type_id::create($sformatf("o_agent[%0d]",i),this);
50       uvm_config_db #(int)::set(this, o_agent[i].get_name(), "port_id", i);
51     end
52 
53     h_agent = host_agent::type_id::create("h_agent", this);
54     adapter = reg_adapter::type_id::create("adapter",this);        //adapter的例化;55 
56     uvm_config_db #(ral_block_host_regmodel)::get(this, "", "regmodel", regmodel);
57 
58     if (regmodel == null) begin
59       string hdl_path;
60       if (!uvm_config_db #(string)::get(this, "", "hdl_path", hdl_path)) begin
61         `uvm_warning("HOSTCFG", "HDL path for backdoor not set!");
62       end
63       regmodel = ral_block_host_regmodel::type_id::create("regmodel", this);
64       regmodel.build();
65       regmodel.lock_model();
66       regmodel.set_hdl_path_root(hdl_path);
67     end
68 
69     uvm_config_db#(ral_block_host_regmodel)::set(this, h_agt.get_name(), "regmodel", regmodel);
70     uvm_config_db#(uvm_object_wrapper)::set(this,{h_agt.get_name(), ".", "sqr.configure_phase"}, "default_sequence", ral_port_unlock_sequence::get_type());
71     hreg_predict=hreg_predictor::type_id::create("h_reg_predict",this);   //predictor的例化;
72   endfunction
73 
74   virtual function void connect_phase(uvm_phase phase);
75     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
76     foreach (i_agent[i]) begin
77       i_agent[i].analysis_port.connect(sb.before_export);
78     end
79     foreach (o_agent[i]) begin
80       o_agent[i].analysis_port.connect(sb.after_export);
81     end
82 
83 regmodel.default_map.set_sequencer(h_agent.seqr, adapter);
84 
85     regmodel.default_map.set_auto_predict(0);
86     hreg_predict.map=regmodel.get_default_map();
87     hreg_predict.adapter=adapter;
88     h_agt.analysis_port.connect(hreg_predict.bus_in);
89   endfunction
90 endclass
91 
92 `endif

4.top_reset_sequence.sv

 1 class top_reset_sequence extends uvm_sequence;
 2     `uvm_object_utils(top_reset_sequence)
 3     `uvm_declare_p_sequencer(top_reset_sequencer)
 4 
 5     reset_sequence  r_seq;
 6     router_input_port_reset_sequence i_seq;
 7     host_reset_sequence h_seq;
 8     uvm_event reset_event=uvm_event_pool::get_global("reset");
 9 
10     function new(string name="top_reset_sequence");
11         super.new(name);
12         `uvm_info("TRACE",$sformatf("%m"),UVM_HIGH)
13         `ifdef UVM_POST_VERSION_1_1
14         set_automatic_phase_objection(1);
15         `endif
16     endfunction
17 
18     virtual task body();
19         `uvm_info("TRACE",$sformatf("%m"),UVM_HIGH)
20         fork
21             `uvm_do_on(r_seq,p_sequencer.r_sqr);
22             foreach(p_sequencer.pkt_sqr[i]) begin
23                 fork
24                     int j=i;
25                     begin
26                         reset_event.wait_on();//该处采用了wait_on()而不是wait_trigger,与sequence和driver行为相关;
27                         `uvm_do_on(i_seq,p_sequencer.pkt_sqr[j]);
28                     end
29                 join_none
30             end
31             begin
32                 reset_event.wait_on();
33                 `uvm_do_on(h_seq, p_sequencer.h_sqr)
34             end
35         join
36     endtask
37 
38     `ifdef UVM_VERSION_1_1
39     virtual task pre_start();
40         `uvm_info("TRACE",$sformatf("%m"),UVM_HIGH)
41         if((get_parent_sequence()==null) && (starting_phase!=null))
42             starting_phase.raise_objection(this);
43     endtask
44     virtual task post_start();
45         `uvm_info("TRACE",$sformatf("%m"),UVM_HIGH)
46         if((get_parent_sequence()==null) && (starting_phase!=null))
47             starting_phase.raise_objection(this);
48     endtask
49     `endif
50 endclass

5.host_data & reg_adapter

5.1 host_data

 1 class host_data extends uvm_sequence_item;
 2   typedef enum {READ, WRITE} kind_e;
 3   rand kind_e    kind;
 4     rand uvm_status_e status;
 5   rand bit[15:0] addr;
 6   rand bit[15:0] data;
 7  
 8   `uvm_object_utils_begin(host_data)
 9     `uvm_field_int(addr, UVM_ALL_ON)
10     `uvm_field_int(data, UVM_ALL_ON)
11     `uvm_field_enum(kind_e, kind, UVM_ALL_ON)
12         `uvm_field_enum(uvm_status_e, status, UVM_ALL_ON)
13   `uvm_object_utils_end
14 
15   function new(string name="host_data");
16     super.new(name);
17     `uvm_info("Trace", $sformatf("%m"), UVM_HIGH);
18         status.rand_mode(0);
19   endfunction
20 endclass

5.2 reg_adapter

 1 class reg_adapter extends uvm_reg_adapter;
 2   `uvm_object_utils(reg_adapter)
 3 
 4   function new(string name="reg_adapter");
 5     super.new(name);
 6     `uvm_info("Trace", $sformatf("%m"), UVM_HIGH);
 7   endfunction
 8 
 9   virtual function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);
10     host_data tr;
11     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
12 
13     tr = host_data::type_id::create("tr");
14     tr.kind = (rw.kind == UVM_READ) ? host_data::READ : host_data::WRITE;
15     tr.addr = rw.addr;
16     tr.data = rw.data;
17     return tr;
18 
19   endfunction
20 
21   virtual function void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);
22     host_data tr;
23     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
24 
25     if (!$cast(tr, bus_item)) begin
26       `uvm_fatal("NOT_HOST_REG_TYPE", "bus_item is not correct type");
27     end
28     rw.kind = (tr.kind == host_data::READ) ? UVM_READ : UVM_WRITE;
29     rw.addr = tr.addr;
30     rw.data = tr.data;
31     rw.status = tr.status;
32 
33   endfunction
34 endclass

6.host_sequences

6.1host_sequence_base

 1 class host_sequence_base extends uvm_sequence #(host_data);
 2   `uvm_object_utils(host_sequence_base)
 3     
 4     virtual host_io vif;
 5     uvm_sequencer_base p_sqr;
 6 
 7   function new(string name = "host_sequence_base");
 8     super.new(name);
 9     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
10   endfunction
11 
12     virtual task pre_start();
13         p_sqr=get_sequencer();
14         ...
15   endtask
16     
17   ...
18 endclass

6.2host_reset_sequence

 1 class host_reset_sequence extends host_sequence_base;
 2     `uvm_object_utils(host_reset_sequence)
 3 
 4     function new(string name="host_reset_sequence");
 5         super.new(name);
 6     endfunction
 7 
 8     virtual task body();
 9         vif.wr_n = 1'b1;
10         vif.rd_n = 1'b1;
11         vif.address = 'z;
12         vif.data = 'z;
13     endtask
14 
15 endclass

6.3host_bfm_sequence

 1 class host_bfm_sequence extends host_sequence_base;
 2   `uvm_object_utils(host_bfm_sequence)
 3 
 4   function new(string name = "host_bfm_sequence");
 5     super.new(name);
 6     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
 7   endfunction
 8 
 9   virtual task body();
10     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
11     `uvm_do_with(req, {addr == 'h0; kind == host_data::READ;});
12 
13     if(req.data != 'h5a03) begin
14         `uvm_fatal("BFM_ERR",$sformatf("HOST_ID is %4h instead of 'h5a03",req.data))
15     end
16 
17     `uvm_do_with(req, {addr == 'h100; kind == host_data::READ;});
18 
19     if(req.data != '1) begin
20          `uvm_fatal("BFM_ERR",$sformatf("HOST_ID is %4h instead of 'hffff",req.data))
21     end
22 
23     `uvm_do_with(req, {addr == 'h100; data == '0; kind == host_data::WRITE;});
24     `uvm_do_with(req, {addr == 'h100; kind == host_data::READ;});
25 
26     if(req.data != '0) begin
27         `uvm_fatal("BFM_ERR",$sformatf("HOST_ID is %4h instead of 'h0000",req.data))
28     end
29 
30   endtask
31 
32 endclass

6.4host_ral_sequence_base

(1)uvm_reg_sequence内通过config_db::set()方法获取regmodel的句柄;

 1 class host_ral_sequence_base extends uvm_reg_sequence #(host_sequence_base);
 2   `uvm_object_utils(host_ral_sequence_base)
 3   ral_block_host_regmodel regmodel;
 4 
 5   function new(string name = "host_ral_sequence_base");
 6     super.new(name);
 7     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
 8   endfunction
 9 
10   virtual task pre_start();
11         super.pre_start();
12         if(!uvm_config_db#(ral_block_host_regmodel)::get(p_sqr.get_parent(),"","regmodel", regmodel)) begin
13             `uvm_info("RAL_CFG","regmodel not set through configureation.",UVM_MEDIUM)
14             if(regmodel==null) begin
15                 `uvm_fatal("RAL_CFG","regmodel not set")
16             end
17         end
18     endtask
19 endclass

6.5host_ral_test_sequence

 1 class host_ral_test_sequence extends host_ral_sequence_base;
 2     `uvm_object_utils(host_ral_test_sequence)
 3     
 4     function new(string name="host_ral_test_sequence");
 5         super.new(name);
 6     endfunction
 7 
 8     virtual task body();
 9         uvm_status_e status;
10         uvm_reg_data_t data;
11 
12         regmodel.HOST_ID.read(.status(status), .value(data), .path(UVM_BACKDOOR), .parent(this));
13       ...
14     endtask
15 endclass

7.reset_sequence.sv & reset_agent.sv(省略,见uvm lab5)

8.input_agent.sv & iMonitor.sv & driver.sv(省略)

9.output_agent.sv & oMonitor.sv(省略)

10.scoreboard.sv & ms_scoreboard.sv(省略)

11.host_agent.sv & host_driver.sv & host_monitor.sv & host_sequencer.sv

  1 `ifndef HOST_AGENT__SV
  2 `define HOST_AGENT__SV
  3 
  4 `include "host_sequence.sv"
  5 
  6 typedef uvm_sequencer #(host_data) host_sequencer;
  7 typedef class host_driver;
  8 typedef class host_monitor;
  9 
 10 class host_agent extends uvm_agent;
 11   virtual host_io sigs;     // DUT host interface
 12   uvm_analysis_port #(host_data) analysis_port;
 13   host_sequencer seqr;
 14   host_driver    drv;
 15   host_monitor   mon;
 16 
 17   `uvm_component_utils(host_agent)
 18 
 19   function new(string name, uvm_component parent);
 20     super.new(name, parent);
 21     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
 22   endfunction
 23 
 24   virtual function void build_phase(uvm_phase phase);
 25     super.build_phase(phase);
 26     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
 27 
 28     // The agent retrieves virtual interface.
 29     uvm_config_db#(virtual host_io)::get(this, "", "host_io", sigs);
 30 
 31     if (is_active) begin
 32       seqr = host_sequencer::type_id::create("seqr", this);
 33       drv  = host_driver::type_id::create("drv", this);
 34       uvm_config_db#(virtual host_io)::set(this, "drv", "host_io", sigs);
 35       uvm_config_db#(virtual host_io)::set(this, "seqr", "host_io", sigs);
 36     end
 37     mon = host_monitor::type_id::create("mon", this);
 38     uvm_config_db#(virtual host_io)::set(this, "mon", "host_io", sigs);
 39   endfunction
 40 
 41   virtual function void connect_phase(uvm_phase phase);
 42     super.connect_phase(phase);
 43     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
 44     if (is_active) begin
 45       drv.seq_item_port.connect(seqr.seq_item_export);
 46     end
 47   endfunction
 48 endclass
 49 
 50 class host_driver extends uvm_driver #(host_data);
 51   virtual host_io sigs;
 52   event go;
 53 
 54   `uvm_component_utils(host_driver)
 55 
 56   function new(string name, uvm_component parent);
 57     super.new(name, parent);
 58     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
 59   endfunction
 60 
 61   virtual function void build_phase(uvm_phase phase);
 62     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
 63     if (!uvm_config_db#(virtual host_io)::get(this, "", "host_io", sigs)) begin
 64       `uvm_fatal("CFGERR", "DUT host interface not set");
 65     end
 66   endfunction
 67 
 68   virtual task pre_reset_phase(uvm_phase phase);
 69     sigs.wr_n    = 'x;
 70     sigs.address = 'x;
 71     sigs.data    = 'x;
 72   endtask
 73 
 74   virtual task reset_phase(uvm_phase phase);
 75     sigs.wr_n    = '1;
 76     sigs.address = '1;
 77     sigs.data    = '1;
 78   endtask
 79 
 80   virtual task post_reset_phase(uvm_phase phase);
 81 //    -> go;
 82   endtask
 83 
 84   virtual task run_phase(uvm_phase phase);
 85     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
 86 //    suspend();
 87     forever begin
 88       seq_item_port.get_next_item(req);
 89       `uvm_info("RUN", { "Before process\n", req.sprint() }, UVM_FULL);
 90       data_rw(req);
 91       `uvm_info("RUN", { "After process\n", req.sprint() }, UVM_FULL);
 92       seq_item_port.item_done();
 93     end
 94   endtask
 95 
 96   virtual task data_rw(host_data req);
 97     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
 98     case(req.kind)
 99       host_data::READ: begin
100                         sigs.wr_n = '1;
101                         sigs.cb.address <= req.addr;
102                         @(sigs.cb);
103                         req.data = sigs.cb.data;
104                     end
105       host_data::WRITE: begin
106                          sigs.wr_n = '0;
107                          sigs.data = req.data;
108                          sigs.cb.address <= req.addr;
109                          @(sigs.cb);
110                          sigs.wr_n = '1;
111                          sigs.data = 'z;
112                        end
113       default: begin `uvm_fatal("REGERR", "Not a valid Register Command"); end
114     endcase
115   endtask
116 
117   task suspend();
118     wait(go.triggered);
119   endtask
120 endclass
121 
122 class host_monitor extends uvm_monitor;
123   uvm_analysis_port #(host_data) analysis_port;
124   virtual host_io sigs;
125   event go;
126 
127   `uvm_component_utils(host_monitor)
128 
129   function new(string name, uvm_component parent);
130     super.new(name, parent);
131     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
132   endfunction
133 
134   virtual function void build_phase(uvm_phase phase);
135     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
136     if (!uvm_config_db#(virtual host_io)::get(this, "", "host_io", sigs)) begin
137       `uvm_fatal("CFGERR", "DUT host interface not set");
138     end
139     analysis_port = new("analysis_port", this);
140   endfunction
141 
142   virtual task run_phase(uvm_phase phase);
143     host_data tr;
144     suspend();
145     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
146     forever begin
147       tr = host_data::type_id::create("tr", this);
148       data_rw(tr);
149       analysis_port.write(tr);
150     end
151   endtask
152 
153   virtual task post_reset_phase(uvm_phase phase);
154     -> go;
155   endtask
156 
157   virtual task data_rw(host_data tr);
158     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
159     if(!sigs.mon.wr_n) begin
160       tr.kind = host_data::WRITE;
161       tr.addr = sigs.mon.address;
162       tr.data = sigs.mon.data;
163       `uvm_info("Got WRITE", {"\n", tr.sprint()}, UVM_DEBUG);
164       @(sigs.mon);
165     end else begin
166       fork
167         begin
168           fork
169             @(sigs.mon.wr_n);
170             @(sigs.mon.address);
171           join_any
172           disable fork;
173           tr.addr = sigs.mon.address;
174           tr.data = sigs.mon.data;
175           if(!sigs.mon.wr_n) begin
176             tr.kind = host_data::WRITE;
177             `uvm_info("Got WRITE", {"\n", tr.sprint()}, UVM_DEBUG);
178           end else begin
179             tr.kind = host_data::READ;
180             `uvm_info("Got READ", {"\n", tr.sprint()}, UVM_DEBUG);
181           end
182           @(sigs.mon);
183         end
184       join
185     end
186   endtask
187 
188   task suspend();
189     wait(go.triggered);
190   endtask
191 endclass
192 
193 `endif

12.host.ralf

 1 # This file contains the DUT register and memory definitions
 2 
 3 #
 4 # Lab 7 - Task 6
 5 # Populate each of the following register and memory specification.
 6 #
 7 register HOST_ID {
 8 #  ToDo
 9   field REV_ID {
10     bits 8;
11     access ro;
12     reset 'h03;
13   }
14   field CHIP_ID {
15     bits 8;
16     access ro;
17     reset 'h5A;
18   }
19 }
20 
21 register PORT_LOCK {
22 #  ToDo
23   field LOCK {
24     bits 16;
25     access w1c;
26     reset 'hffff;
27   }
28 }
29 
30 register REG_ARRAY {
31 #  ToDo
32   field USER_REG {
33     bits 16;
34     access rw;
35     reset 'h0;
36   }
37 }
38 
39 memory RAM {
40 #  ToDo
41   size 4k;
42   bits 16;
43   access rw;
44 }
45 
46 #
47 # The block level declaration is done for you.  This include the hdl_path name for
48 # the signals in the DUT.  Later on, the hdl_path will be in RAL backdoor access.
49 #
50 block host_regmodel {
51   bytes 2;
52   register HOST_ID        (host_id)       @'h0000;
53   register PORT_LOCK      (lock)          @'h0100;
54   register REG_ARRAY[256] (host_reg[%d])  @'h1000; # array must specify HDL index
55   memory   RAM            (ram)           @'h4000;
56 }

13.ral_host_regmodel.sv

(1) uvm_reg和uvm_reg_model的定义;

(2) add_hdl_path(), add_reg(), add_mem()的使用;

 

 

 

  1 `ifndef RAL_HOST_REGMODEL
  2 `define RAL_HOST_REGMODEL
  3 
  4 import uvm_pkg::*;
  5 
  6 class ral_reg_HOST_ID extends uvm_reg;
  7     uvm_reg_field REV_ID;
  8     uvm_reg_field CHIP_ID;
  9 
 10     function new(string name = "HOST_ID");
 11         super.new(name, 16,build_coverage(UVM_NO_COVERAGE));
 12     endfunction: new
 13    virtual function void build();
 14       this.REV_ID = uvm_reg_field::type_id::create("REV_ID");
 15       this.REV_ID.configure(this, 8, 0, "RO", 0, 8'h03, 1, 0, 1);
 16       this.CHIP_ID = uvm_reg_field::type_id::create("CHIP_ID");
 17       this.CHIP_ID.configure(this, 8, 8, "RO", 0, 8'h5A, 1, 0, 1);
 18    endfunction: build
 19 
 20     `uvm_object_utils(ral_reg_HOST_ID)
 21 
 22 endclass : ral_reg_HOST_ID
 23 
 24 
 25 class ral_reg_PORT_LOCK extends uvm_reg;
 26     rand uvm_reg_field LOCK;
 27 
 28     function new(string name = "PORT_LOCK");
 29         super.new(name, 16,build_coverage(UVM_NO_COVERAGE));
 30     endfunction: new
 31    virtual function void build();
 32       this.LOCK = uvm_reg_field::type_id::create("LOCK");
 33       this.LOCK.configure(this, 16, 0, "W1C", 0, 16'hffff, 1, 0, 1);
 34    endfunction: build
 35 
 36     `uvm_object_utils(ral_reg_PORT_LOCK)
 37 
 38 endclass : ral_reg_PORT_LOCK
 39 
 40 
 41 class ral_reg_REG_ARRAY extends uvm_reg;
 42     rand uvm_reg_field USER_REG;
 43 
 44     function new(string name = "REG_ARRAY");
 45         super.new(name, 16,build_coverage(UVM_NO_COVERAGE));
 46     endfunction: new
 47    virtual function void build();
 48       this.USER_REG = uvm_reg_field::type_id::create("USER_REG");
 49       this.USER_REG.configure(this, 16, 0, "RW", 0, 16'h0, 1, 0, 1);
 50    endfunction: build
 51 
 52     `uvm_object_utils(ral_reg_REG_ARRAY)
 53 
 54 endclass : ral_reg_REG_ARRAY
 55 
 56 
 57 class ral_mem_RAM extends uvm_mem;
 58    function new(string name = "RAM");
 59       super.new(name, `UVM_REG_ADDR_WIDTH'h1000, 16, "RW", build_coverage(UVM_NO_COVERAGE));
 60    endfunction
 61    virtual function void build();
 62    endfunction: build
 63 
 64    `uvm_object_utils(ral_mem_RAM)
 65 
 66 endclass : ral_mem_RAM
 67 
 68 
 69 class ral_block_host_regmodel extends uvm_reg_block;
 70     rand ral_reg_HOST_ID HOST_ID;
 71     rand ral_reg_PORT_LOCK PORT_LOCK;
 72     rand ral_reg_REG_ARRAY REG_ARRAY[256];
 73     rand ral_mem_RAM RAM;
 74     uvm_reg_field HOST_ID_REV_ID;
 75     uvm_reg_field REV_ID;
 76     uvm_reg_field HOST_ID_CHIP_ID;
 77     uvm_reg_field CHIP_ID;
 78     rand uvm_reg_field PORT_LOCK_LOCK;
 79     rand uvm_reg_field LOCK;
 80     rand uvm_reg_field REG_ARRAY_USER_REG[256];
 81     rand uvm_reg_field USER_REG[256];
 82 
 83     function new(string name = "host_regmodel");
 84         super.new(name, build_coverage(UVM_NO_COVERAGE));
 85     endfunction: new
 86 
 87    virtual function void build();
 88       this.default_map = create_map("", 0, 2, UVM_LITTLE_ENDIAN);
 89       this.HOST_ID = ral_reg_HOST_ID::type_id::create("HOST_ID");
 90       this.HOST_ID.build();
 91       this.HOST_ID.configure(this, null, "");
 92       this.HOST_ID.add_hdl_path('{
 93 
 94             '{"host_id", -1, -1}
 95       });
 96       this.default_map.add_reg(this.HOST_ID, `UVM_REG_ADDR_WIDTH'h0, "RW", 0);
 97       this.HOST_ID_REV_ID = this.HOST_ID.REV_ID;
 98       this.REV_ID = this.HOST_ID.REV_ID;
 99       this.HOST_ID_CHIP_ID = this.HOST_ID.CHIP_ID;
100       this.CHIP_ID = this.HOST_ID.CHIP_ID;
101       this.PORT_LOCK = ral_reg_PORT_LOCK::type_id::create("PORT_LOCK");
102       this.PORT_LOCK.build();
103       this.PORT_LOCK.configure(this, null, "");
104       this.PORT_LOCK.add_hdl_path('{
105 
106             '{"lock", -1, -1}
107       });
108       this.default_map.add_reg(this.PORT_LOCK, `UVM_REG_ADDR_WIDTH'h100, "RW", 0);
109       this.PORT_LOCK_LOCK = this.PORT_LOCK.LOCK;
110       this.LOCK = this.PORT_LOCK.LOCK;
111       foreach (this.REG_ARRAY[i]) begin
112          int J = i;
113          this.REG_ARRAY[J] = ral_reg_REG_ARRAY::type_id::create($psprintf("REG_ARRAY[%0d]",J));
114          this.REG_ARRAY[J].build();
115          this.REG_ARRAY[J].configure(this, null, "");
116          this.REG_ARRAY[J].add_hdl_path('{
117 
118             '{$psprintf("host_reg[%0d]", J), -1, -1}
119          });
120          this.default_map.add_reg(this.REG_ARRAY[J], `UVM_REG_ADDR_WIDTH'h1000+J*`UVM_REG_ADDR_WIDTH'h1, "RW", 0);
121          this.REG_ARRAY_USER_REG[J] = this.REG_ARRAY[J].USER_REG;
122          this.USER_REG[J] = this.REG_ARRAY[J].USER_REG;
123       end
124       this.RAM = ral_mem_RAM::type_id::create("RAM");
125       this.RAM.build();
126       this.RAM.configure(this, "ram");
127       this.default_map.add_mem(this.RAM, `UVM_REG_ADDR_WIDTH'h4000, "RW", 0);
128    endfunction : build
129 
130    `uvm_object_utils(ral_block_host_regmodel)
131 
132 endclass : ral_block_host_regmodel
133 
134 
135 
136 `endif

 

posted on 2022-05-04 17:36  知北游。。  阅读(406)  评论(0编辑  收藏  举报

导航