UVM Test

2023-11-18
UVM

What is a testcase?

Testcase是一種用於檢查和驗證design的特定feature和功能的pattern。Verification plan列出了需要驗證的所有feature和其他功能項目,這些test需要cover全部要verify的東西。
如果是一個複雜的design,通常需要數百個甚至更多的test來驗證。

為了避免不同的testcase寫很多重複相同的code,我們要把整個testbench放入一個Environment容器中,並為每個test使用具有不同配置的相同環境。

每個testcase案例都可以override、調整旋鈕(tweak knobs)、enable/disable agent、更改configuration table中的變數值以及在驗證環境中的許多sequencer上執行不同的sequences。

Alt text

Steps to write a UVM Test

  1. 建立一個繼承uvm_test的class,然後註冊到factory上

    1
    2
    3
    4
    5
    6
    7
    8
    class my_test extends uvm_test;
    `uvm_component_utils (my_test)

    function new (string name = "my_test", uvm_component parent = null);
    super.new (name, parent);
    endfunction

    endclass
  2. 宣告其他verification component然後在build_phase的時候將他們實例化

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    class my_test extends uvm_test;
    ...
    my_env top_env_0;
    my_cfg cfg_0;

    virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);

    top_env_0 = my_env::type_id::create("top_env_0", this);
    cfg_0 = my_cfg::type_id::create("cfg_0", this);

    set_cfg_params();

    uvm_config_db #(my_cfg)::set (this, "top_env_0.my_agent", "cfg_0", cfg_0);
    endfunction
    endclass
  3. 有需要的話可以在end_of_elaboration_phase phase印出topology

    1
    2
    3
    4
    5
    6
    class my_test extends uvm_test;
    ...
    virtual function void end_of_elaboration_phase (uvm_phase phase);
    uvm_top.print_topology ();
    endfunction
    endclass
  4. run_phase啟動 virtual sequence

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    virtual task run_phase (uvm_phase phase);
    ...
    my_seq seq = my_seq::type_id::create ("seq");

    phase.raise_objection (this);

    seq.start (m_env.seqr);

    phase.drop_objection (this);
    endtask

How to run a UVM test

通常test會在testbench的top(tb or tb_top)透過call run_test 啟動測試。
要對這個global task(run_test)提供需要啟動的 UVM test的名稱。如果 run_test 的參數沒填,則需要使用 +UVM_TESTNAME 透過command-line向simulator定測試名稱。

1
2
3
4
5
module tb_top;
initial begin
run_test ("base_test");
end
endmodule

run_test的code如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// refer to: uvm-1.2\docs\html\src\base\uvm_globals.svh

// Task: run_test
//
// Convenience function for uvm_top.run_test(). See <uvm_root> for more
// information.

task run_test (string test_name="");
uvm_root top;
uvm_coreservice_t cs;
cs = uvm_coreservice_t::get();
top = cs.get_root();
top.run_test(test_name);
endtask

How to run any UVM test

通常喜歡用+UVM_TESTNAME這種方法來run test,因為可以更靈活的選擇不同的test,而不用每次想要執行不同的測試時就要重新修改testbench top。因為文件的內容沒有更新,所以也不用重新complie。

If +UVM_TESTNAME is specified, the UVM factory creates a component of the given test type and starts its phase mechanism. If the specified test is not found or not created by the factory, then a fatal error occurs. If no test is specified via command-line and the argument to the run_test() task is blank, then all the components constructed before the call to run_test() will be cycled through their simulation phases.
中文 (繁體)
如果使用+UVM_TESTNAME,UVM factory將建立給定test type的component然後啟動phase機制。如果找不到指定的test或這個test不是由factory創建的,就會有fatal error。

Using run_test()

1
2
3
initial begin
run_test ("base_test");
end

Using +UVM_TESTNAME

1
2
// Command-line
$> [simulator] -f list +UVM_TESTNAME=base_test