uvm通信-analysis_port使用示例2(完整uvm测试平台)

资料来源

(1) 《The UVM Primer》第16章

1.top.sv

 1 module top;
 2    import uvm_pkg::*;
 3    import   tinyalu_pkg::*;
 4 `include "tinyalu_macros.svh"
 5 `include "uvm_macros.svh"
 6    
 7    tinyalu_bfm       bfm();
 8    tinyalu DUT (.A(bfm.A), .B(bfm.B), .op(bfm.op), 
 9                 .clk(bfm.clk), .reset_n(bfm.reset_n), 
10                 .start(bfm.start), .done(bfm.done), .result(bfm.result));
11 
12 
13 initial begin
14    uvm_config_db #(virtual tinyalu_bfm)::set(null, "*", "bfm", bfm);
15    run_test();
16 end
17 
18 endmodule : top

2.tinyalu_pkg.sv

 1 package tinyalu_pkg;
 2    import uvm_pkg::*;
 3 `include "uvm_macros.svh"
 4    
 5       typedef enum bit[2:0] {no_op  = 3'b000,
 6                           add_op = 3'b001, 
 7                           and_op = 3'b010,
 8                           xor_op = 3'b011,
 9                           mul_op = 3'b100,
10                           rst_op = 3'b111} operation_t;
11    
12 
13    typedef struct {
14       byte unsigned        A;
15       byte unsigned        B;
16       operation_t op;
17    } command_s;
18 
19 
20    
21 
22 `include "coverage.svh"
23 `include "base_tester.svh"
24 `include  "random_tester.svh"
25 `include "add_tester.svh"   
26 `include "scoreboard.svh"
27 `include "command_monitor.svh"
28 `include "result_monitor.svh"
29    
30 `include "env.svh"
31 
32 `include "random_test.svh"
33 `include "add_test.svh"
34    
35 endpackage : tinyalu_pkg

3.tinyalu_bfm.sv

 1 interface tinyalu_bfm;
 2    import tinyalu_pkg::*;
 3    
 4    command_monitor command_monitor_h;
 5    result_monitor  result_monitor_h;
 6 
 7    byte         unsigned        A;
 8    byte         unsigned        B;
 9    bit          clk;
10    bit          reset_n;
11    wire [2:0]   op;
12    bit          start;
13    wire         done;
14    wire [15:0]  result;
15    operation_t  op_set;
16 
17 
18    
19    
20    assign op = op_set;
21 
22    task reset_alu();
23       reset_n = 1'b0;
24       @(negedge clk);
25       @(negedge clk);
26       reset_n = 1'b1;
27       start = 1'b0;
28    endtask : reset_alu
29    
30 
31 
32    task send_op(input byte iA, input byte iB, input operation_t iop, shortint result);
33       if (iop == rst_op) begin
34          @(posedge clk);
35          reset_n = 1'b0;
36          start = 1'b0;
37          @(posedge clk);
38          #1;
39          reset_n = 1'b1;
40       end else begin
41          @(negedge clk);
42          op_set = iop;
43          A = iA;
44          B = iB;
45          start = 1'b1;
46          if (iop == no_op) begin
47             @(posedge clk);
48             #1;
49             start = 1'b0;           
50          end else begin
51             do
52               @(negedge clk);
53             while (done == 0);
54             start = 1'b0;
55          end
56       end // else: !if(iop == rst_op)
57       
58    endtask : send_op
59 
60 
61    always @(posedge clk) begin : cmd_monitor
62       bit new_command;
63       if (!start) 
64         new_command = 1;
65       else
66         if (new_command) begin 
67  command_monitor_h.write_to_monitor(A, B, op);
68            new_command = (op == 3'b000); // handle no_op
69         end 
70    end : cmd_monitor
71 
72    always @(negedge reset_n) begin : rst_monitor
73       if (command_monitor_h != null) //guard against VCS time 0 negedge
74          command_monitor_h.write_to_monitor(A, B, rst_op);
75    end : rst_monitor
76    
77 
78    always @(posedge clk) begin : rslt_monitor
79          if (done) 
80            result_monitor_h.write_to_monitor(result);
81    end : rslt_monitor
82    
83 
84    initial begin
85       clk = 0;
86       forever begin
87          #10;
88          clk = ~clk;
89       end
90    end
91 
92 
93 endinterface : tinyalu_bfm

4.random_test.svh

 1 class random_test extends uvm_test;
 2    `uvm_component_utils(random_test);
 3 
 4    env       env_h;
 5    
 6    function new (string name, uvm_component parent);
 7       super.new(name,parent);
 8    endfunction : new
 9 
10    function void build_phase(uvm_phase phase);
11       env_h = env::type_id::create("env_h",this);
12    endfunction : build_phase
13 
14 endclass

5.env.svh

 1 class env extends uvm_env;
 2    `uvm_component_utils(env);
 3 
 4    random_tester     random_tester_h;
 5    coverage   coverage_h;
 6    scoreboard scoreboard_h;
 7    command_monitor command_monitor_h;
 8    result_monitor  result_monitor_h;
 9    
10    function new (string name, uvm_component parent);
11       super.new(name,parent);
12    endfunction : new
13 
14    function void build_phase(uvm_phase phase);
15       random_tester_h    = random_tester::type_id::create("random_tester_h",this);
16       coverage_h  =  coverage::type_id::create ("coverage_h",this);
17       scoreboard_h = scoreboard::type_id::create("scoreboard_h",this);
18       command_monitor_h   = command_monitor::type_id::create("command_monitor_h",this);
19       result_monitor_h= result_monitor::type_id::create("result_monitor_h",this);
20       
21       
22    endfunction : build_phase
23 
24    function void connect_phase(uvm_phase phase);
25       
26       result_monitor_h.ap.connect(scoreboard_h.analysis_export);
27       command_monitor_h.ap.connect(scoreboard_h.cmd_f.analysis_export);
28       command_monitor_h.ap.connect(coverage_h.analysis_export);
29 
30    endfunction : connect_phase
31    
32 endclass

6.random_test.svh

 1 `ifdef QUESTA
 2 virtual class base_tester extends uvm_component;
 3 `else
 4 class base_tester extends uvm_component;
 5 `endif
 6 
 7 `uvm_component_utils(base_tester)
 8    virtual tinyalu_bfm bfm;
 9 
10    function void build_phase(uvm_phase phase);
11       
12       if(!uvm_config_db #(virtual tinyalu_bfm)::get(null, "*","bfm", bfm))
13         $fatal("Failed to get BFM");
14    endfunction : build_phase
15 
16    pure virtual function operation_t get_op();
17 
18    pure virtual function byte get_data();
19 
20    task run_phase(uvm_phase phase);
21       byte         unsigned        iA;
22       byte         unsigned        iB;
23       operation_t                  op_set;
24       shortint     result;
25       
26       phase.raise_objection(this);
27       bfm.reset_alu();
28       repeat (1000) begin : random_loop
29          op_set = get_op();
30          iA = get_data();
31          iB = get_data();
32          bfm.send_op(iA, iB, op_set, result);
33       end : random_loop
34       #500;
35       phase.drop_objection(this);
36    endtask : run_phase
37    
38 
39    function new (string name, uvm_component parent);
40       super.new(name, parent);
41    endfunction : new
42 
43 endclass : base_tester
44 
45 class random_tester extends base_tester;
46    `uvm_component_utils (random_tester)
47    
48    function byte get_data();
49       bit [1:0] zero_ones;
50       zero_ones = $random;
51       if (zero_ones == 2'b00)
52         return 8'h00;
53       else if (zero_ones == 2'b11)
54         return 8'hFF;
55       else
56         return $random;
57    endfunction : get_data
58 
59    function operation_t get_op();
60       bit [2:0] op_choice;
61       op_choice = $random;
62       case (op_choice)
63         3'b000 : return no_op;
64         3'b001 : return add_op;
65         3'b010 : return and_op;
66         3'b011 : return xor_op;
67         3'b100 : return mul_op;
68         3'b101 : return no_op;
69         3'b110 : return rst_op;
70         3'b111 : return rst_op;
71       endcase // case (op_choice)
72    endfunction : get_op
73 
74    function new (string name, uvm_component parent);
75       super.new(name, parent);
76    endfunction : new
77 
78 endclass : random_tester

7.command_monitor.svh

 1 class command_monitor extends uvm_component;
 2    `uvm_component_utils(command_monitor);
 3 
 4   uvm_analysis_port #(command_s) ap;
 5   
 6   function void build_phase(uvm_phase phase);
 7     virtual tinyalu_bfm bfm;
 8     
 9     if(!uvm_config_db #(virtual tinyalu_bfm)::get(null, "*","bfm", bfm))
10        $fatal("Failed to get BFM");
11 
12     bfm.command_monitor_h = this;
13 
14     ap  = new("ap",this);
15 
16   endfunction : build_phase
17 
18   function void write_to_monitor(byte A, byte B, bit[2:0] op);
19     command_s cmd;
20     cmd.A = A;
21     cmd.B = B;
22     cmd.op = op2enum(op);
23     $display("COMMAND MONITOR: A:0x%2h B:0x%2h op: %s", A, B, cmd.op.name());
24     ap.write(cmd);
25   endfunction : write_to_monitor
26 
27 
28    function operation_t op2enum(bit[2:0] op);
29       case(op)
30         3'b000 : return no_op;
31         3'b001 : return add_op;
32         3'b010 : return and_op;
33         3'b011 : return xor_op;
34         3'b100 : return mul_op;
35         3'b111 : return rst_op;
36         default : $fatal($sformatf("Illegal operation on op bus: %3b",op));
37       endcase // case (op)
38    endfunction : op2enum
39 
40    function new (string name, uvm_component parent);
41       super.new(name,parent);
42    endfunction
43 
44 endclass : command_monitor

8.result_monitor.svh

 1 class result_monitor extends uvm_component;
 2    `uvm_component_utils(result_monitor);
 3 
 4    uvm_analysis_port #(shortint) ap;
 5 
 6    function void write_to_monitor(shortint r);
 7       $display ("RESULT MONITOR: resultA: 0x%0h",r);
 8       ap.write(r);
 9    endfunction : write_to_monitor
10    
11    function void build_phase(uvm_phase phase);
12     virtual tinyalu_bfm bfm;
13     if(!uvm_config_db #(virtual tinyalu_bfm)::get(null, "*","bfm", bfm))
14        $fatal("Failed to get BFM");
15     bfm.result_monitor_h = this;
16     ap  = new("ap",this);
17    endfunction : build_phase
18    
19    function new (string name, uvm_component parent);
20       super.new(name, parent);
21    endfunction : new
22 
23 endclass : result_monitor

9.coverage.svh

 1 class coverage extends uvm_subscriber #(command_s);
 2    `uvm_component_utils(coverage)
 3 
 4    byte         unsigned        A;
 5    byte         unsigned        B;
 6    operation_t  op_set;
 7 
 8    covergroup op_cov;
 9 
10       coverpoint op_set {
11          bins single_cycle[] = {[add_op : xor_op], rst_op,no_op};
12          bins multi_cycle = {mul_op};
13 
14          bins opn_rst[] = ([add_op:mul_op] => rst_op);
15          bins rst_opn[] = (rst_op => [add_op:mul_op]);
16 
17          bins sngl_mul[] = ([add_op:xor_op],no_op => mul_op);
18          bins mul_sngl[] = (mul_op => [add_op:xor_op], no_op);
19 
20          bins twoops[] = ([add_op:mul_op] [* 2]);
21          bins manymult = (mul_op [* 3:5]);
22 
23          bins rstmulrst   = (rst_op => mul_op [=  2] => rst_op);
24          bins rstmulrstim = (rst_op => mul_op [-> 2] => rst_op);
25 
26       }
27 
28    endgroup
29 
30    covergroup zeros_or_ones_on_ops;
31 
32       all_ops : coverpoint op_set {
33          ignore_bins null_ops = {rst_op, no_op};}
34 
35       a_leg: coverpoint A {
36          bins zeros = {'h00};
37          bins others= {['h01:'hFE]};
38          bins ones  = {'hFF};
39       }
40 
41       b_leg: coverpoint B {
42          bins zeros = {'h00};
43          bins others= {['h01:'hFE]};
44          bins ones  = {'hFF};
45       }
46 
47       op_00_FF:  cross a_leg, b_leg, all_ops {
48          bins add_00 = binsof (all_ops) intersect {add_op} &&
49                        (binsof (a_leg.zeros) || binsof (b_leg.zeros));
50 
51          bins add_FF = binsof (all_ops) intersect {add_op} &&
52                        (binsof (a_leg.ones) || binsof (b_leg.ones));
53 
54          bins and_00 = binsof (all_ops) intersect {and_op} &&
55                        (binsof (a_leg.zeros) || binsof (b_leg.zeros));
56 
57          bins and_FF = binsof (all_ops) intersect {and_op} &&
58                        (binsof (a_leg.ones) || binsof (b_leg.ones));
59 
60          bins xor_00 = binsof (all_ops) intersect {xor_op} &&
61                        (binsof (a_leg.zeros) || binsof (b_leg.zeros));
62 
63          bins xor_FF = binsof (all_ops) intersect {xor_op} &&
64                        (binsof (a_leg.ones) || binsof (b_leg.ones));
65 
66          bins mul_00 = binsof (all_ops) intersect {mul_op} &&
67                        (binsof (a_leg.zeros) || binsof (b_leg.zeros));
68 
69          bins mul_FF = binsof (all_ops) intersect {mul_op} &&
70                        (binsof (a_leg.ones) || binsof (b_leg.ones));
71 
72          bins mul_max = binsof (all_ops) intersect {mul_op} &&
73                         (binsof (a_leg.ones) && binsof (b_leg.ones));
74 
75          ignore_bins others_only =
76                                   binsof(a_leg.others) && binsof(b_leg.others);
77 
78       }
79 
80 endgroup
81 
82 
83    function new (string name, uvm_component parent);
84       super.new(name, parent);
85       op_cov = new();
86       zeros_or_ones_on_ops = new();
87    endfunction : new
88 
89    function void write(command_s t);
90          A = t.A;
91          B = t.B;
92          op_set = t.op;
93          op_cov.sample();
94          zeros_or_ones_on_ops.sample();
95    endfunction : write
96 
97 endclass : coverage

10.scoreboard.svh

 1 class scoreboard extends uvm_subscriber #(shortint);
 2    `uvm_component_utils(scoreboard);
 3 
 4    uvm_tlm_analysis_fifo #(command_s) cmd_f;
 5 
 6    function void build_phase(uvm_phase phase);
 7       cmd_f = new ("cmd_f", this);
 8    endfunction : build_phase
 9 
10    function void write(shortint t);
11       shortint predicted_result;
12       command_s cmd; 
13       cmd.op = no_op;
14       do
15        if (!cmd_f.try_get(cmd)) $fatal(1, "No command in self checker");
16       while ((cmd.op == no_op) || (cmd.op == rst_op));
17       
18       case (cmd.op)
19         add_op: predicted_result = cmd.A + cmd.B;
20         and_op: predicted_result = cmd.A & cmd.B;
21         xor_op: predicted_result = cmd.A ^ cmd.B;
22         mul_op: predicted_result = cmd.A * cmd.B;
23       endcase // case (op_set)
24 
25       if (predicted_result != t)
26        $error (
27      "FAILED: A: %2h  B: %2h  op: %s actual result: %4h   expected: %4h",
28          cmd.A, cmd.B, cmd.op.name(), t,  predicted_result);
29    endfunction : write         
30 
31 
32    function new (string name, uvm_component parent);
33       super.new(name, parent);
34    endfunction : new
35 
36 endclass : scoreboard

 

posted on 2022-04-13 22:33  知北游。。  阅读(186)  评论(0编辑  收藏  举报

导航