APB總線詳解及手撕代碼
????????本文的參考資料為官方文檔AMBA?3 APB Protocol specification
????????文檔下載地址:?https://pan.baidu.com/s/1Vsj4RdyCLan6jE-quAsEuw?pwd=w5bi
????????提取碼:w5bi
APB端口介紹
介紹總線具體握手規(guī)則之前,需要先熟悉一下APB總線端口,APB的端口如下:

大體可以分為以下三組:
????????系統(tǒng)信號:PCLK(系統(tǒng)時鐘)、PRESETn(系統(tǒng)復位,低有效)
????????master信號:PADDR(地址信號,確定讀寫的地址)、PSELx(片選信號,拉出來接給搭載APB總線的slave,選中slave時,PSELx信號拉高)、PNEABLE(使能信號,在PSELx拉高一個周期后,必定拉高)、PWRITE(寫使能信號,PWRITE為高時寫有效,為低時讀有效)、PWDATA(寫數據)
????????slave信號:PREADY(ready為高時,代表著一次APB數據傳輸的結束)、PRDATA(讀數據)、PSLVERR(錯誤數據,由slave發(fā)出,具體邏輯由slave內部決定,當slave發(fā)現內部邏輯出現故障,譬如狀態(tài)機狀態(tài)出錯、計數器數字異常等,slave都可以使用內部邏輯把該信號拉高,使得master接收到PSLVERR為高時,哪怕ready拉高表示APB結束了,也可以使master放棄該次傳輸或做出其他應對策略)。
APB寫傳輸

????????如文檔所示,APB的寫分為兩種情況:①沒有等待狀態(tài)的寫;②有等待狀態(tài)的寫。
????????APB和AHB最大的不同就是APB不采用pipeline形式的寫讀方式,因此對于APB協(xié)議來說,最快的寫入或者讀出一個數據的周期是兩周期,先給地址,再寫數據;或者先給地址,再讀數據。APB 協(xié)議文檔中,將上述這種傳輸方式分為兩個階段(phase),給地址的階段稱為Set up phase;緊接著下一周期PENABLE信號拉高,標志著進入寫/讀數據的階段,該階段稱為Access phase。
Write with no wait states

????????一次沒有等待狀態(tài)的寫傳輸如上圖所示,計劃寫數據時,第一周期PSEL拉高,表示選中某個slave,同時給出地址信息Addr1和寫入數據信息Data1,緊接著下一周期,PENABLE信號拉高,PREADY信號也拉高,這時數據寫入完成。

????????沒有等待狀態(tài)的APB連續(xù)寫波形如上所示(代碼見后文),筆者將數據分為了兩組,group1為APB slave的端口信號,group2為APB接的單端口SRAM信號。在第一個周期,也就是Setup phase,psel信號拉高,表示slave被選中,值得注意的是此時要將SRAM的寫信號和使能信號同步拉高,因為我們寫的是一個no wait states的APB接口,數據要在第二周期寫進SRAM的話,就需要提前一拍拉高使能信號和寫信號。然后到了第二周期,penable信號拉高,pready信號也拉高標志著這一次APB傳輸的結束。另外,也正是因為在setup phase我們把SRAM的en信號和we信號拉高了,因此在access phase數據傳輸結束的同時,數據也被寫入到SRAM中。
Write with wait states


在文檔中,對有等待周期的APB寫傳輸描述如上,即:
????????一開始的setup phase和write with no wait沒有區(qū)別,psel拉高,penable為低;緊跟著第二周期,penable拉高之后,進入access phase,進入access phase之后,penable不會拉低,直到pready為高標志著一次傳輸結束時,penable才會隨著pready一起拉低。penable等待pready拉高的這段等待時間為additional cycles,在這個階段PADDR、PWRITE、PSEL、PENABLE、PWDATA都應該保持不變,可以說總線被hold住了。
APB讀傳輸

????????APB的讀傳輸也分為兩種情況:①沒有等待狀態(tài)的讀;②有等待狀態(tài)的讀。
Read with no wait states

????????一次沒有等待狀態(tài)的讀傳輸如上圖所示,讀狀態(tài)和寫狀態(tài)不同,寫數據時PWRITE=1,讀數據時應該令PWRITE=0計劃讀數據時,第一周期PSEL拉高,表示選中某個slave,同時給出地址信息Addr1,緊接著下一周期,PENABLE信號拉高,PREADY信號也拉高,這時數據被讀出,master接受到讀出數據PRDATA。

????????上圖為連續(xù)讀的APB傳輸波形圖,從第一次讀數據可以看到,隨著psel信號拉高,PWRITE=0標志著為讀狀態(tài),此時傳入地址給APB的SRAM,SRAM端口en=1,we=0標志著SRAM為讀模式,數據在下一周期從SRAM給到prdata。
????????這邊還要提一個APB的特點,也是大多人容易忽略的點,APB總線完成一次讀傳輸或者寫傳輸之后,PADDR和PWRITE不會改變,會一直維持到下一次的傳輸,這可以減少功耗。spec中描述如下

手撕代碼
????????筆者寫了一個Write和Read都是with no states的APB SRAM,因為含有SRAM部分,所以在apb_sram中需要例化一個單端口ram,單端口ram代碼如下:
dpram
apb_sram
tb
????????testbench例化apb_sram并給出激勵,我這邊在tb中發(fā)起了10次連續(xù)的隨機寫,然后再發(fā)起10次連續(xù)讀,發(fā)現讀出來的數據和寫入的數據一致。
????????接著又測試了寫和讀無縫銜接在一起的apb傳輸,結果符合spec。tb代碼如下:
vcs仿真結果如下:
波形圖
連續(xù)10次寫、連續(xù)10次讀、連續(xù)10次讀寫波形如下
