如果將文章名稱寫成《一個資深驗證工程師通過一篇文章告訴你如何設計寄存器》,那麼這篇文章有可能會被傳到各大BBS去,獲取不錯的點擊量。但是,當我想到我身邊曾有很多比我優秀的驗證工程師,他們都沒有如此自稱時,我就覺得這個標題我實在承受不起,哈哈!
寄存器(域段)訪問屬性的概念
一個典型的寄存器定義,如下所示。
寄存名:系統配置寄存器[0xC800_0000]
域段名 |
域段範圍 |
訪問屬性 |
默認值 |
描述 |
rsv |
31-7 |
RO |
0 |
保留 |
6-4 |
RW |
0 |
啓動核心數 0:rmvb 1:mpeg4 2:avi 3:3gp 4:flv 5:dat others:rsv |
|
rsv |
3-1 |
RO |
0 |
保留 |
mode_type |
0 |
RW |
0 |
0:正常模式 1:測試模式 |
域段的訪問屬性,是從處理器(如CPU)端來看的。以mode_type爲例,該域段的訪問屬性爲RW(讀寫),表示該域段的值既可以被處理器寫入,也可以被處理器讀出。一般情況下,寄存器域段的訪問屬性與寄存器的訪問屬性一致。對於寄存器中的保留域,一般處理器是無法操作保留域段的信息的,可以認爲保留域只可以被讀出默認值“0”,可以將保留域的訪問屬性標記爲“RO(只讀)”。
由於保留域的存在,如上例,“系統配置寄存器”的訪問屬性爲RW,其中,域段mode_type和video_format的訪問屬性也是RW,但保留域的訪問屬性就是RO,即存在寄存器訪問屬性和域段訪問屬性不一致的情況。
爲了描述方便,下文所有“寄存器訪問屬性”將特指爲某個有效“域段的訪問屬性”。
寄存器訪問結構
如圖所示,處理器(CPU)通過其總線Master訪問邏輯設計的總線Slave。總線Slave解析寄存器總線訪問,如果是寫操作,一般轉換爲對邏輯處理的配置,如果是讀操作,一般轉換爲讀取邏輯處理的上報結果。
爲了下文描述方便,將處理器寫信息稱爲“數據”,而將邏輯設計內部存儲的已有信息,稱爲“域段值”。
UVM定義的寄存器訪問屬性
UVM定義的寄存器訪問屬性共有25個。如果想一下記住25個訪問屬性,還是比較難的。因此,我們需要對訪問屬性先做一個歸納總結:
1、 所有包括R的訪問屬性,會將寄存器的“域段值”讀出給處理器;
2、 所有包括W的訪問屬性,會將處理器的“數據”,傳遞給寄存器域段處理,但不一定是簡單的賦值操作;
3、 讀操作的處理範圍是整個寄存器(因爲讀操作無法區分讀哪個域段,不讀哪個域段);
4、 寫操作的處理範圍可以是整個寄存器,也可以是某個域段,當需要區分域段時,需要通過1(或0)標記哪個域段信息被操作;
5、 所有包括“C”的訪問,將清除(清0)對應處理範圍的信息,處理範圍可能是整個寄存器,也可能是整個域段;
6、 所有包括“S”的訪問,將置位(置1)對應處理範圍的信息,處理範圍可能是整個寄存器,也可能是整個域段;
7、 所有包括“T”的訪問,將翻轉(0->1,1->0)對應處理範圍的信息,處理範圍可能是整個寄存器,也可能是整個域段;
如果您已經理解以上7點,那麼我們可以繼續學習UVM的寄存器屬性了。
UVM定義的寄存器訪問屬性如下所示。
”RO” | W: no effect, R: no effect |
”RW” | W: as-is, R: no effect |
”RC” | W: no effect, R: clears all bits |
”RS” | W: no effect, R: sets all bits |
”WRC” | W: as-is, R: clears all bits |
”WRS” | W: as-is, R: sets all bits |
”WC” | W: clears all bits, R: no effect |
”WS” | W: sets all bits, R: no effect |
”WSRC” | W: sets all bits, R: clears all bits |
”WCRS” | W: clears all bits, R: sets all bits |
”W1C” | W: 1/0 clears/no effect on matching bit, R: no effect |
”W1S” | W: 1/0 sets/no effect on matching bit, R: no effect |
”W1T” | W: 1/0 toggles/no effect on matching bit, R: no effect |
”W0C” | W: 1/0 no effect on/clears matching bit, R: no effect |
”W0S” | W: 1/0 no effect on/sets matching bit, R: no effect |
”W0T” | W: 1/0 no effect on/toggles matching bit, R: no effect |
”W1SRC” | W: 1/0 sets/no effect on matching bit, R: clears all bits |
”W1CRS” | W: 1/0 clears/no effect on matching bit, R: sets all bits |
”W0SRC” | W: 1/0 no effect on/sets matching bit, R: clears all bits |
”W0CRS” | W: 1/0 no effect on/clears matching bit, R: sets all bits |
”WO” | W: as-is, R: error |
”WOC” | W: clears all bits, R: error |
”WOS” | W: sets all bits, R: error |
”W1” | W: first one after HARD reset is as-is, other W have no effects, R: no effect |
”WO1” | W: first one after HARD reset is as-is, other W have no effects, R: error |
”NOACCESS” | W: no effect, R: no effect |
寄存器訪問屬性的應用
RW(讀寫)
RW寄存器是邏輯設計中數量最多的寄存器,一般用於配置操作。其中的讀操作是可測試性設計,寫入的寄存器,處理器可以通過讀取操作,判斷寫入信息是否正確。
有“高人”曾建議,配置寄存器就應該採用“WO只寫”方式,這樣可以節省寄存器資源。我當時真的感到“天雷滾滾”!不怕被測試、軟件,以及項目經理罵死,就這麼設計好了。省的那點資源,不夠費的功夫。
RO(只讀)
RO寄存器是邏輯設計中數量第二多的寄存器,一般用於狀態指示,或者信息採樣。
狀態指示舉例:當前的時鐘是否鎖定(PLL_LOCK);當前的狀態機狀態(FSM_State);
信息採樣舉例:當前處理數據的平均功率統計(averagepower)。
RC(讀清)
RC寄存器,讀操作後,域段信息就被清除。應用RC寄存器的考慮因素包括:
從設計便利性考慮:一段時間的統計信息,如計數值,或者平均功率,讀操作完成後,數據清零,重新統計;
從信息的重要性考慮:相對不是特別重要的信息,一般可以採用讀清操作。
RC寄存器與RO寄存器的結構基本一致,僅多了一步清除操作。
RS(讀置位)
與RC的應用場景類似,有時候計數器置位後,下一次計數則從0xffff直接跳到0,比較方便。但是,本能上不喜好這樣的設計,沒有任何特殊理由。
WC(寫清)
主要與RC(讀清)寄存器對比,相比較讀清,寫清可以在軟件確信獲取到信息後,再清除信息。需要注意的是,WC(寫清)是與RC(讀清)做選擇,而不是和W1C(寫1清)做選擇。因爲WC和RC都是對整個寄存器的操作,而W1C是對域段的操作,應用場景完全不同。
W1C(寫1清)
最常用於“中斷狀態指示寄存器”。
當中斷髮生時,邏輯發送中斷“脈衝”給寄存器域段緩存。處理器收到中斷線指示(中斷使能場景)後,讀取相應的“中斷狀態指示寄存器”,獲取是哪個信息導致的中斷。處理器依次處理中斷對應信息,完成中斷處理程序後,向對應域段的寫1,清除對應域段。
一般W1C寄存器,與某個RW寄存器的域段一一對應,該RW寄存器爲“中斷狀態指示使能寄存器”,一個bit的使能,對應一個bit的中斷狀態指示。
寫1清的好處是,僅操作對應域段,而不影響其他域段的中斷信息。
W1C(寫1清)要小心“電平指示”中斷。
對於“脈衝”指示的中斷,中斷信息緩存在寄存器域段裏,如果清中斷,系統中就不再有中斷指示。但是,對於“電平指示”的中斷,僅僅清除寄存器域段中的指示是不夠的,還需要清除邏輯處理髮出的持續電平信號。否則,即使清除了寄存器域段中的中斷指示,邏輯處理的中斷電平又會立刻將寄存器中的中斷指示拉起。導致最終陷入“清中斷->重新拉起中斷”的死循環。
W1T(寫1翻轉)
一個非常有意思的寄存器訪問屬性,最常用於“總線測試寄存器”。舉例如下:
當“域段值”爲8’hFF時,寫入8’h55,讀出8’hAA,證明總線(APB/AXI)讀寫正常。
W1(只寫1次)
一般這樣的寄存器應用於做“一次”操作的判斷(flag)。應用該寄存器的需求分析:
1、 從便利性的角度分析:可以多個軟件進程調用寫,只要有一個寫操作,寫操作就記錄,且屏蔽後續的寫操作。在某些場景下,這樣的設計會比較方便;
2、 從“安全性”的角度分析:某些特殊信息,如DDR初始化啓動指示等,上電後,僅操作一次。
但是,從設計角度講,這樣的設計有些過於嚴格要求硬件,而放鬆軟件。但是,硬件如何設計不合理,軟件是沒有辦法挽回的。例如DDR初始化,可能在某些場景,需要執行兩次,如果軟復位操作不到對應寄存器,系統就可能掛死。因此,要慎用W1(只寫1次)訪問屬性的寄存器。
其餘寄存器訪問屬性
其餘寄存器訪問屬性,不是特別常見,本文就不再贅述。雖然更多的寄存器屬性,可以帶來應用上的方便,但是也會帶來理解上的障礙。從溝通的角度來看,我建議儘量少用不常見的寄存器屬性。當然,哪些寄存器訪問屬性是常用的,哪些是不常用的,這個問題可以好好探討。