FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

Vivado Simulatorを使ってUVMに入門する (12. UVM Testbench Exampleを試す)

前回はこちら: msyksphinz.hatenablog.com

UVMのさらなるテストベンチを試行するために、以下のウェブサイトのサンプルを試してみることにした。

www.chipverify.com

このページでは、別ページで作ったSystemVerilogのレジスタコントローラ(レジスタファイルみたいなもの)を検証するためのUVM環境を作り上げていくものになっている。

www.chipverify.com

これでエラーが出てしまいデバッグに困っているのだけれども、とりあえずuvm_config_dbの挙動が良く分からな過ぎる。

UVM_INFO /tools/Xilinx/Vivado/2023.2/data/system_verilog/uvm_1.2/xlnx_uvm_package.sv(8184) @ 0: reporter [CFGDB/SET] Configuration '*.reg_vif' (type uvm_pkg::T) set by  = (uvm_pkg::T) /tb_top/vif
...
UVM_FATAL test.sv(14) @ 0: uvm_test_top [TEST] Did not get vif

tb_top.svの以下がtest.svreg_ifを渡してほしいのだけれども:

  uvm_config_db #(virtual reg_if)::set(uvm_root::get(), "*", "reg_vif", vif);
    if (!uvm_config_db #(virtual reg_if)::get(this, "", "reg_vif", vif))
      `uvm_fatal("TEST", "Did not get vif")

うーん、とりあえずtest.svからvifを除去してみる。

class test extends uvm_test;
  `uvm_component_utils(test);
  function new(string name="test", uvm_component parent=null);
    super.new(name, parent);
  endfunction // new                                                                                                                                                                                                                                                                                                                                                                      

  env e0;
  // virtual reg_if vif;                                                                                                                                                                                                                                                                                                                                                                  

  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    e0 = env::type_id::create("e0", this);
    // if (!uvm_config_db #(virtual reg_if)::get(this, "", "reg_if", vif))                                                                                                                                                                                                                                                                                                                
    //   `uvm_fatal("TEST", "Did not get vif")                                                                                                                                                                                                                                                                                                                                            
    //                                                                                                                                                                                                                                                                                                                                                                                    
    // uvm_config_db #(virtual reg_if)::set(this, "e0.a0.*", "reg_vif", vif);                                                                                                                                                                                                                                                                                                             
  endfunction // build_phase                                                                                                                                                                                                                                                                                                                                                              

  virtual task run_phase (uvm_phase phase);
    gen_item_seq seq = gen_item_seq::type_id::create("seq");

    uvm_top.print_topology();

    phase.raise_objection(this);
    apply_reset();

    seq.randomize() with {num inside {[20:30]}; };
    seq.start(e0.a0.s0);
    #200;
    phase.drop_objection(this);
  endtask // run_phase                                                                                                                                                                                                                                                                                                                                                                    

  virtual task apply_reset();
    // vif.rstn <= 0;                                                                                                                                                                                                                                                                                                                                                                     
    // repeat(5) @ (posedge vif.clk);                                                                                                                                                                                                                                                                                                                                                     
    // vif.rstn <= 1;                                                                                                                                                                                                                                                                                                                                                                     
    // repeat(10) @ (posedge vif.clk);                                                                                                                                                                                                                                                                                                                                                    
  endtask // apply_reset                                                                                                                                                                                                                                                                                                                                                                  

endclass // test                                                                                                                                                                                                                                                                                                                                                                          

そうすると、一応テストケースは動き出した。では、なんでtest.svvifを登録しようとするとおかしくなるんだろう?