1. 程式人生 > >2.2.2 加入factory機制

2.2.2 加入factory機制

func nds extends 能夠 rand 並且 spa 屬於 style

上一節給出了一個只有driver、使用UVM搭建的驗證平臺。嚴格來說這根本就不算是UVM驗證平臺,因為UVM的特性幾乎一點都沒有用到。像上節中my_driver的實例化及drv.main_phase的顯式調用,即使不使用UVM,只使用簡單的SystemVerilog也可以完成。本節將會為讀者展示在初學者看來感覺最神奇的一點:自動創建一個類的實例並調用其中的函數(function)和任務(task)。

要使用這個功能,需要引入UVM的factory機制:

代碼清單 2-7
文件:src/ch2/section2.2/2.2.2/my_driver.sv
  3 class my_driver extends uvm_driver;
  4
  5    `uvm_component_utils(my_driver)
  6    function new(string name = "my_driver", uvm_component parent = null);
  7       super.new(name, parent);
  8       `uvm_info("my_driver", "new is called", UVM_LOW);
  9    endfunction
 10    extern virtual task main_phase(uvm_phase phase);
 11 endclass
 12
 13 task my_driver::main_phase(uvm_phase phase);
 14    `uvm_info("my_driver", "main_phase is called", UVM_LOW);
 15    top_tb.rxd <= 8‘b0;
 16    top_tb.rx_dv <= 1‘b0;
 17    while(!top_tb.rst_n)
 18       @(posedge top_tb.clk);
 19    for(int i = 0; i < 256; i++)begin
 20       @(posedge top_tb.clk);
 21       top_tb.rxd <= $urandom_range(0, 255);
 22       top_tb.rx_dv <= 1‘b1;
 23       `uvm_info("my_driver", "data is drived", UVM_LOW);
 24    end
 25    @(posedge top_tb.clk);
 26    top_tb.rx_dv <= 1‘b0;
 27 endtask

factory機制的實現被集成在了一個宏中:uvm_component_utils。這個宏所做的事情非常多,其中之一就是將my_driver登記在UVM內部的一張表中,這張表是factory功能實現的基礎。只要在定義一個新的類時使用這個宏,就相當於把這個類註冊到了這張表中。那麽factory機制到底是什麽?這個宏還做了哪些事情呢?這些屬於UVM中的高級問題,本書會在後文一一展開。

在給driver中加入factory機制後,還需要對top_tb做一些改動:

代碼清單 2-8
文件:src/ch2/section2.2/2.2.2/top_tb.sv
  7 module top_tb;
  …
 36 initial begin
 37    run_test("my_driver");
 38 end
 39
 40 endmodule

這裏使用一個run_test語句替換掉了代碼清單2-6中第23到28行的my_driver實例化及main_phase的顯式調用。運行這個新的驗證平臺,會輸出如下語句:
new is called
main_phased is called

一個run_test語句會創建一個my_driver的實例,並且會自動調用my_driver的main_phase。仔細觀察run_test語句,會發現傳遞給它的是一個字符串。UVM根據這個字符串創建了其所代表類的一個實例。如果沒有UVM,讀者自己能夠實現同樣的功能嗎?

根據類名創建一個類的實例,這是uvm_component_utils宏所帶來的效果,同時也是factory機制給讀者的最初印象。只有在類定義時聲明了這個宏,才能使用這個功能。所以從某種程度上來說,這個宏起到了註冊的作用。只有經過註冊的類,才能使用這個功能,否則根本不能使用。請記住一點:所有派生自uvm_component及其派生類的類都應該使用uvm_component_utils宏註冊。

除了根據一個字符串創建類的實例外,上述代碼中另外一個神奇的地方是main_phase被自動調用了。在UVM驗證平臺中,只要一個類使用uvm_component_utils註冊且此類被實例化了,那麽這個類的main_phase就會自動被調用。這也就是為什麽上一節中會強調實現一個driver等於實現其main_phase。所以,在driver中,最重要的就是實現main_phase。

上面的例子中,只輸出到“main_phase is called”。

令人沮喪的是,根本沒有輸出“data is drived”,而按照預期,它應該輸出256次。

關於這個問題,牽涉UVM的objection機制。

2.2.2 加入factory機制