What is a monitor?
UVM monitor負責從design interface擷取訊號活動(activity),並將其轉換為可傳送至其他component的data object。
為此,需要滿足以下條件:
- 一個virtual interface handle,用於監視此monitor正在嘗試監視的實際interface。
- 宣言一個TLM Analysis Port,用於向其他人廣播capture到的資料。
What does a UVM monitor do?
UVM monitorr繼承了uvm_monitor,具有以下功能:
- 透過virtual interface收集bus或signal的資訊
- 收集的數據可用於protocol檢查和覆蓋(coverage)
- 透過analysis port將收集的數據匯出
UVM monitor的功能應該要盡量只有基本且一定需要的基本監控。它可能具有用於基本啟用/停用protocol的checking和coverage collection。比較high level的functional的checking應該要在scoreboard。
Steps to create a UVM monitor
建立一個繼承
uvm_monitor的class,然後註冊到factory上1
2
3
4
5
6
7
8class my_monitor extends uvm_monitor;
`uvm_component_utils (my_monitor)
function new (string name = "my_monitor", uvm_component parent = null);
super.new (name, parent);
endfunction
endclass宣告analysis port和virtual interface handle
1
2
3
4
5
6
7
8class my_monitor extends uvm_monitor;
...
// Actual interface object is later obtained by doing a get() call on uvm_config_db
virtual if_name vif;
uvm_analysis_port #(my_data) mon_analysis_port;
...
endclass建置UVM monitor,並在build phase建立analysis port的instance
1
2
3
4
5
6
7
8
9
10
11
12
13
14class my_monitor extends uvm_monitor;
...
virtual function void build_phase (uvm_phase phase);
super.build_phase (phase);
mon_analysis_port = new("mon_analysis_port", this);
// Get virtual interface handle from the configuration DB
if (! uvm_config_db #(virtual if_name)::get(this, "", "vif", vif)) begin
`uvm_error (get_type_name (), "DUT interface not found")
end
endfunction
...
endclassCode the run_phase
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16class my_monitor extends uvm_monitor;
...
virtual task run_phase (uvm_phase phase);
// Fork off multiple threads "if" required to monitor the interface, for example:
fork
// Thread 1: Monitor address channel
// Thread 2: Monitor data channel, populate "obj" data object
// Thread 3: Monitor control channel, decide if transaction is over
// Thread 4: When data transfer is complete, send captured information
// through the declared analysis port
mon_analysis_port.write(obj);
join_none
endtask
...
endclass