從下面一段代碼,我們猜一下最終的輸出是什么?
那我先把運行結果丟給大家,然后從源碼一一來分析為什么是這樣。
get_name() 在uvm_object.svh中定義了這個virtual函數,經過追蹤發現這個函數並沒有被重寫過。
- 經過上述代碼,我們能清楚的看到get_name()其實就是我們new(create)的時候對應的string name.並不是我們聲明的名稱。
- 當然get_name()除了從new(string name)以外,也可以通過set_name()的方式獲取,但是並不常用。
- 對比開頭的那段代碼,我們可以得出get_name()返回的應該是“my_component_create”,而不是“my_component_def”.
get_full_name(),在uvm_object.svh中定義了這個virtaul函數,並且在外部被從寫過。
- 雖然get_full_name()這個函數會在uvm_object.svh以外的函數進行重新,但是我覺得這里的注釋很有意義。解讀一下就是return hierarchy name.並且繼承自uvm_object和uvm_component的意義是不同的。
- uvm_component.svh里面重寫了get_full_name(),但是直白的看好像並不能看出來什么,但是再仔細看,你就可以看出來uvm_component的new函數其實將其調用的。
- get_full_name()其實就是get_name()的拼接!!!!
那既然說到這里,那就要想一個問題,UVM里面有兩大類一類是uvm_component派生來的,比如樹形結構的uvm_driver,另一類的uvm_object派生來的,比如說uvm_sequence.,上面我們看到派生自uvm_component的get_full_name()其實是在uvm_component的new函數完成了拼接,那么派生自uvm_object的類呢?get_full_name()又會表現出什么行為呢?
其實通過源碼分析,我們也可以知道,對於派生自uvm_object的類,get_full_name()其實也就是調用的get_name().所以我們的uvm_sequence/uvm_sequence_item這些其實都是沒有生命的(也就是說這些其實不是uvm樹的節點,所以並沒有Hier)組件其實get_name()=get_full_name().
get_type_name()
通過源代碼我們可以看出,如果派生自uvm_component/uvm_object的函數沒有重寫get_type_name()的話,那么結果應該是源代碼中的值,但實際上從第一張圖上,我們就可以清楚地發現,其實跟我們的預期是不一樣的,那么問題出在什么地方呢?
沒錯,就是`uvm_componet_utils(my_compont)
我們接下來看看這個宏做了什么,如果不看源碼,我們知道這個宏其實就是將component注冊到factory中。下面我們來看一下這個宏的展開的模樣。
- m_uvm_component_registry_internal()這個跟factory相關,這里不展開介紹。
- m_uvm_get_type_name_func()其實已經一目了然了。
- 由此我們也可以猜測,擴展自uvm_object的`uvm_object_utils()應該也有類似的定義。
- get_type_name()其實就是返回的class的名稱。也就是`uvm_componet_utils()/uvm_object_utils()注冊的名稱。
小結:對於uvm_root(null)以及my_casen(uvm_test_top)是在源碼中指定的兩層。
- get_name():返回的是type_id::create(string name,null)里面對應的name.
- get_full_name():根據是不是UVM樹的節點分為兩種情況,一種是擴展自uvm_component的時候,返回的是uvm_test_top.開始的路徑圖,也就是get_name()的拼接,另一種情況是擴展自uvm_object的時候,get_full_name()=get_name().
- get_type_name():返回的是class的名稱,也就是uvm_component_utils()/uvm_object_utils()里面對應的name()
補充,經過一段時間的學習我發現上面針對uvm_sequence_item的理解其實是不太准確的,所以這次來填坑。
- 准確來講,雖然uvm_sequence_item是從uvm_obejct擴展來的,但是sequence其實是對get_full_name做了override的。
- 如果seq掛在在了sqr上面,那么seq的m_sequencer != null,那么get_full_name的返回值應該是m_sequencer.get_full_name+get_name().
- 如果seq是沒有掛在在sqr上面,也就是m_sequencer == null,比如我最開始舉的例子,那么get_full_name的返回值應該是get_name().