uvm_agent+configuration object+configuration database(uvm验证平台)
资料来源
(1) 《The UVM Primer》第22章
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 class_bfm(); 8 9 tinyalu class_dut (.A(class_bfm.A), .B(class_bfm.B), .op(class_bfm.op), 10 .clk(class_bfm.clk), .reset_n(class_bfm.reset_n), 11 .start(class_bfm.start), .done(class_bfm.done), 12 .result(class_bfm.result)); 13 14 tinyalu_bfm module_bfm(); 15 16 tinyalu module_dut (.A(module_bfm.A), .B(module_bfm.B), .op(module_bfm.op), 17 .clk(module_bfm.clk), .reset_n(module_bfm.reset_n), 18 .start(module_bfm.start), .done(module_bfm.done), 19 .result(module_bfm.result)); 20 21 tinyalu_tester_module stim_module(module_bfm); 22 23 initial begin 24 uvm_config_db #(virtual tinyalu_bfm)::set(null, "*", "class_bfm", class_bfm); 25 uvm_config_db #(virtual tinyalu_bfm)::set(null, "*", "module_bfm", module_bfm); 26 run_test("dual_test"); 27 end 28 29 endmodule : top
2.tinyalu_tester_module.sv
1 module tinyalu_tester_module(tinyalu_bfm bfm); 2 import tinyalu_pkg::*; 3 4 function operation_t get_op(); 5 bit [2:0] op_choice; 6 op_choice = $random; 7 case (op_choice) 8 3'b000 : return no_op; 9 3'b001 : return add_op; 10 3'b010 : return and_op; 11 3'b011 : return xor_op; 12 3'b100 : return mul_op; 13 3'b101 : return no_op; 14 3'b110 : return rst_op; 15 3'b111 : return rst_op; 16 endcase // case (op_choice) 17 endfunction : get_op 18 19 function byte get_data(); 20 bit [1:0] zero_ones; 21 zero_ones = $random; 22 if (zero_ones == 2'b00) 23 return 8'h00; 24 else if (zero_ones == 2'b11) 25 return 8'hFF; 26 else 27 return $random; 28 endfunction : get_data 29 30 initial begin 31 byte unsigned iA; 32 byte unsigned iB; 33 operation_t op_set; 34 shortint result; 35 36 bfm.reset_alu(); 37 repeat (5) begin : random_loop 38 op_set = get_op(); 39 iA = get_data(); 40 iB = get_data(); 41 bfm.send_op(iA, iB, op_set,result); 42 end : random_loop 43 end // initial begin 44 endmodule : tinyalu_tester_module
3.tinyalu_bfm.sv
1 interface tinyalu_bfm; 2 import uvm_pkg::*; 3 `include "uvm_macros.svh" 4 import tinyalu_pkg::*; 5 6 byte unsigned A; 7 byte unsigned B; 8 bit clk; 9 bit reset_n; 10 wire [2:0] op; 11 bit start; 12 wire done; 13 wire [15:0] result; 14 operation_t op_set; 15 16 17 assign op = op_set; 18 19 task reset_alu(); 20 reset_n = 1'b0; 21 @(negedge clk); 22 @(negedge clk); 23 reset_n = 1'b1; 24 start = 1'b0; 25 endtask : reset_alu 26 27 28 29 task send_op(input byte iA, input byte iB, input operation_t iop, output shortint alu_result); 30 if (iop == rst_op) begin 31 @(posedge clk); 32 reset_n = 1'b0; 33 start = 1'b0; 34 @(posedge clk); 35 #1; 36 reset_n = 1'b1; 37 end else begin 38 @(negedge clk); 39 op_set = iop; 40 A = iA; 41 B = iB; 42 start = 1'b1; 43 if (iop == no_op) begin 44 @(posedge clk); 45 #1; 46 start = 1'b0; 47 end else begin 48 do 49 @(negedge clk); 50 while (done == 0); 51 alu_result = result; 52 start = 1'b0; 53 end 54 end // else: !if(iop == rst_op) 55 56 endtask : send_op 57 58 command_monitor command_monitor_h; 59 60 function operation_t op2enum(); 61 case(op) 62 3'b000 : return no_op; 63 3'b001 : return add_op; 64 3'b010 : return and_op; 65 3'b011 : return xor_op; 66 3'b100 : return mul_op; 67 3'b111 : return rst_op; 68 default : `uvm_fatal("TINYALU BFM",$sformatf("Illegal operation: %d", int'(op))) 69 endcase // case (op) 70 endfunction : op2enum 71 72 73 always @(posedge clk) begin : op_monitor 74 static bit in_command = 0; 75 command_transaction command; 76 if (start) begin : start_high 77 if (!in_command) begin : new_command 78 command_monitor_h.write_to_monitor(A, B, op2enum()); 79 in_command = (op2enum() != no_op); 80 end : new_command 81 end : start_high 82 else // start low 83 in_command = 0; 84 end : op_monitor 85 86 always @(negedge reset_n) begin : rst_monitor 87 command_transaction command; 88 if (command_monitor_h != null) //guard against VCS time 0 negedge 89 command_monitor_h.write_to_monitor($random,0,rst_op); 90 end : rst_monitor 91 92 result_monitor result_monitor_h; 93 94 initial begin : result_monitor_thread 95 forever begin : result_monitor 96 @(posedge clk) ; 97 if (done) 98 result_monitor_h.write_to_monitor(result); 99 end : result_monitor 100 end : result_monitor_thread 101 102 103 initial begin 104 clk = 0; 105 forever begin 106 #10; 107 clk = ~clk; 108 end 109 end 110 111 112 endinterface : tinyalu_bfm
4.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 14 15 `include "env_config.svh" 16 `include "tinyalu_agent_config.svh" 17 `include "command_transaction.svh" 18 `include "add_transaction.svh" 19 `include "result_transaction.svh" 20 `include "coverage.svh" 21 `include "tester.svh" 22 `include "scoreboard.svh" 23 `include "driver.svh" 24 `include "command_monitor.svh" 25 `include "result_monitor.svh" 26 `include "tinyalu_agent.svh" 27 `include "env.svh" 28 29 `include "dual_test.svh" 30 31 32 endpackage : tinyalu_pkg
5.dual_test.svh
1 class dual_test extends uvm_test; 2 `uvm_component_utils(dual_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 11 function void build_phase(uvm_phase phase); 12 13 virtual tinyalu_bfm class_bfm, module_bfm; 14 env_config env_config_h; 15 16 if(!uvm_config_db #(virtual tinyalu_bfm)::get(this, "","class_bfm", class_bfm)) 17 `uvm_fatal("DUAL TEST", "Failed to get CLASS BFM"); 18 if(!uvm_config_db #(virtual tinyalu_bfm)::get(this, "","module_bfm", module_bfm)) 19 `uvm_fatal("DUAL TEST", "Failed to get MODULE BFM"); 20 21 env_config_h = new(.class_bfm(class_bfm), .module_bfm(module_bfm)); 22 23 uvm_config_db #(env_config)::set(this, "env_h*", "config", env_config_h); 24 25 env_h = env::type_id::create("env_h",this); 26 endfunction : build_phase 27 28 29 endclass
6.env.svh
1 class env extends uvm_env; 2 `uvm_component_utils(env); 3 4 tinyalu_agent class_tinyalu_agent_h, module_tinyalu_agent_h; 5 tinyalu_agent_config class_config_h, module_config_h; 6 7 function new (string name, uvm_component parent); 8 super.new(name,parent); 9 endfunction : new 10 11 function void build_phase(uvm_phase phase); 12 virtual tinyalu_bfm class_bfm; 13 virtual tinyalu_bfm module_bfm; 14 env_config env_config_h; 15 16 17 18 if(!uvm_config_db #(env_config)::get(this, "","config", env_config_h)) 19 `uvm_fatal("RANDOM TEST", "Failed to get CLASS BFM"); 20 21 class_config_h = new(.bfm(env_config_h.class_bfm), .is_active(UVM_ACTIVE)); 22 module_config_h = new(.bfm(env_config_h.module_bfm), .is_active(UVM_PASSIVE)); 23 24 uvm_config_db #(tinyalu_agent_config)::set(this, "class_tinyalu_agent_h*", 25 "config", class_config_h); 26 27 uvm_config_db #(tinyalu_agent_config)::set(this, "module_tinyalu_agent_h*", 28 "config", module_config_h); 29 30 31 32 class_tinyalu_agent_h = new("class_tinyalu_agent_h",this); 33 module_tinyalu_agent_h = new("module_tinyalu_agent_h",this); 34 35 endfunction : build_phase 36 37 endclass
7.env_config.svh
class env_config; virtual tinyalu_bfm class_bfm; virtual tinyalu_bfm module_bfm; function new(virtual tinyalu_bfm class_bfm, virtual tinyalu_bfm module_bfm); this.class_bfm = class_bfm; this.module_bfm = module_bfm; endfunction : new endclass : env_config
8.tinyalu_agent.svh
1 class tinyalu_agent extends uvm_agent; 2 `uvm_component_utils(tinyalu_agent) 3 4 tinyalu_agent_config tinyalu_agent_config_h; 5 6 tester tester_h; 7 driver driver_h; 8 scoreboard scoreboard_h; 9 coverage coverage_h; 10 command_monitor command_monitor_h; 11 result_monitor result_monitor_h; 12 13 uvm_tlm_fifo #(command_transaction) command_f; 14 uvm_analysis_port #(command_transaction) cmd_mon_ap; 15 uvm_analysis_port #(result_transaction) result_ap; 16 17 18 function new (string name, uvm_component parent); 19 super.new(name,parent); 20 endfunction : new 21 22 23 function void build_phase(uvm_phase phase); 24 25 if(!uvm_config_db #(tinyalu_agent_config)::get(this, "","config", 26 tinyalu_agent_config_h)) 27 `uvm_fatal("AGENT", "Failed to get config object"); 28 is_active = tinyalu_agent_config_h.get_is_active(); 29 30 if (get_is_active() == UVM_ACTIVE) begin : make_stimulus 31 command_f = new("command_f", this); 32 tester_h = tester::type_id::create( "tester_h",this); 33 driver_h = driver::type_id::create("driver_h",this); 34 end 35 36 command_monitor_h = command_monitor::type_id::create("command_monitor_h",this); 37 result_monitor_h = result_monitor::type_id::create("result_monitor_h",this); 38 39 coverage_h = coverage::type_id::create("coverage_h",this); 40 scoreboard_h = scoreboard::type_id::create("scoreboard_h",this); 41 42 cmd_mon_ap = new("cmd_mon_ap",this); 43 result_ap = new("result_ap", this); 44 45 endfunction : build_phase 46 47 function void connect_phase(uvm_phase phase); 48 if (get_is_active() == UVM_ACTIVE) begin : make_stimulus 49 driver_h.command_port.connect(command_f.get_export); 50 tester_h.command_port.connect(command_f.put_export); 51 end 52 53 command_monitor_h.ap.connect(cmd_mon_ap); 54 result_monitor_h.ap.connect(result_ap); 55 56 command_monitor_h.ap.connect(scoreboard_h.cmd_f.analysis_export); 57 command_monitor_h.ap.connect(coverage_h.analysis_export); 58 result_monitor_h.ap.connect(scoreboard_h.analysis_export); 59 60 endfunction : connect_phase 61 62 endclass : tinyalu_agent
9.tinyalu_agent_config.svh
1 class tinyalu_agent_config; 2 3 virtual tinyalu_bfm bfm; 4 protected uvm_active_passive_enum is_active; 5 6 function new (virtual tinyalu_bfm bfm, uvm_active_passive_enum 7 is_active); 8 this.bfm = bfm; 9 this.is_active = is_active; 10 endfunction : new 11 12 function uvm_active_passive_enum get_is_active(); 13 return is_active; 14 endfunction : get_is_active 15 16 endclass : tinyalu_agent_config