uvm通信-uvm_event & uvm_event_pool & uvm_event_callback


參考資料

(1) UVM通信篇之六:同步通信元件(上) - 路科驗證的日志 - EETOP 創芯網論壇 (原名:電子頂級開發網) -

(2) 《Practical UVM Step by Step with IEEE》

1.同步的方法

1.1 sv與uvm中同步的方法

(1) 在sv中,用於同步的方法有event, semaphore和mailbox;

(2) 在UVM中,用於同步的方法為uvm_event(uvm_event派生於uvm_object);

(3) uvm_event不僅能實現不同組件進程間同步的功能,還能像TLM通信一樣傳遞數據,並且作用范圍更廣(TLM通信只能局限於uvm_component之間,而uvm_event不限於此);

1.2 什么情況下會使用uvm_event呢?

(1) 組件之間的常規的數據流向是通過TLM通信方法實現的,比如sequencer與driver之間,或者monitor與scoreboard之間。然而有些時候,數據的傳輸的偶然觸發的,並且需要立即響應,這個時候uvm_event就是得力的助手了。

(2) uvm_event也解決了一個重要問題,那就是在一些uvm_object和uvm_component對象之間如果要發生同步,那么無法通過TLM傳輸,因為TLM傳輸必須是在組件(component)和組件之間進行的。如果在sequence與sequence之間要進行同步,或者sequence與driver之間要進行同步,都可以借助uvm_event來實現。

2.uvm_event的使用示例(已實踐,非常好用)

(1)通過uvm_event_pool::get_global_pool()函數獲取全局的單實例類uvm_event_pool類型對象的句柄;

(2)兩個initial塊中調用get_global_pool返回同一個uvm_event_pool類型對象的句柄;

(3)通過uvm_event_pool.get(“ev”)可以得到一個名字為”ev”的uvm_event對象的句柄;如果名字為"ev"的uvm_event對象不存在,會在第一次調用get_global()函數時創建這樣一個對象

(4)在uvm_event中,觸發的方式是uvm_event.trigger(); 而等待觸發的方式是wait_ptrigger() (電平觸發)wait_trigger()(上升沿觸發);

 1 //示例2
 2 //step1.The event is created in the top-level test;
 3 //step2.The event is placed in config_db;
 4 class eth_transmit_event_sync_test extends eth_blk_env_test;
 5     ...
 6     uvm_event transmit_barrier_ev=new("transmit_complete_event");
 7     ...
 8     virtual function void build_phase(uvm_phase phase);
 9         super.build_phase(phase);
10         uvm_config_db #(uvm_event)::set(null,"","transmit_b",transmit_barrier_env);
11     endfunction
12 endclass
13 
14 //step3.The transmit_sequence picks it from config_db;
15 //simple transmit sequence with events;
16 virtual task body();
17     uvm_config_db #(uvm_event)::get(null,"","transmit_b",send_2_pkt_event);
18     ...
19     send_2_pkt_event.trigger();
20     ...
21 endtask
22 
23 //step4.The interrupt sequence picks it from config_db;
24 class tx_interrupt_event_seq extends base_sequence;
25     ...
26     uvm_event int_event;
27     ...
28     virtual task body();
29         ...
30         uvm_config_db #(uvm_event)::get(null,"","transmit_b",int_event);
31         int_event.wait_ptrigger();
32         ...
33     endtask
34 
35 endclass

3.uvm_event相關function/task

注1: uvm_event主要有三類function: trigger函數(如trigger(), get_trigger_data(), get_trigger_time()等),狀態函數(is_on(),is_off(),reset(), get_num_waiters()等),callback函數(add_callback(), delete_callback()等);

3.1 wait_on

(1) 等待事件處於activated狀態,如果事件已經被觸發,這個task會立即返回;一旦事件被觸發,它將一直保持"on"狀態直到事件reset;

3.2 wait_off

(1) 如果事件已經被觸發,並且處於"on"狀態,該task會等待該事件通過調用reset而關掉;

(2) 如果事件沒有被觸發,該task會立即返回;

3.3 trigger

3.4 wait_trigger

(1) 等待事件被觸發;

3.5 wait_trigger_data

3.6 wait_ptrigger

3.7 wait_ptrigger_data

3.8 reset

3.9 is_on

3.10 is_off

3.11 get_trigger_time

4.uvm_event與event的區別

(1) uvm_event的基礎是event,只不過對event的觸發與等待進行了擴展;

(2) event被->觸發后,會觸發用@/wait(event.triggered())等待該事件的對象; uvm_event通過trigger()來觸發,會觸發使用wait_trigger()/wait_ptrigger()/wait_trigger_data()/wait_ptrigger_data()等待的對象;

(3) 如果再次觸發事件,event只需使用->來觸發; uvm_event需要先通過reset()方法重置初始狀態,再使用trigger()來觸發;

(4) event無法攜帶更多的信息; uvm_event可以通過trigger(uvm_event data=null)的可選參數,將要伴隨觸發的數據對象都寫到該觸發事件中,而等待該事件的對象可以通過方法wait_trigger_data(output uvm_object data)來獲取事件觸發時寫入的數據對象;

注1:如果uvm_event.trigger不傳遞參數,不傳遞額外的信息,則等待該事件的對象可以調用wait_trigger,而不是wait_trigger_data;

(5) event觸發時無法直接觸發回調函數; uvm_event可通過add_callback函數來添加回調函數;

(6) event無法直接獲取等待它的進程數目,而uvm_event可以通過get_num_waiters()來獲取等待它的進程數目;

5.uvm_event_pool

(1) 不同的組件可以共享同一個uvm_event,這不需要通過跨層次傳遞uvm_event對象句柄來實現共享的,因為這並不符合組件環境封閉的原則。這種共享同一個uvm_event對象是通過uvm_event_pool這一全局資源池來實現的。

(2) uvm_event_pool這個資源池類是uvm_object_string_pool #(T)的子類,它可以生成和獲取通過字符串來索引的uvm_event對象。通過全局資源池對象(唯一的),在環境中任何一個地方的組件都可以從資源池中獲取共同的對象,這就避免了組件之間的互相依賴。

6.uvm_event_callback(派生於uvm_callback)

(1) 可以從uvm_event_callback進行類的派生,並實現pre_trigger與post_trigger函數,之后將該派生類通過add_callback函數添加到uvm_event中;

(2) pre_trigger()有返回值,如果返回值為1,則表示uvm_event不會被trigger,也不會再執行post_trigger()方法;如果返回值為0,則會繼續trigger該事件對象。

注1:對於uvm_event的callback而言,不用采用示例2中通用的callback機制方法,可以直接使用uvm_event已經實現好的函數(如add_callback等);

 1 //示例1
 2 class edata extends uvm_object;
 3     `uvm_object_utils(edata)
 4     int data;
 5     ...
 6 endclass
 7 
 8 class ecb extends uvm_event_callback;
 9     `uvm_object_utils(ecb)
10     ...
11     function bit pre_trigger(uvm_event e, uvm_object data=null);
12         `uvm_info("EPRETRIG",$sformatf("before trigger event %s", e.get_name()),UVM_NONE)
13         return 0;    
14     endfunction
15 
16     function void post_trigger();
17         `uvm_info("EPOSTTRIG",$sformatf("after trigger event %s", e.get_name()),UVM_NONE)
18     endfunction
19 endclass
20 
21 class comp1 extends uvm_component;
22     `uvm_component_utils(comp1)
23     uvm_event e1;
24     ...
25     function void build_phase(uvm_phase phase);
26         super.build_phase(phase);
27         e1=uvm_event_pool::get_global("e1");
28     endfunction
29 
30     task run_phase(uvm_phase phase);
31         edata d=new();
32         ecb  cb=new();
33         d.data=100;
34         #10ns;
35         e1.add_callback(cb);
36         e1.trigger(d);
37     endtask
38 endclass
39 
40 class comp2 extends uvm_component;
41     `uvm_component_utils(comp2)
42     uvm_event e1;
43     ...
44     function void build_phase(uvm_phase phase);
45         super.build_phase(phase);
46         e1=uvm_event_pool::get_global("e1");
47     endfunction
48 
49     task run_phase(uvm_phase phase);
50         uvm_object tmp;
51         edata d;
52         e1.wait_trigger_data(tmp);
53         void'($cast(d,tmp));
54     endtask
55 endclass
56 
57 class env1 extends uvm_env;
58     comp1 c1;
59     comp2 c2;
60     ...
61 endclass
 1 //示例2
 2 //step1.create event callback class;
 3 class int_event_callbacks extends uvm_event_callback;
 4     function new(string name="int_event_callbacks");
 5         super.new(name);
 6     endfunction
 7     
 8     virtual function bit pre_trigger(uvm_event e, uvm_object data=null);
 9         `uvm_info("UVM_EVENT_CALLBACK",$sformatf("UVM EVENT pre_trigger callback triggered"),UVM_LOW)
10     endfunction
11     
12     virtual function void post_trigger(uvm_event e, uvm_object data=null);
13         `uvm_info("UVM_EVENT_CALLBACK",$sformatf("UVM EVENT post_trigger callback triggered"),UVM_LOW)
14     endfunction
15 endclass
16 
17 //step2.instantiate callback class;
18 typedef uvm_callbacks #(uvm_event, int_event_callbacks) cbs;
19 int_event_callbacks interrupt_event_cbk=new("interrupt_event_cbk");
20 
21 //step3.register callback class;
22 uvm_config_db#(uvm_event)::set(null,"","transmit_b",transmit_barrier_ev);
23 cbs::add(transmit_barrier_ev, interrupt_event_cbk);

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM