UVM验证平台

Posted 夏风喃喃

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVM验证平台相关的知识,希望对你有一定的参考价值。

参考:《UVM实战》 张强 著

文章目录

UVM 框架

DUT

1 module dut(clk,
2          rst_n,
3 		   rxd,
4 		   rx_dv,
5 		   txd,
6 		   tx_en);
7  input clk;
8  input rst_n;
9  input[7:0] rxd;
10 input rx_dv;
11 output [7:0] txd;
12 output tx_en;
13
14 reg[7:0] txd;
15 reg tx_en;
16
17 always @(posedge clk) begin
18 	if(!rst_n) begin
19 		txd <= 8'b0;
20 		tx_en <= 1'b0;
21	end
22 	else begin
23 		txd <= rxd;
24 		tx_en <= rx_dv;
25 	end
26 end
27 endmodule

testbench top

 1 `timescale 1ns/1ps
 2 `include "uvm_macros.svh"
 3 
 4 import uvm_pkg::*;
 5 `include "my_if.sv"
 6 `include "my_transaction.sv"
 7 //`include "my_sequence.sv"
 8 `include "my_driver.sv"
 9 `include "my_monitor.sv"
10 `include "my_sequencer.sv"
11 `include "my_agent.sv"
12 `include "my_model.sv"
13 `include "my_scoreboard.sv"
14 `include "my_env.sv"
15 `include "base_test.sv"
16 `include "my_case0.sv"
17 `include "my_case1.sv"
18 
19 module top_tb;
20 
21 reg clk;
22 reg rst_n;
23 reg[7:0] rxd;
24 reg rx_dv;
25 wire[7:0] txd;
26 wire tx_en;
27 
28 my_if input_if(clk, rst_n);
29 my_if output_if(clk, rst_n);
30 
31 dut my_dut(.clk(clk),
32            .rst_n(rst_n),
33            .rxd(input_if.data),
34            .rx_dv(input_if.valid),
35            .txd(output_if.data),
36            .tx_en(output_if.valid));
37 
38 initial begin
39    clk = 0;
40    forever begin
41       #100 clk = ~clk;
42    end
43 end
44 
45 initial begin
46    rst_n = 1'b0;
47    #1000;
48    rst_n = 1'b1;
49 end
50 
51 initial begin
52    //run_test("my_env");
53    run_test();
54 end
55 
56 initial begin
57    uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.env.i_agt.drv", "vif", input_if);
58    uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.env.i_agt.mon", "vif", input_if);
59    uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.env.o_agt.mon", "vif", output_if);
60 end
61 
62 endmodule

interface

 1 `ifndef MY_IF__SV
 2 `define MY_IF__SV
 3 
 4 interface my_if(input clk, input rst_n);
 5 
 6    logic [7:0] data;
 7    logic valid;
 8 endinterface
 9 
10 `endif

my_case0

 1 `ifndef MY_CASE0__SV
 2 `define MY_CASE0__SV
 3 class case0_sequence extends uvm_sequence #(my_transaction);
 4    my_transaction m_trans;
 5 
 6    function  new(string name= "case0_sequence");
 7       super.new(name);
 8    endfunction 
 9    
10    virtual task body();
11       if(starting_phase != null) 
12          starting_phase.raise_objection(this);
13       repeat (10) begin
14          `uvm_do(m_trans)
15       end
16       #100;
17       if(starting_phase != null) 
18          starting_phase.drop_objection(this);
19    endtask
20 
21    `uvm_object_utils(case0_sequence)
22 endclass
23 
24 
25 class my_case0 extends base_test;
26 
27    function new(string name = "my_case0", uvm_component parent = null);
28       super.new(name,parent);
29    endfunction 
30    extern virtual function void build_phase(uvm_phase phase); 
31    `uvm_component_utils(my_case0)
32 endclass
33 
34 
35 function void my_case0::build_phase(uvm_phase phase);
36    super.build_phase(phase);
37 
38    uvm_config_db#(uvm_object_wrapper)::set(this, 
39                                            "env.i_agt.sqr.main_phase", 
40                                            "default_sequence", 
41                                            case0_sequence::type_id::get());
42 endfunction
43 
44 `endif

base_test

 1 `ifndef BASE_TEST__SV
 2 `define BASE_TEST__SV
 3 
 4 class base_test extends uvm_test;
 5 
 6    my_env         env;
 7    
 8    function new(string name = "base_test", uvm_component parent = null);
 9       super.new(name,parent);
10    endfunction
11    
12    extern virtual function void build_phase(uvm_phase phase);
13    extern virtual function void report_phase(uvm_phase phase);
14    `uvm_component_utils(base_test)
15 endclass
16 
17 
18 function void base_test::build_phase(uvm_phase phase);
19    super.build_phase(phase);
20    env  =  my_env::type_id::create("env", this); 
21    //uvm_config_db#(uvm_object_wrapper)::set(this,
22                                            //"env.i_agt.sqr.main_phase",
23                                            //"default_sequence",
24                                            // my_sequence::type_id::get());
25 endfunction
26 
27 function void base_test::report_phase(uvm_phase phase);
28    uvm_report_server server;
29    int err_num;
30    super.report_phase(phase);
31 
32    server = get_report_server();
33    err_num = server.get_severity_count(UVM_ERROR);
34 
35    if (err_num != 0) begin
36       $display("TEST CASE FAILED");
37    end
38    else begin
39       $display("TEST CASE PASSED");
40    end
41 endfunction
42 
43 `endif

env

1  `ifndef MY_ENV__SV
2  `define MY_ENV__SV
3
4  class my_env extends uvm_env;
5 
6    my_agent   i_agt;
7    my_agent   o_agt;
8    my_model   mdl;
9    my_scoreboard scb;
10   
11   uvm_tlm_analysis_fifo #(my_transaction) agt_scb_fifo;
12   uvm_tlm_analysis_fifo #(my_transaction) agt_mdl_fifo;
13   uvm_tlm_analysis_fifo #(my_transaction) mdl_scb_fifo;
14   
15   function new(string name = "my_env", uvm_component parent);
16      super.new(name, parent);
17   endfunction
18
19   virtual function void build_phase(uvm_phase phase);
20      super.build_phase(phase);
21      i_agt = my_agent::type_id::create("i_agt", this);
22      o_agt = my_agent::type_id::create("o_agt", this);
23      i_agt.is_active = UVM_ACTIVE;
24      o_agt.is_active = UVM_PASSIVE;
25      mdl = my_model::type_id::create("mdl", this);
26      scb = my_scoreboard::type_id::create("scb", this);
27      agt_scb_fifo = new("agt_scb_fifo", this);
28      agt_mdl_fifo = new("agt_mdl_fifo", this);
29      mdl_scb_fifo = new("mdl_scb_fifo", this);
30
31   endfunction
32
33   extern virtual function void connect_phase(uvm_phase phase);
34   
35   `uvm_component_utils(my_env)
36 endclass
37
38 function void my_env::connect_phase(uvm_phase phase);
39   super.connect_phase(phase);
40   i_agt.ap.connect(agt_mdl_fifo.analysis_export);
41   mdl.port.connect(agt_mdl_fifo.blocking_get_export);
42   mdl.ap.connect(mdl_scb_fifo.analysis_export);
43   scb.exp_port.connect(mdl_scb_fifo.blocking_get_export);
44   o_agt.ap.connect(agt_scb_fifo.analysis_export);
45   scb.act_port.connect(agt_scb_fifo.blocking_get_export); 
46 endfunction
47
48 `endif
agent
 1 `ifndef MY_AGENT__SV
 2 `define MY_AGENT__SV
 3 
 4 class my_agent extends uvm_agent ;
 5    my_sequencer  sqr;
 6    my_driver     drv;
 7    my_monitor    mon;
 8    
 9    uvm_analysis_port #(my_transaction)  ap;
10    
11    function new(string name, uvm_component parent);
12       super.new(name, parent);
13    endfunction 
14    
15    extern virtual function void build_phase(uvm_phase phase);
16    extern virtual function void connect_phase(uvm_phase phase);
17 
18    `uvm_component_utils(my_agent)
19 endclass 
20 
21 
22 function void my_agent::build_phase(uvm_phase phase);
23    super.build_phase(phase);
24    if (is_active == UVM_ACTIVE) begin
25        sqr = my_sequencer::type_id::create("sqr",this);
26        drv = my_driver::type_id::create("drv", this);
27    end
28    mon = my_monitor::type_id::create("mon", this);
29 endfunction 
30 
31 function void my_agent::connect_phase(uvm_phase phase);
32    super.connect_phase(phase);
33    if(is_active == UVM_ACTIVE)begin
34         drv.seq_item_port.connect(sqr.seq_item_export);   
35    end
36    ap = mon.ap;
37 endfunction
38 
39 `endif
tarnsaction
 1 `ifndef MY_TRANSACTION__SV
 2 `define MY_TRANSACTION__SV
 3 
 4 class my_transaction extends uvm_sequence_item;
 5 
 6    rand bit[47:0] dmac;
 7    rand bit[47:0] smac;
 8    rand bit[15:0] ether_type;
 9    rand byte      pload[];
10    rand bit[31:0] crc;
11 
12    constraint pload_cons
13       pload.size >= 46;
14       //pload.size <= 1500;
15       pload.size <= 200;
16       dmac == 48'h01_02_03_04_05_06;
17       smac == 48'h60_50_40_30_20_10;
18 	  
19    
20 
21    function bit[31:0] calc_crc();
22       return 32'h0;
23    endfunction
24 
25    function void post_randomize();
26       crc = calc_crc;
27    endfunction
28 
29    //`uvm_object_utils(my_transaction)
30    `uvm_object_utils_begin(my_transaction)
31         `uvm_field_int(dmac,UVM_ALL_ON)
32         `uvm_field_int(smac,UVM_ALL_ON)
33         `uvm_field_int(ether_type,UVM_ALL_ON)
34         `uvm_field_array_int(pload,UVM_ALL_ON)
35         `uvm_field_int(crc,UVM_ALL_ON)
36    `uvm_object_utils_end
37 
38    function new(string name = "my_transaction");
39       super.new();
40    endfunction
41 
42    /*function void my_print();
43       $display("dmac = %0h", dmac);
44       $display("smac = %0h", smac);
45       $display("ether_type = %0h", ether_type);
46       for(int i = 0; i < pload.size; i++) begin
47          $display("pload[%0d] = %0h", i, pload[i]);
48       end
49       $display("crc = %0h", crc);
50    endfunction
51 
52    function void my_copy(my_transaction tr);
53       if(tr == null)
54          `uvm_fatal("my_transaction", "tr is null!!!!")
55       dmac = tr.dmac;
56       smac = tr.smac;
57       ether_type = tr.ether_type;
58       pload = new[tr.pload.size()];
59       for(int i = 0; i < pload.size(); i++) begin
60          pload[i] = tr.pload[i];
61       end
62       crc = tr.crc;
63    endfunction
64 
65    function bit my_compare(my_transaction tr);
66       bit result;
67       
68       if(tr == null)
69          `uvm_fatal("my_transaction", "tr is null!!!!")
70       result = ((dmac == tr.dmac) &&
71                 (smac == tr.smac) &&
72                 (ether_type == tr.ether_type) &&
73                 (crc == tr.crc));
74       if(pload.size() != tr.pload.size())
75          result = 0;
76       else 
77          for(int i = 0; i < pload.size(); i++) begin
78             if(pload[i] != tr.pload[i])
79                result = 0;
80          end
81       return result; 
82    endfunction*/
83 
84 endclass

85 `endif
sequence
 1 class my_sequence extends uvm_sequence #(my_transaction);
 2     my_transaction m_trans;
 3 
 4     function new(string name="my_sequence");
 5         super.new(name);
 6     endfunction
 7 
 8     virtual task body();
 9         if(starting_phase != null)
10             starting_phase.raise_objection(this);
11 
12         repeat(10) begin
13             `uvm_do(m_trans)
14         end
15         #1000;
16 
17         if(starting_phase != null)
18             starting_phase.drop_objection(this);
19     endtask
20 
21     `uvm_object_utils(my_sequence)
22 
23 endclass
sequencer
 1 `ifndef MY_SEQUENCER__SV
 2 `define MY_SEQUENCER__SV
 3 
 4 class my_sequencer extends uvm_sequencer #(my_transaction);
 5    
 6    function new(string name, uvm_component parent);
 7       super.new(name, parent);
 8    endfunction 
 9    
10    `uvm_component_utils(my_sequencer)
11 endclass
12 
13 `endif
driver
 1 `ifndef MY_DRIVER__SV
 2 `define MY_DRIVER__SV
 
 3 class my_driver extends uvm_driver#(my_transaction);
 4 
 5    virtual my_if vif;
 6 
 7    `uvm_component_utils(my_driver)
 8    function new(string name = "my_driver", uvm_component parent = null);
 9       super.new(name, parent);
10    endfunction
11 
12    virtual function void build_phase(uvm_phase phase);
13       super.build_phase(phase);
14       if(!uvm_config_db#(virtual my_if)::get(this, "", "vif", vif))
15          `uvm_fatal("my_driver", "virtual interface must be set for vif!!!")
16    endfunction
17 
18    extern task main_phase(uvm_phase phase);
19    extern task drive_one_pkt(my_transaction tr);
20 endclass
21 
22 /*task my_driver::main_phase(uvm_phase phase);
23    my_transaction tr;
24    phase.raise_objection(this);
25    vif.data <= 8'b0;
26    vif.valid <= 1'b0;
27    while(!vif.rst_n)
28       @(posedge vif.clk);
29    for(int i = 0; i < 2; i++) begin 
30       req = new("req");
31       assert(req.randomize() with pload.size == 200;
32                                   dmac == 48'h01_02_03_04_05_06;
33                                   smac == 48'h60_50_40_30_20_10;
34                                                          
35             );
36       drive_one_pkt(req);
37    end
38    repeat(5) @(posedge vif.clk);
39    phase.drop_objection(this);
40 endtask*/
41 
42 task my_driver::main_phase(uvm_phase phase);
43     vif.data <= 8'b0;
44     vif.valid <= 1'b0;
45    
46     while(!vif.rst_n)
47         @(posedge vif.clk);
48     
49     while(1)begin
50         seq_item_port.get_next_item(req);
51         drive_one_pkt(req);
52         seq_item_port.item_done();
53     end
54 endtask
55 
56 task my_driver::drive_one_pkt(my_transaction tr);
57       
58    byte unsigned data_q[];
59    int unsigned data_size;
60 
61    data_size = tr.pack_bytes(data_q)/8;//fill data_q on the order in uvm_object_utils of transaction
62    `uvm_info("my_driver","begin to drive one pkt"UVM验证平台

从零开始,搭建一个简单的UVM验证平台

UVM学习——介绍

数字IC验证学习,uvm资源库uvm componentuvm平台的结构树

UVM学习记录1:验证平台的各个组件

路科验证UVM入门与进阶详解实验1