uvm_factory重载bfm发包逻辑

testbench.sv

import uvm_pkg::*;

`include "bfm_base_pkg.sv"
`include "base_intf.sv"
`include "tc_001.sv"
`include "tc_002.sv"
`include "tc_003.sv"

module harness;
  
  import bfm_base_pkg::*;

  base_intf base_bfm();

  initial begin
    uvm_config_db#(virtual base_intf)::set(uvm_top,"driver","vbif",base_bfm);
    uvm_config_db#(virtual base_intf)::set(uvm_top,"test","vbif",base_bfm);
    run_test();
  end
  initial begin
    $dumpfile("dump.vcd"); 
    $dumpvars;
  end
endmodule

 base_intf.sv

interface base_intf();
  logic [3:0] in;
  
  import uvm_pkg::*;
  import bfm_base_pkg::*;

  base_drv driver;//for override
  
  task drv_bfm(uvm_sequence_item req);
    if(driver != null)
      driver.drv_sig(req);
    else
      `uvm_fatal("base_bfm","driver does not initialized ...");
//     create_drv(req);
//     start_drv(req);
  endtask
  function void create_drv(uvm_sequence_item req);
    if(driver == null)begin
      uvm_component obj;
      obj = f.create_component_by_type(lookup_table::search_lookup(req.get_object_type()),"","driver",null);
      $cast(driver, obj);
//       $cast(driver, lookup_table::search_lookup(req.get_object_type()).create_component($sformatf("drv_%0s",req.get_type_name()),null));

      $display("============= %0s ============",driver.get_type_name());
    end
  endfunction
      
endinterface

base_bfm_pkg.sv

package bfm_base_pkg;
	
  import uvm_pkg::*;

  typedef virtual base_intf vbif;

  uvm_coreservice_t cs = uvm_coreservice_t::get();
  uvm_factory f = cs.get_factory();
  uvm_root uvm_top = cs.get_root();

  class lookup_table;
    static local uvm_object_wrapper lookup[uvm_object_wrapper];
    static function void add_lookup(uvm_object_wrapper ind, uvm_object_wrapper wrp);
      lookup[ind] = wrp;
    endfunction
    static function uvm_object_wrapper search_lookup(uvm_object_wrapper ind);
      return lookup[ind];
    endfunction
  endclass

  class base_trans extends uvm_sequence_item;
    rand bit[2:0] opcode;
    `uvm_object_utils_begin(base_trans)
      `uvm_field_int(opcode,UVM_ALL_ON)
    `uvm_object_utils_end
    function new(string name = "base_trans");
      super.new(name);
    endfunction
  endclass

  class user_def_trans extends base_trans;
    `uvm_object_utils_begin(user_def_trans)
    `uvm_field_int(opcode,UVM_ALL_ON)
    `uvm_object_utils_end
    
    function new(string name = "user_def_trans");
      super.new(name);
    endfunction
    constraint cons{
    	this.opcode == 1;
    };
  endclass

  class user_def_abn_trans extends base_trans;
    `uvm_object_utils_begin(user_def_abn_trans)
    `uvm_field_int(opcode,UVM_ALL_ON)
    `uvm_object_utils_end
    
    function new(string name = "user_def_abn_trans");
      super.new(name);
    endfunction
    constraint cons{
    	this.opcode == 3;
    };    
  endclass

  class base_drv extends uvm_component;
    `uvm_component_utils(base_drv)
    protected virtual base_intf vif;
    function new(string name, uvm_component parent);
      super.new(name,parent);
      set_if();
    endfunction
    protected function void set_if();
      if(vif == null)
        void'(uvm_config_db#(virtual base_intf)::get(null,"driver","vbif",vif));//todo
    endfunction
    virtual task drv_sig(uvm_sequence_item req); endtask
      
  endclass
      
  class drv#(type T = int) extends base_drv;
    protected T tr;
    `uvm_component_param_utils(drv#(T))
    `uvm_type_name_decl("drv")
    function new(string name, uvm_component parent);
      super.new(name,parent);
    endfunction
    virtual task drv_sig(uvm_sequence_item req);
      $display("%0s start stimulus ...", this.get_type_name());
      assert($cast(tr,req.clone())) else `uvm_error("drv","errot type of trans to be sent ")//todo   
      $display("tr.opcode is %0b", tr.opcode);
      
      if(vif == null) `uvm_fatal("drv","no vif set, pls call set_if() func ...");
      $display("drive signal start...");
      vif.in = 4'hf;
      #10ns;
      vif.in = 0;
      #10ns;
      vif.in = 4'hf;
      #10ns;
      $display("drive signal done...");
      $display("%0s end stimulus ...", this.get_type_name());
    endtask
//     virtual function string get_type_name();
//       return {"drv_",`"T`"};
//     endfunction
  endclass
 
  class drv_nor#(type T = int) extends drv#(T);
    `uvm_component_param_utils(drv_nor#(T))
    `uvm_type_name_decl("drv_nor")
    function new(string name, uvm_component parent);
      super.new(name,parent);
    endfunction
    virtual task drv_sig(uvm_sequence_item req);
      $display("%0s start stimulus ...", this.get_type_name());
      assert($cast(tr,req.clone())) else `uvm_error("drv","errot type of trans to be sent ")//todo   
      $display("tr.opcode is %0b", tr.opcode);
     
      if(vif == null) `uvm_fatal("drv","no vif set, pls call set_if() func ...");
      $display("drive signal start...");
      vif.in = 4'b1010;
      #10ns;
      vif.in = 0;
      #10ns;
      vif.in = 4'b1010;
      #10ns;
      $display("drive signal done...");
      $display("%0s end stimulus ...", this.get_type_name());
    endtask 
  endclass

endpackage

 tc_001.sv

class tc_001 extends uvm_test;
  `uvm_component_utils(tc_001)
  
  import bfm_base_pkg::*;
  protected virtual base_intf base_bfm;

  base_trans a;
  
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction
  
  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    lookup_table::add_lookup(base_trans::get_type(),         drv#(base_trans)::get_type());
    void'(uvm_config_db#(virtual base_intf)::get(null,"test","vbif",base_bfm));//todo
    
    //always do in sequence
    a = base_trans::type_id::create("base_trans");
    
    //always do in driver_proxy
    base_bfm.create_drv(a);
  endfunction
  
  virtual task main_phase(uvm_phase phase);
    phase.raise_objection(this);
    /*
    lookup_table::add_lookup(base_trans::get_type(),         drv#(base_trans)::get_type());
    lookup_table::add_lookup(user_def_trans::get_type(),     drv#(user_def_trans)::get_type());
    lookup_table::add_lookup(user_def_abn_trans::get_type(), drv#(user_def_abn_trans)::get_type());   

//     f.set_type_override_by_type(base_trans::get_type(), user_def_trans::get_type());
    
    f.set_type_override_by_type(drv#(user_def_abn_trans)::get_type(), drv_nor#(user_def_abn_trans)::get_type());
    f.set_type_override_by_type(base_trans::get_type(), user_def_abn_trans::get_type());

//     f.set_type_override_by_type(drv#(user_def_trans)::get_type(), drv#(user_def_abn_trans)::get_type());
//     f.set_type_override_by_type(drv#(user_def_trans)::get_type(), drv_nor#(user_def_trans)::get_type());
*/
    repeat(10)begin
      a.randomize();
      base_bfm.drv_bfm(a);
      #10ns;
    end
    phase.drop_objection(this);
  endtask

  virtual task shutdown_phase(uvm_phase phase);
    uvm_top.print_topology();
  endtask
endclass

 tc_002.sv

class tc_002 extends uvm_test;
  `uvm_component_utils(tc_002)
  
  import bfm_base_pkg::*;
  protected virtual base_intf base_bfm;

  base_trans a;
  
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction
  
  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
//     lookup_table::add_lookup(base_trans::get_type(),         drv#(base_trans)::get_type());
    lookup_table::add_lookup(user_def_trans::get_type(),     drv#(user_def_trans)::get_type());
    void'(uvm_config_db#(virtual base_intf)::get(null,"test","vbif",base_bfm));//todo
    
    f.set_type_override_by_type(base_trans::get_type(), user_def_trans::get_type());

    //always do in sequence
    a = base_trans::type_id::create("base_trans");
    
    //always do in driver_proxy
    base_bfm.create_drv(a);
  endfunction
  
  virtual task main_phase(uvm_phase phase);
    phase.raise_objection(this);
    /*
    lookup_table::add_lookup(base_trans::get_type(),         drv#(base_trans)::get_type());
    lookup_table::add_lookup(user_def_trans::get_type(),     drv#(user_def_trans)::get_type());
    lookup_table::add_lookup(user_def_abn_trans::get_type(), drv#(user_def_abn_trans)::get_type());   

//     f.set_type_override_by_type(base_trans::get_type(), user_def_trans::get_type());
    
    f.set_type_override_by_type(drv#(user_def_abn_trans)::get_type(), drv_nor#(user_def_abn_trans)::get_type());
    f.set_type_override_by_type(base_trans::get_type(), user_def_abn_trans::get_type());

//     f.set_type_override_by_type(drv#(user_def_trans)::get_type(), drv#(user_def_abn_trans)::get_type());
//     f.set_type_override_by_type(drv#(user_def_trans)::get_type(), drv_nor#(user_def_trans)::get_type());
*/
    repeat(10)begin
      a.randomize();
      base_bfm.drv_bfm(a);
      #10ns;
    end
    phase.drop_objection(this);
  endtask

  virtual task shutdown_phase(uvm_phase phase);
    uvm_top.print_topology();
  endtask
endclass

 tc_003.sv

class tc_003 extends uvm_test;
  `uvm_component_utils(tc_003)
  
  import bfm_base_pkg::*;
  protected virtual base_intf base_bfm;

  base_trans a;
  
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction
  
  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
//     lookup_table::add_lookup(base_trans::get_type(),         drv#(base_trans)::get_type());
    lookup_table::add_lookup(user_def_abn_trans::get_type(),     drv_nor#(user_def_abn_trans)::get_type());
    void'(uvm_config_db#(virtual base_intf)::get(null,"test","vbif",base_bfm));//todo
    
    f.set_type_override_by_type(base_trans::get_type(), user_def_abn_trans::get_type());

    //always do in sequence
    a = base_trans::type_id::create("base_trans");
    
    //always do in driver_proxy
    base_bfm.create_drv(a);
  endfunction
  
  virtual task main_phase(uvm_phase phase);
    phase.raise_objection(this);
    /*
    lookup_table::add_lookup(base_trans::get_type(),         drv#(base_trans)::get_type());
    lookup_table::add_lookup(user_def_trans::get_type(),     drv#(user_def_trans)::get_type());
    lookup_table::add_lookup(user_def_abn_trans::get_type(), drv#(user_def_abn_trans)::get_type());   

//     f.set_type_override_by_type(base_trans::get_type(), user_def_trans::get_type());
    
    f.set_type_override_by_type(drv#(user_def_abn_trans)::get_type(), drv_nor#(user_def_abn_trans)::get_type());
    f.set_type_override_by_type(base_trans::get_type(), user_def_abn_trans::get_type());

//     f.set_type_override_by_type(drv#(user_def_trans)::get_type(), drv#(user_def_abn_trans)::get_type());
//     f.set_type_override_by_type(drv#(user_def_trans)::get_type(), drv_nor#(user_def_trans)::get_type());
*/
    repeat(10)begin
      a.randomize();
      base_bfm.drv_bfm(a);
      #10ns;
    end
    phase.drop_objection(this);
  endtask

  virtual task shutdown_phase(uvm_phase phase);
    uvm_top.print_topology();
  endtask
endclass

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值