[CU]uvm lab2-router

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

注2:lab1相应的makefile见IC仿真makefile示例3 - __见贤思齐 - 博客园 (cnblogs.com);

注3:结合synopsys uvm lab guide阅读;

注4:uvm1.1 lab链接第三方资源 – 路科验证 (rockeric.com).

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

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

学习目标

(1) 创建uvm transaction类;

(2) sequence内创建uvm transaction;

(3) 将sequence配置给sequencer的某一phase进行sequence的执行;

(4) 利用factory机制进行transaction的override;

1.test.sv

 1 program automatic test;
 2 import uvm_pkg::*;
 3 
 4 `include "test_collection.sv"
 5 
 6 initial begin
 7   $timeformat(-9, 1, "ns", 10);
 8   run_test();
 9 end
10 
11 endprogram

2.test_collection.sv(派生于uvm_test)

 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   router_env env;
 9 
10   function new(string name, uvm_component parent);
11     super.new(name, parent);
12     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
13   endfunction
14 
15   virtual function void build_phase(uvm_phase phase);
16     super.build_phase(phase);
17     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
18     env = router_env::type_id::create("env", this);
19   endfunction
20 
21 //
22 // The start_of_simulation_phase method from lab1 is moved to final_phase
23 // for the convinience of seeing the topology and factory registry at the
24 // end of simulation.  In practice, you should implement both phases to
25 // display the topology and the factory registry.
26 //
27   virtual function void final_phase(uvm_phase phase);
28     super.final_phase(phase);
29     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
30     uvm_top.print_topology();
31     uvm_factory::get().print();
32   endfunction
33 endclass
34 
35 // Lab 2 - Include the packet_da_3.sv file
36 //
37 // ToDo
38 `include "packet_da_3.sv"
39 
40 
41 class test_da_3_inst extends test_base;
42   `uvm_component_utils(test_da_3_inst)
43 
44   function new(string name, uvm_component parent);
45     super.new(name, parent);
46     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
47   endfunction
48 
49   virtual function void build_phase(uvm_phase phase);
50     super.build_phase(phase);
51     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
52 
53     // Lab 2 - Use instance override to configure the packet sequencer
54     //         to use packet_da_3 instead of packet
55     //
56     // ToDo
57     set_inst_override_by_type("env.i_agent*.seqr.*", packet::get_type(), packet_da_3::get_type());
58     //set_inst_override_by_type("env.i_agent.seqr.packet_sequence.req", packet::get_type(), packet_da_3::get_type());
59 
60   endfunction
61 
62 endclass
63 
64 // Optional Lab 2 - Create a test to globally set all packet instances to packet_da_3
65 
66 class test_da_3_type extends test_base;
67   `uvm_component_utils(test_da_3_type)
68 
69   function new(string name, uvm_component parent);
70     super.new(name, parent);
71     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
72   endfunction
73 
74   virtual function void build_phase(uvm_phase phase);
75     super.build_phase(phase);
76     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
77     set_type_override_by_type(packet::get_type(), packet_da_3::get_type());
78   endfunction
79 endclass
80 
81 
82 `endif

3.router_env.sv(派生于uvm_env)

 1 `ifndef ROUTER_ENV__SV
 2 `define ROUTER_ENV__SV
 3 
 4 // The files content needed by the environment must be included
 5 
 6 `include "input_agent.sv"
 7 
 8 
 9 // Lab 1 - Declare the router_env class, extended from uvm_env
10 //
11 // ToDo
12 class router_env extends uvm_env;
13 
14   // Lab 1 - Create an input_agent handle called i_agent
15   //
16   // ToDo
17   input_agent i_agent;
18 
19   `uvm_component_utils(router_env)
20 
21   function new(string name, uvm_component parent);
22     super.new(name, parent);
23     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
24   endfunction: new
25 
26   virtual function void build_phase(uvm_phase phase);
27     super.build_phase(phase);
28     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
29 
30     // Lab 1 - Construct the i_agent object using the proxy create() method
31     //
32     // ToDo
33     i_agent = input_agent::type_id::create("i_agent", this);
34 
35     // Lab 1 - Set the input sequencer to execute packet_sequence as the default_sequence in main_phase
36     //         Use uvm_config_db #(uvm_object_wrapper)::set(this, "i_agent.seqr.main_phase", "default_sequence", packet_sequence::get_type());
37     //
38     // ToDo
39     uvm_config_db #(uvm_object_wrapper)::set(this, "i_agent.seqr.main_phase", "default_sequence", packet_sequence::get_type());
40 
41   endfunction: build_phase
42 
43 endclass: router_env
44 
45 `endif

4.input_agent.sv(派生于uvm_agent)

 1 `ifndef INPUT_AGENT__SV
 2 `define INPUT_AGENT__SV
 3 
 4 // The files content needed by the agent must be included
 5 
 6 `include "packet_sequence.sv"
 7 `include "driver.sv"
 8 
 9 // Lab 1 - Use typedef to create a class called packet_sequencer from the uvm_sequencer class parameterized with packet type
10 //
11 // ToDo
12 typedef uvm_sequencer #(packet) packet_sequencer;
13 
14 // Lab 1 - Declare the input_agent class, extended from uvm_agent
15 //
16 // ToDo
17 class input_agent extends uvm_agent;
18 
19   // Lab 1 - Create a packet_sequencer handle, call it seqr
20   //
21   // ToDo
22   packet_sequencer seqr;
23 
24   // Lab 1 - Create a driver handle, call it drv
25   //
26   // ToDo
27   driver drv;
28 
29   `uvm_component_utils(input_agent)
30 
31   function new(string name, uvm_component parent);
32     super.new(name, parent);
33     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
34   endfunction: new
35 
36   virtual function void build_phase(uvm_phase phase);
37     super.build_phase(phase);
38     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
39 
40     // Lab 1 - Construct the packet_sequencer and driver objects using the proxy create() method
41     //
42     // ToDo
43     seqr = packet_sequencer::type_id::create("seqr", this);
44     drv  = driver::type_id::create("drv", this);
45 
46   endfunction: build_phase
47 
48   virtual function void connect_phase(uvm_phase phase);
49     super.connect_phase(phase);
50     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
51 
52     // Lab 1 - Connect the seq_item_port in drv to the seqr's seq_item_export
53     //
54     //  ToDo
55     drv.seq_item_port.connect(seqr.seq_item_export);
56 
57   endfunction: connect_phase
58 
59 endclass: input_agent
60 
61 `endif

4.1 driver.sv (派生于uvm_driver)

 1 `ifndef DRIVER__SV
 2 `define DRIVER__SV
 3 
 4 // Lab 1 - Declare a class driver that extends uvm_driver processing packet type
 5 //
 6 // ToDo
 7 class driver extends uvm_driver #(packet);
 8 
 9   // Since the factory registration and the constructor are the same as what
10   // you have already done.  There is no learning benefit in re-typing them.
11   // These are entered for you in all subsequence tasks and labs.
12   `uvm_component_utils(driver)
13 
14   function new(string name, uvm_component parent);
15     super.new(name, parent);
16     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
17   endfunction: new
18 
19   virtual task run_phase(uvm_phase phase);
20     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
21     forever begin
22       // seq_item_port is built into the uvm_driver base class
23       // It is typically used to pull a sequence_item from the sequencer connected to the driver
24       // You will be doing the driver to sequencer connection in the environment
25       seq_item_port.get_next_item(req);
26 
27       // Lab 1 - Call the req object's print() method to display content
28       //
29       // ToDo
30       req.print();
31 
32       // Once the driver finishes processing the requested sequence item, the driver must call item_done()
33       // to indicate to the sequencer that the sequence item has completed processing
34       seq_item_port.item_done();
35     end
36   endtask: run_phase
37 
38 endclass: driver
39 
40 `endif

5.packet_sequence.sv (派生于uvm_sequence)

(1) 注意set_automatic_phase_objection(1)的使用;

 1   // Function: set_automatic_phase_objection
 2   // Sets the 'automatically object to starting phase' bit.
 3   //
 4   // The most common interaction with the starting phase
 5   // within a sequence is to simply ~raise~ the phase's objection
 6   // prior to executing the sequence, and ~drop~ the objection
 7   // after ending the sequence (either naturally, or
 8   // via a call to <kill>). In order to 
 9   // simplify this interaction for the user, the UVM
10   // provides the ability to perform this functionality
11   // automatically.
12   //
13   // For example:
14   //| function my_sequence::new(string name="unnamed");
15   //|   super.new(name);
16   //|   set_automatic_phase_objection(1);
17   //| endfunction : new
18   //
19   // From a timeline point of view, the automatic phase objection
20   // looks like:
21   //| start() is executed
22   //|   --! Objection is raised !--
23   //|   pre_start() is executed
24   //|   pre_body() is optionally executed
25   //|   body() is executed
26   //|   post_body() is optionally executed
27   //|   post_start() is executed
28   //|   --! Objection is dropped !--
29   //| start() unblocks
30   //
31   // This functionality can also be enabled in sequences
32   // which were not written with UVM Run-Time Phasing in mind:
33   //| my_legacy_seq_type seq = new("seq");
34   //| seq.set_automatic_phase_objection(1);
35   //| seq.start(my_sequencer);
36   //
37   // Internally, the <uvm_sequence_base> uses a <uvm_get_to_lock_dap> to 
38   // protect the ~automatic_phase_objection~ value from being modified 
39   // after the reference has been read.  Once the sequence has ended 
40   // its execution (either via natural termination, or being killed),
41   // then the ~automatic_phase_objection~ value can be modified again.
42   //
43   // NEVER set the automatic phase objection bit to 1 if your sequence
44   // runs with a forever loop inside of the body, as the objection will
45   // never get dropped!
46   function void set_automatic_phase_objection(bit value);
47      m_automatic_phase_objection_dap.set(value);
48   endfunction : set_automatic_phase_objection
 1 `ifndef PACKET_SEQUENCE__SV
 2 `define PACKET_SEQUENCE__SV
 3 
 4 `include "packet.sv"
 5 
 6 // Lab 1 - Declare the class packet_sequence that extends uvm_sequence typed to packet
 7 //
 8 // ToDo
 9 class packet_sequence extends uvm_sequence #(packet);
10 
11 
12   // Since the factory registration and the constructor are the same as what
13   // you have already done.  There is no learning benefit in re-typing them.
14   // These are entered for you in all subsequence tasks and labs.
15 
16   `uvm_object_utils(packet_sequence)
17 
18   function new(string name = "packet_sequence");
19     super.new(name);
20     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH); //`ifdef UVM_POST_VERSION_1_1 set_automatic_phase_objection(1); `endif
21   endfunction: new
22 
23   // Lab 1 - Create the body task with no argument
24   // Lab 1 - Add trace statement: `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
25   // Lab 1 - Check to see if there is a starting phase
26   // Lab 1 - If yes, raise the phase objection
27   // Lab 1 - Then, generate 10 random packets
28   // Lab 1 - When done, drop the phase objection
29   // Lab 1 - Reference the lecture slides for exact syntax
30   //
31   // ToDo
32   task body();
33     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
34     if (starting_phase != null)
35       starting_phase.raise_objection(this);
36     repeat(10) begin
37       `uvm_do(req);
38     end
39     if (starting_phase != null)
40       starting_phase.drop_objection(this);
41   endtask: body
42 
43 endclass: packet_sequence
44 
45 `endif

5.1 packet.sv(派生于uvm_sequence_item)

 1 `ifndef PACKET__SV
 2 `define PACKET__SV
 3 
 4 // Lab 1 - Declare the class packet that extends uvm_sequence_item
 5 //
 6 // ToDo
 7 class packet extends uvm_sequence_item;
 8 
 9   // Lab 1 - Declare the random 4-bit sa and da fields
10   //
11   // ToDo
12   rand bit [3:0] sa, da;
13 
14   // Lab 1 - Declare the random 8-bit payload queue
15   //
16   // ToDo
17   rand bit[7:0] payload[$];
18 
19   `uvm_object_utils_begin(packet)
20     `uvm_field_int(sa, UVM_ALL_ON | UVM_NOCOMPARE)
21     `uvm_field_int(da, UVM_ALL_ON)
22     `uvm_field_queue_int(payload, UVM_ALL_ON)
23   `uvm_object_utils_end
24 
25   constraint valid {
26     payload.size inside {[1:10]};
27   }
28 
29   // Lab 1 - Create the constructor with one argument: string name="packet"
30   // Lab 1 - Call super.new() with this argument
31   // Lab 1 - Lastly, print a message with:
32   // Lab 1 - `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
33   //
34   // ToDo
35   function new(string name = "packet");
36     super.new(name);
37     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
38   endfunction: new
39 
40 
41 endclass: packet
42 `endif

5.2 packet_da_3.sv(派生于uvm_sequence_item)

 1 `ifndef PACKET_DA_3__SV
 2 `define PACKET_DA_3__SV
 3 
 4 class packet_da_3 extends packet;
 5   `uvm_object_utils(packet_da_3)
 6 
 7   // Lab 2 - set the constraint for destination address (da) to 3
 8   //
 9   // ToDo
10   constraint da_3 {
11     da == 3;
12   }
13 
14   function new(string name = "packet_da_3");
15     super.new(name);
16    `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
17   endfunction
18 endclass
19 
20 `endif

6.makefile在uvm_lab2中的使用

(1) make test=test_da_3_inst

(2) make test=test_base plus=uvm_set_inst_override=packet,packet_da_3,\*.req

(3) make test=test_base plus=uvm_set_type_override=packet,packet_da_3

 

posted on 2022-04-30 11:49  知北游。。  阅读(394)  评论(0编辑  收藏  举报

导航