[CU]uvm lab3-router

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

注2:uvm lab2 - __见贤思齐 - 博客园 (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.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 
 9   router_env env;
10 
11   function new(string name, uvm_component parent);
12     super.new(name, parent);
13     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
14   endfunction
15 
16   virtual function void build_phase(uvm_phase phase);
17     super.build_phase(phase);
18     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
19     env = router_env::type_id::create("env", this);
20   endfunction
21 
22   virtual function void final_phase(uvm_phase phase);
23     super.final_phase(phase);
24     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
25     uvm_top.print_topology();
26 
27     factory.print();
28   endfunction
29 endclass
30 
31 `include "packet_da_3.sv"
32 
33 class test_da_3_inst extends test_base;
34   `uvm_component_utils(test_da_3_inst)
35 
36   function new(string name, uvm_component parent);
37     super.new(name, parent);
38     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
39   endfunction
40 
41   virtual function void build_phase(uvm_phase phase);
42     super.build_phase(phase);
43     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
44     set_inst_override_by_type("env.i_agent*.seqr.*", packet::get_type(), packet_da_3::get_type());
45   endfunction
46 endclass
47 
48 class test_da_3_type extends test_base;
49   `uvm_component_utils(test_da_3_type)
50 
51   function new(string name, uvm_component parent);
52     super.new(name, parent);
53     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
54   endfunction
55 
56   virtual function void build_phase(uvm_phase phase);
57     super.build_phase(phase);
58     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
59     set_type_override_by_type(packet::get_type(), packet_da_3::get_type());
60   endfunction
61 endclass
62 
63 // Lab 3 - Task 4
64 //
65 // In this task, you are expected to code the entire test class definition.
66 // Reference the above code or the lecture material if you have questions on syntax.
67 //
68 // Create a test called test_da_3_seq.
69 //
70 // In the build phase, enable only destination address 3 and set item_count to 20.
71 // (via the sequencer because, in UVM, all configuration must be done through component path)
72 // 
73 // uvm_config_db#(bit[15:0])::set(this, "env.i_agent*.seqr", "da_enable", 16'h0008);
74 // uvm_config_db#(int)::set(this, "env.i_agent*.seqr", "item_count", 20);
75 //
76 // Don't forget you will need to implement the uvm_component_utils macro and the constructor
77 //
78 // ToDo
79 
80 class test_da_3_seq extends test_base;
81   `uvm_component_utils(test_da_3_seq)
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     uvm_config_db#(bit[15:0])::set(this, "env.i_agent*.seqr", "da_enable", 16'h0008);  //见packet_sequence.sv;
92     uvm_config_db#(int)::set(this, "env.i_agent*.seqr", "item_count", 20);
93   endfunction
94 endclass
95 
96 
97 `endif

3.router_env.sv (派生于uvm_env)

 1 `ifndef ROUTER_ENV__SV
 2 `define ROUTER_ENV__SV
 3 
 4 `include "input_agent.sv"
 5 
 6 // Lab 3 - Task 7, Step 2
 7 //
 8 // To save lab time, the reset agent with its sequencer, driver and monitor has been done
 9 // for you.  You will need to add an instance of it in the environment.
10 //
11 // Include the reset_agent.sv file
12 //
13 // ToDo
14 `include "reset_agent.sv"
15 
16 
17 class router_env extends uvm_env;
18   input_agent i_agent;
19 
20   // Lab 3 - Task 7, Step 3
21   //
22   // Create an instance of reset_agent, call it r_agent
23   //
24   // ToDo
25   reset_agent r_agent;
26 
27 
28   `uvm_component_utils(router_env)
29 
30   function new(string name, uvm_component parent);
31     super.new(name, parent);
32     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
33   endfunction
34 
35   virtual function void build_phase(uvm_phase phase);
36     super.build_phase(phase);
37     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
38 
39     i_agent = input_agent::type_id::create("i_agent", this);
40     uvm_config_db #(uvm_object_wrapper)::set(this, "i_agent.seqr.main_phase", "default_sequence", packet_sequence::get_type());
41     
42     // Lab 3 - Task 7, Step 4
43     //
44     // Construct the r_agent object with the proxy create() method.
45     //
46     // ToDo
47     r_agent = reset_agent::type_id::create("r_agent", this);
48 
49 
50     // Lab 3 - Task 7, Step 5
51     //
52     // Configure r_agent's seqr to execute reset_sequence at reset_phase:
53     // uvm_config_db #(uvm_object_wrapper)::set(this, "r_agent.seqr.reset_phase", "default_sequence", reset_sequence::get_type());
54     //
55     // ToDo
56     uvm_config_db #(uvm_object_wrapper)::set(this, "r_agent.seqr.reset_phase", "default_sequence", reset_sequence::get_type());
57 
58 
59   endfunction
60 
61 endclass
62 
63 `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 class driver extends uvm_driver #(packet);
 5   `uvm_component_utils(driver)
 6 
 7   function new(string name, uvm_component parent);
 8     super.new(name, parent);
 9     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
10   endfunction
11 
12   virtual task run_phase(uvm_phase phase);
13     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
14     forever begin
15       seq_item_port.get_next_item(req);
16 
17       // Lab 3 - Task 5, Step 4
18       // Change the req.print() statement into a uvm_info message statement:
19       //
20       // ToDo
21       `uvm_info("DRV_RUN", {"\n", req.sprint()}, UVM_MEDIUM);
22 
23       seq_item_port.item_done();
24     end

5.reset_agent.sv(派生于uvm_agent)

 1 `ifndef RESET_AGENT__SV
 2 `define RESET_AGENT__SV
 3 
 4 `include "reset_sequence.sv"
 5 
 6 typedef uvm_sequencer#(reset_tr) reset_sequencer;
 7 
 8 class reset_agent extends uvm_agent;
 9   reset_sequencer seqr;
10   
11   `uvm_component_utils(reset_agent)
12 
13   function new(string name, uvm_component parent);
14     super.new(name, parent);
15     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
16   endfunction: new
17 
18   function void build_phase(uvm_phase phase);
19     super.build_phase(phase);
20     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
21 
22     seqr = reset_sequencer::type_id::create("seqr", this);
23   endfunction: build_phase
24 endclass
25 
26 `endif

6.packet_sequence.sv(派生于uvm_sequence)

  1 `ifndef PACKET_SEQUENCE__SV
  2 `define PACKET_SEQUENCE__SV
  3 
  4 `include "packet.sv"
  5 
  6 class packet_sequence extends uvm_sequence #(packet);
  7 
  8   // Lab 3 - Task 2, Step 2
  9   // Create the new fields as shown below.
 10   //
 11   //   int       item_count = 10;
 12   //   int       port_id    = -1;
 13   //   bit[15:0] da_enable  = '1;
 14   //   int       valid_da[$];
 15   //
 16   // The intent of the item_count field is to control how many packet objects
 17   // to create and pass on to the driver per execution of the body() task.
 18   //
 19   // The intent of the port_id field is to constrain the packet's source address.
 20   //
 21   // The lab DUT has 16 input ports needing to be tested.  Each input agent created
 22   // to drive a particular port will be assigned a port_id specifying which port it
 23   // should exercise.  Because of this, the sequence within an input agent when
 24   // when generating packets need to constrain the packet's source address.
 25   //
 26   // The rule for constrainint the source address shall be as follows:
 27   // If port_id is inside the range of {[0:15]}, then the source address shall be port_id.
 28   // If port_id is -1 (unconfigured), the source address shall be in the range of {[0:15]}
 29   // port_id outside the range of {-1, {[0:15]} is not allowed.
 30   //
 31   // The intent of the da_enable fields is to enable corresponding destination
 32   // addresses to be generated.  A value of 1 in a particular bit position will
 33   // enable the corresponding address as a valid address to generate.  A value of 0
 34   // prohibit the corresponding address from being generated.
 35   //
 36   // Example: if the sequence were to be configured to generate only packets
 37   // for destination address 3, then the da_enable need to be configured as:
 38   // 16'b0000_0000_0000_1000
 39   //
 40   // Note that the default value is '1, meaning that all addresses are enabled.
 41   //
 42   // To simplify the constraint coding, a corresponding set of queue, valid_da
 43   // is needed.  This queue is populated based on the value of da_enable.
 44   //
 45   // Example: if da_enable is 16'b0000_0011_0000_1000, then the valid_da queue
 46   // will populated with 3, 8 and 9.
 47   //
 48   // ToDo
 49   int       item_count = 10;
 50   int       port_id    = -1;
 51   bit[15:0] da_enable  = '1;
 52   int       valid_da[$];
 53 
 54 
 55   //
 56   // To save lab time, the `uvm_object_utils macro is filled in for you.
 57   //
 58   `uvm_object_utils_begin(packet_sequence)
 59     `uvm_field_int(item_count, UVM_ALL_ON)
 60     `uvm_field_int(port_id, UVM_ALL_ON)
 61     `uvm_field_int(da_enable, UVM_ALL_ON)
 62     `uvm_field_queue_int(valid_da, UVM_ALL_ON)
 63   `uvm_object_utils_end
 64 
 65   //
 66   // The valid_da queue must be populated with legal set of addresses as specified
 67   // by the da_enable field.  Since the first thing that the sequencer performs is
 68   // the randomization of its default_sequence, a good place to retreive the configuration
 69   // fields and populate the valid_da queue is in the pre_randomize() method.
 70   //
 71   // To simplify your code development, the code is done for you as follows:
 72   //
 73   function void pre_randomize();
 74     uvm_config_db#(int)::get(m_sequencer, "", "item_count", item_count);
 75     uvm_config_db#(int)::get(m_sequencer, "", "port_id", port_id);
 76     uvm_config_db#(bit[15:0])::get(m_sequencer, "", "da_enable", da_enable);
 77     if (!(port_id inside {-1, [0:15]})) begin
 78       `uvm_fatal("CFGERR", $sformatf("Illegal port_id value of %0d", port_id));
 79     end
 80 
 81     valid_da.delete();
 82     for (int i=0; i<16; i++)
 83       if (da_enable[i])
 84         valid_da.push_back(i);
 85   endfunction
 86 
 87   function new(string name = "packet_sequence");
 88     super.new(name);
 89     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
 90   endfunction
 91 
 92   task body();
 93     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
 94 
 95     if (starting_phase != null)
 96       starting_phase.raise_objection(this);
 97 
 98     // Lab 3 - Task 2, Step 3
 99     // Instead of hard coding the number of item to be generated, replace the
100     // hard-coded value 10 in the repeat() statement to use item_count.
101     //
102     // ToDo
103     repeat(item_count) begin
104 
105 
106       // Lab 3 - Task 2, Step 3
107       //
108       // As stated in the comment at the beginning of the file.  If the port_id is unconfigured (-1)
109       // then the legal values for the source address shall be in the range of {[0:15]}.  If the
110       // port_id is configured, then the source address shall be port_id.  This will give the test
111       // the ability to test whether or not the driver drops the packet it is not configured to drive.
112       //
113       // For destination address, the legal values should be picked out of the valid_da array.
114       //
115       // Change the following `uvm_do(req) macro to:
116       // `uvm_do_with(req, {if (port_id == -1) sa inside {[0:15]}; else sa == port_id; da inside valid_da;});
117       //
118       // ToDo
119       `uvm_do_with(req, {if (port_id == -1) sa inside {[0:15]}; else sa == port_id; da inside valid_da;});
120 
121 
122     end
123 
124     if (starting_phase != null)
125       starting_phase.drop_objection(this);
126  endtask
127 
128 endclass
129 
130 `endif

6.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

6.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

7.reset_sequence.sv(派生于uvm_sequence_item)

 1 `ifndef RESET_SEQUENCE__SV
 2 `define RESET_SEQUENCE__SV
 3 
 4 class reset_tr extends uvm_sequence_item;
 5   typedef enum {ASSERT, DEASSERT} kind_e;
 6   rand kind_e kind;
 7   rand int unsigned cycles = 1;
 8 
 9   `uvm_object_utils_begin(reset_tr)
10     `uvm_field_enum(kind_e, kind, UVM_ALL_ON)
11     `uvm_field_int(cycles, UVM_ALL_ON)
12   `uvm_object_utils_end
13 
14   function new(string name = "reset_tr");
15     super.new(name);
16     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
17   endfunction: new
18 endclass
19 
20 class reset_sequence extends uvm_sequence#(reset_tr);
21   `uvm_object_utils(reset_sequence)
22 
23   function new(string name = "reset_sequence");
24     super.new(name);
25     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
26   endfunction
27 
28   task body();
29     `uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
30 
31     if (starting_phase != null)
32       starting_phase.raise_objection(this);
33 
34     `uvm_info("RESET", "Executing Reset", UVM_MEDIUM);
35 
36     if (starting_phase != null)
37       starting_phase.drop_objection(this);
38    endtask
39 endclass
40 
41 `endif

 

posted on 2022-04-30 16:05  _见贤_思齐  阅读(306)  评论(0编辑  收藏  举报

导航