sequence,sequencer的使用(完整的uvm验证平台)


资料来源

(1) 《The UVM Primer》第23章

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_bfm.sv

  1 interface tinyalu_bfm;
  2    import tinyalu_pkg::*;
  3 
  4    byte         unsigned        A;
  5    byte         unsigned        B;
  6    bit          clk;
  7    bit          reset_n;
  8    wire [2:0]   op;
  9    bit          start;
 10    wire         done;
 11    wire [15:0]  result;
 12    operation_t  op_set;
 13 
 14 
 15    assign op = op_set;
 16 
 17    task reset_alu();
 18       reset_n = 1'b0;
 19       @(negedge clk);
 20       @(negedge clk);
 21       reset_n = 1'b1;
 22       start = 1'b0;
 23    endtask : reset_alu
 24    
 25 
 26 
 27    task send_op(input byte iA, input byte iB, input operation_t iop, output shortint alu_result);
 28       if (iop == rst_op) begin
 29          @(posedge clk);
 30          reset_n = 1'b0;
 31          start = 1'b0;
 32          @(posedge clk);
 33          #1;
 34          reset_n = 1'b1;
 35       end else begin
 36          @(negedge clk);
 37          op_set = iop;
 38          A = iA;
 39          B = iB;
 40          start = 1'b1;
 41          if (iop == no_op) begin
 42             @(posedge clk);
 43             #1;
 44             start = 1'b0;           
 45          end else begin
 46             do
 47               @(negedge clk);
 48             while (done == 0);
 49             alu_result = result;
 50             start = 1'b0;
 51          end
 52       end // else: !if(iop == rst_op)
 53       
 54    endtask : send_op
 55    
 56    command_monitor command_monitor_h;
 57 
 58    function operation_t op2enum();
 59       case(op)
 60         3'b000 : return no_op;
 61         3'b001 : return add_op;
 62         3'b010 : return and_op;
 63         3'b011 : return xor_op;
 64         3'b100 : return mul_op;
 65         default : $fatal("Illegal operation on op bus");
 66       endcase // case (op)
 67    endfunction : op2enum
 68 
 69 
 70    always @(posedge clk) begin : op_monitor
 71       static bit in_command = 0;
 72       if (start) begin : start_high
 73         if (!in_command) begin : new_command
 74            command_monitor_h.write_to_monitor(A, B, op2enum());
 75            in_command = (op2enum() != no_op);
 76         end : new_command
 77       end : start_high
 78       else // start low
 79         in_command = 0;
 80    end : op_monitor
 81 
 82    always @(negedge reset_n) begin : rst_monitor
 83       if (command_monitor_h != null) //guard against VCS time 0 negedge
 84         command_monitor_h.write_to_monitor($random,0,rst_op);
 85    end : rst_monitor
 86    
 87    result_monitor  result_monitor_h;
 88 
 89    initial begin : result_monitor_thread
 90       forever begin : result_monitor_block
 91          @(posedge clk) ;
 92          if (done) 
 93            result_monitor_h.write_to_monitor(result);
 94       end : result_monitor_block
 95    end : result_monitor_thread
 96    
 97 
 98    initial begin
 99       clk = 0;
100       fork
101          forever begin
102             #10;
103             clk = ~clk;
104          end
105       join_none
106    end
107 
108 
109 endinterface : tinyalu_bfm

3.tinyalu_pkg.sv

 1 package tinyalu_pkg;
 2    import uvm_pkg::*;
 3 `include "uvm_macros.svh"
 4    
 5       typedef enum bit[2:0] {
 6                              no_op  = 3'b000,
 7                              add_op = 3'b001, 
 8                              and_op = 3'b010,
 9                              xor_op = 3'b011,
10                              mul_op = 3'b100,
11                              rst_op = 3'b111} operation_t;
12       
13 `include "sequence_item.svh"   
14 typedef uvm_sequencer #(sequence_item) sequencer;
15    
16 `include "add_sequence_item.svh"
17 `include "random_sequence.svh"
18 `include "maxmult_sequence.svh"
19 `include "reset_sequence.svh"
20 `include "runall_sequence.svh"
21 `include "add_sequence.svh"
22 `include "fibonacci_sequence.svh"
23 `include "short_random_sequence.svh"
24    
25 
26 `include "result_transaction.svh"
27 `include "coverage.svh"
28 `include "scoreboard.svh"
29 `include "driver.svh"
30 `include "command_monitor.svh"
31 `include "result_monitor.svh"
32    
33 `include "env.svh"
34 `include "parallel_sequence.svh"
35 
36 `include "tinyalu_base_test.svh"
37 `include "full_test.svh"
38 `include "fibonacci_test.svh"
39 `include "parallel_test.svh"
40    
41    
42 
43 
44    
45 endpackage : tinyalu_pkg

4.sequence_item.svh

 1 class sequence_item extends uvm_sequence_item;
 2    `uvm_object_utils(sequence_item);
 3 
 4    function new(string name = "");
 5       super.new(name);
 6    endfunction : new
 7    
 8    rand byte unsigned        A;
 9    rand byte unsigned        B;
10    rand operation_t         op;
11    shortint  unsigned       result;
12 
13    constraint op_con {op dist {no_op := 1, add_op := 5, and_op:=5, 
14                                xor_op:=5,mul_op:=5, rst_op:=1};}
15 
16    constraint data { A dist {8'h00:=1, [8'h01 : 8'hFE]:=1, 8'hFF:=1};
17       B dist {8'h00:=1, [8'h01 : 8'hFE]:=1, 8'hFF:=1};} 
18    
19    function bit do_compare(uvm_object rhs, uvm_comparer comparer);
20       sequence_item tested;
21       bit               same;
22       
23       if (rhs==null) `uvm_fatal(get_type_name(), 
24                                 "Tried to do comparison to a null pointer");
25       
26       if (!$cast(tested,rhs))
27         same = 0;
28       else
29         same = super.do_compare(rhs, comparer) && 
30                (tested.A == A) &&
31                (tested.B == B) &&
32                (tested.op == op) &&
33                (tested.result == result);
34       return same;
35    endfunction : do_compare
36 
37    function void do_copy(uvm_object rhs);
38       sequence_item RHS;
39       assert(rhs != null) else
40         $fatal(1,"Tried to copy null transaction");
41       super.do_copy(rhs);
42       assert($cast(RHS,rhs)) else
43         $fatal(1,"Faied cast in do_copy");
44       A = RHS.A;
45       B = RHS.B;
46       op = RHS.op;
47       result = RHS.result;
48    endfunction : do_copy
49 
50    function string convert2string();
51       string            s;
52       s = $sformatf("A: %2h  B: %2h   op: %s = %4h",
53                     A, B, op.name(), result);
54       return s;
55    endfunction : convert2string
56 
57 endclass : sequence_item

5.base_test & tests

 1 `ifdef QUESTA
 2 virtual class tinyalu_base_test extends uvm_test;
 3 `else 
 4 class tinyalu_base_test extends uvm_test;
 5 `endif
 6 
 7    env       env_h;
 8    sequencer sequencer_h;
 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    function void end_of_elaboration_phase(uvm_phase phase);
15       sequencer_h = env_h.sequencer_h;
16    endfunction : end_of_elaboration_phase
17 
18    function new (string name, uvm_component parent);
19       super.new(name,parent);
20    endfunction : new
21 
22 endclass
23 
24 class fibonacci_test extends tinyalu_base_test;
25    `uvm_component_utils(fibonacci_test);
26 
27    task run_phase(uvm_phase phase);
28       fibonacci_sequence fibonacci;
29       fibonacci = new("fibonacci");
30 
31       phase.raise_objection(this);
32       fibonacci.start(sequencer_h);
33       phase.drop_objection(this);
34    endtask : run_phase
35       
36    function new(string name, uvm_component parent);
37       super.new(name,parent);
38    endfunction : new
39 
40 endclass
41 
42 class parallel_test extends tinyalu_base_test;
43    `uvm_component_utils(parallel_test);
44 
45    parallel_sequence parallel_h;
46       
47    function new(string name, uvm_component parent);
48       super.new(name,parent);
49       parallel_h = new("parallel_h");
50    endfunction : new
51 
52    task run_phase(uvm_phase phase);
53       phase.raise_objection(this);
54       parallel_h.start(sequencer_h);
55       phase.drop_objection(this);
56    endtask : run_phase
57 
58 endclass
59 
60 class full_test extends tinyalu_base_test;
61    `uvm_component_utils(full_test);
62    
63    runall_sequence runall_seq;
64 
65    task run_phase(uvm_phase phase);
66       runall_seq = new("runall_seq");
67       phase.raise_objection(this);
68       runall_seq.start(null); //virtual sequence;
69       phase.drop_objection(this);
70    endtask : run_phase
71 
72 
73    function new (string name, uvm_component parent);
74       super.new(name,parent);
75    endfunction : new
76 
77 endclass

6.env.svh

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

7.driver,coverage,scoreboard略

8.fibonacci_sequence.svh

 1 class fibonacci_sequence extends uvm_sequence #(sequence_item);
 2    `uvm_object_utils(fibonacci_sequence);
 3 
 4    function new(string name = "fibonacci");
 5       super.new(name);
 6    endfunction : new
 7    
 8 
 9    task body();
10       byte unsigned n_minus_2=0;
11       byte unsigned n_minus_1=1;
12       sequence_item command;
13       
14       command = sequence_item::type_id::create("command");
15          
16       start_item(command);
17       command.op = rst_op;
18       finish_item(command);
19 
20       `uvm_info("FIBONACCI", " Fib(01) = 00", UVM_MEDIUM);
21       `uvm_info("FIBONACCI", " Fib(02) = 01", UVM_MEDIUM);
22       for(int ff = 3; ff<=14; ff++) begin //斐波那契数列
23        start_item(command);
24        command.A = n_minus_2;
25        command.B = n_minus_1;
26        command.op = add_op;
27        finish_item(command);
28        n_minus_2 = n_minus_1;
29        n_minus_1 = command.result; //command.result=command.A+command.B;
30        `uvm_info("FIBONACCI", $sformatf("Fib(%02d) = %02d", ff, n_minus_1),
31                  UVM_MEDIUM);
32       end 
33    endtask : body
34 endclass : fibonacci_sequence

9.reset_sequence.svh

 1 class reset_sequence extends uvm_sequence #(sequence_item);
 2    `uvm_object_utils(reset_sequence)
 3 
 4    sequence_item command;
 5 
 6    function new(string name = "reset");
 7       super.new(name);
 8    endfunction : new
 9 
10    task body();
11       command = sequence_item::type_id::create("command");
12       start_item(command);
13       command.op = rst_op;
14       finish_item(command);
15    endtask : body
16 endclass : reset_sequence

10.short_random_sequence.svh

 1 class short_random_sequence extends uvm_sequence #(sequence_item);
 2    `uvm_object_utils(short_random_sequence);
 3    
 4    sequence_item command;
 5 
 6    function new(string name = "short_random_sequence");
 7       super.new(name);
 8    endfunction : new
 9    
10 
11 
12    task body();
13       repeat (14) begin : short_random_loop
14          command = sequence_item::type_id::create("command");
15          start_item(command);
16          assert(command.randomize());
17          finish_item(command);
18 // Moved relative to the book example so as to show result
19     `uvm_info("SHORT RANDOM", $sformatf("random command: %s", command.convert2string), UVM_MEDIUM)
20       end : short_random_loop
21    endtask : body
22 endclass : short_random_sequence

11.parallel_sequence.svh

 1 class parallel_sequence extends uvm_sequence #(uvm_sequence_item);
 2    `uvm_object_utils(parallel_sequence);
 3 
 4    protected reset_sequence reset;
 5    protected short_random_sequence short_random;
 6    protected fibonacci_sequence fibonacci;
 7 
 8    function new(string name = "parallel_sequence");
 9       super.new(name);
10       reset = reset_sequence::type_id::create("reset");
11       fibonacci = fibonacci_sequence::type_id::create("fibonacci");
12       short_random = short_random_sequence::type_id::create("short_random");
13    endfunction : new
14 
15    task body();
16       reset.start(m_sequencer);
17       fork
18         fibonacci.start(m_sequencer);
19            short_random.start(m_sequencer);
20       join
21    endtask : body
22 endclass : parallel_sequence

相关