1. 程式人生 > >UVM暫存器篇之六:暫存器模型的常規方法(上)

UVM暫存器篇之六:暫存器模型的常規方法(上)

本文轉自:http://www.eetop.cn/blog/html/28/1561828-6266223.html

mirrored、desired和actual value

在我們應用暫存器模型的時候,除了利用它的暫存器檔案資訊,也會利用它來跟蹤暫存器的值。跟蹤暫存器的值,一方面是建立mirrored value,另外一方面是為建立desired value。讀到這裡,讀者們首先需要確立,任何一個暫存器模型中的暫存器例項,都應該有兩個值,一個是映象值(mirrored value),一個是期望值(desired value)。期望值是先利用暫存器模型修改軟體物件值,而後利用該值更新硬體值;映象值是表示當前硬體的已知狀態值。期望值往往由模型預測給出,關於預測,我們上一節給了一些基本概念,即在前門訪問時通過觀察匯流排或者在後門訪問時通過自動預測等方式來給出映象值。然而映象值有可能與硬體實際值(hardware actual value)不一致,例如狀態暫存器的映象值則無法保持與硬體實際值保持同步更新,另外如果其他訪問暫存器的通路修改了暫存器,那麼可能由於那一路匯流排沒有被監測,因此暫存器的映象值也無法得到及時更新。

 

接下來我們要討論的暫存器模型預測方式,與上面的三種值相關,這是因為預測行為會直接影響到如何更新映象值和期望值。在介紹之前,需要需要分辨與,mirrored value與desired value是暫存器模型的屬性,而actual value則對應硬體的真實數值。

 

prediction的分類

UVM提供了兩種用來跟蹤暫存器值的方式,我們將其分為自動預測(auto prediction)和顯式預測(explicit )。自動預測的例碼在上一節中已經給出,如果使用者想使用自動預測的方式,還需要呼叫函式uvm_reg_map::set_auto_predict()。這兩種預測方式的顯著差別在於預測的暫存器數值上,顯式預測更為準確,具體原因我們可以通過下面對兩種模式的分析來得出。

 

自動預測(auto prediction)

如果使用者並沒有整合獨立的predictor在環境中,而是利用暫存器的操作來自動記錄每一次暫存器的讀寫數值,並在後臺自動呼叫predict()方法的話,這種方式被稱之為自動預測。這種方式簡單有效,然而需要注意,如果其它一些sequence直接在匯流排層面上對暫存器進行操作(跳過暫存器級別的write()/read()操作,或者通過其它匯流排來訪問暫存器等等這些為通過暫存器模型做操作的方式來訪問暫存器都無法自動得到暫存器的映象值和預期值。

 

顯式預測(explicit prediction)

更為可靠的一種方式是在物理總線上通過監視器來捕捉匯流排事務,並將捕捉到的事務傳遞給外部例化的predictor(預測器)。該predictor由UVM引數化類uvm_reg_predictor例化並整合在頂層環境中。在整合的過程中,需要將adapter與map的控制代碼也一併傳遞給predictor,同時將monitor採集好的事務通過analysis port接入到predictor一側。這種整合關係可以使得,monitor一旦捕捉到有效事務,會發送給predicotr,再尤其利用adapter的橋接方法,實現事務資訊轉換,並將轉化後的暫存器模型有關資訊更新到map中。預設情況下,系統將採用顯式預測的方式,這就要求整合到環境中的匯流排UVC的monitor需要具備捕捉事務功能和對應的analysis port,以便於predictor連線。

 

關於predictor在頂層環境中的整合,讀者可以通過下面的一段例碼片段來掌握整合時的幾個要素:

 

 

 

uvm_reg的訪問方法

在給出暫存器模型的常見應用模式之前,我們還需要更全面瞭解uvm_reg_block/uvm_reg/uvm_field三個類提供的用於訪問暫存器的公共方法:

 

在上一節給出的例碼中,已經類比了uvm_reg_block/uvm_reg/uvm_reg_field的方法和uvm_reg_sequence封裝的方法。在上面給出暫存器模型相關類的詳盡方法列表之後,我們再將uvm_reg_sequence提供的方法(均是針對暫存器物件的,而不是暫存器塊或者暫存器域)整理如下,方便讀者進行對比使用:

在上一節中,我們對uvm_reg提供的四種方法即read()、write()、peek()和poke()如何進行前門訪問和後門訪問做了介紹。結合著mirrored value、desired value和actual value,我們需要理解這四種方法在呼叫時,三個值之間的變化時序關係:

  • 對於前門訪問的read()和write(),在匯流排事務完成時,映象值和期望值才會更新為與總線上相同的值,這種預測方式是顯式預測。

  • 對於peek()和poke(),以及後門訪問模式下的read()和write(),由於不通過匯流排,預設採取自動預測的方式,因此在零時刻方法呼叫返回後,映象值和期望值也相應修改。

 

關於reset()和get_reset()的用法,下面也給出部分例碼。例如硬體在復位觸發時,會將內部暫存器值復位,而暫存器模型在捕捉到復位事件時,為了保持同硬體行為一致,也應當對其復位。這裡注意的是,復位的物件是暫存器模型,而不是硬體。

 

 

在復位之後,使用者也可以通過讀取暫存器模型的復位值(與暫存器描述檔案一致),與從前門訪問獲取的暫存器復位值進行比較,以此來判斷硬體各個暫存器的復位值是否按照暫存器描述檔案去實現。這裡個get_reset()方法指的也是暫存器模型的復位值,而不是硬體。

 

 

 

mirror()方法與read()方法類似,也可以選擇前門訪問後者後門訪問,不同的是,mirror()不會返回讀回的數值,但是會將對應的映象值修改。在修改映象值之前,使用者還可以選擇是否將讀回的值與模型中的原映象值進行比較。下面的例碼一方面在更新映象值之前,首先將讀回的值與上一次映象值做了比對,隨後再更新映象值。譬如,對於配置暫存器,可以採用這種方法來檢查上一次的配置是否生效,又或者對於狀態暫存器,可以選擇只更新映象值不做比較,這是因為狀態暫存器隨時可能被硬體內部邏輯修改。

 

下面的方法是運用set()和update()對暫存器做批量修改。首先set()方法的物件是暫存器模型自身,通過set()可以修改期望值,而在暫存器配置時不妨先對其模型隨機化,再配置個別暫存器或者域,當暫存器的期望值與映象值不相同時,可以通過update()方法來將不相同的暫存器通過前門訪問或者後門訪問的方式做全部修改。這種set()和update()的方式較write()和poke()的寫暫存器方式更為靈活的是,它可以實現隨機化暫存器配置值(先隨機化暫存器模型,後將隨機值寫入到暫存器),繼而模擬更多不可預知的暫存器應用場景,另外update()強大的批量操作暫存器功能使得修改暫存器更為便捷。