What is a driver?
UVM driver是一個了解如何將signal驅動(drive)到design的特定interface的實體。例如為了驅動一個APB bus protocol,UVM driver定義了訊號的時序,打出正確的signal以便有效使用這個protocol。所有driver類別都應直接或間接地從uvm_driver擴充。
從Sequencer取得transaction level的物件,然後UVM driver透過interface handle將它們驅動到design。
Steps to create a UVM driver
建立一個繼承
uvm_driver的class,然後註冊到factory上1
2
3
4
5
6
7
8class my_driver extends uvm_driver;
`uvm_component_utils (my_driver)
function new (string name = "my_driver", uvm_component parent = null);
super.new (name, parent);
endfunction
...
endclass宣告virtual interface handle 然後在
build_phase的時候用uvm_config_db的getmethod得到這個interface的object1
2
3
4
5
6
7
8
9
10
11
12class my_driver extends uvm_driver;
...
virtual if_name vif_0;
virtual function void build_phase (uvm_phase phase);
super.build_phase (phase);
if (! uvm_config_db #(virtual if_name) :: get (this, "", "vif_0", vif_0)) begin
`uvm_fatal (get_type_name (), "Cannot get handle to virtual interface if_name")
end
endfunction
...
endclass實作
run_phase1
2
3
4
5
6
7
8
9class my_driver extends uvm_driver;
virtual task run_phase (uvm_phase phase);
forever begin
// 1. get_next_item()
// 2. assign_the_data_into_DUT_interface()
// 3. finish_driving_transaction()
end
endtask
endclass
UVM Driver-Sequencer handshake
UVM driver is a parameterized class which can drive a specific type of transaction object.
UVM driver是一個參數化的class,可以驅動transaction object。
Driver有一個 uvm_seq_item_pull_port可以接收從uvm_sequencer發來的request。它也可以把object傳回給uvm_sequencer,通常request和reponse的傳的東西的type是相同的
如果有明確指定type的話,request和reponse的物件的type也可以不同,UVM driver用以下方法與sequencer互動。
| Method | Description |
|---|---|
| get_next_item | Block method,會卡著一直等到sequencer中有可用的request為止。之後要使用 item_done 完成handshake。 |
| try_next_item | Non-blocking method,如果sequencer中沒有可用的request就會return null。有request的話會回傳object的pointer。 |
| item_done | 完成driver和sequencer handshake的Non-blocking method。要在 get_next_item 或 try_next_item 成功之後呼叫item_done。 |
How are driver/sequencer API methods used?
Driver和Sequencer的handshake機制背後的想法是允許driver從sequence中獲取一連串的transaction object,並在收到後回應response,才能繼續get下一個item。
呼叫
get_next_item後要接著呼叫item_done1
2
3
4
5
6
7
8
9
10
11
12virtual task run_phase (uvm_phase phase);
my_data req_item;
forever begin
seq_item_port.get_next_item (req_item);
// Drive signals to the interface
// ...
seq_item_port.item_done();
end
endtask呼叫
get後要接著呼叫put1
2
3
4
5
6
7
8
9
10
11
12virtual task run_phase (uvm_phase phase);
my_data req_item;
forever begin
seq_item_port.get (req_item);
// Drive signals to the interface
// ...
seq_item_port.put (rsp_item);
end
endtask