一、一篇博文:CPU與flash鏈接時地址線如何鏈接ios
文中介紹的是,32位CPU內每一個地址對應的一個字節,當訪問32Bits的flash時沒有問題,地址一一對應。那麼當訪問16Bits或者8Bits的外設時呢?
16Bits外設時:CPU地址線A1鏈接外設的A0,CPU地址線A0懸空;
8Bits外設時:CPU地址線A2鏈接外設的A0,CPU地址線A0、A1懸空。
簡單說這是由於外設的一個地址對應的不是一個字節,而是相應的數據線位數。這就須要有一層Memory Controller,其實現的功能以16Bits外設說明:
當工程師編程訪問(意味着CPU地址)地址0的int32數據時,Memory Controller就進行兩次讀或寫,先是外設地址0(CPU地址0)的16Bits數據,而後外設地址1(CPU地址2)的16Bits數據,組合後提供給使用者。當工程師編程訪問地址4的int32數據時,就是外設地址二、3的數據組合。當工程師編程訪問地址2的int16數據時,就是外設地址1的數據。
在看《嵌入式C文章精華》時遇到了此問題,學習此文後感受茅塞頓開。app
二、問題:爲什麼16Bits數據線,卻連了地址線0
在接手的一個FPGA的開發項目中使用了512K的SRAM,數據線16位,地址線18位。
電路設計中所有地址線都連了,包括A0。Verilog模塊做爲Memory Controller,並無作相應處理。
爲何還能跑的正常呢?
難道是將錯就錯而變對?(這個常見,有些設計故意把地址線順序反過來,讀寫能對應起來就OK,防止被盜版)
因爲NIOS II的軟件程序中,訪問的數據位數不是肯定的,有8Bits、16Bits、32Bits,確定會出錯。
爲何能跑呢?
三、釋疑:奇妙的Avalon總線
FPGA開發中verilog寫的SRAM模塊,通過Avalon總線與NIOS II CPU交互。那麼Memory Controller的功能就是在Avalon總線中實現的。
查閱altera提供的技術文檔:《Avalon Interface Specification》
能夠找到以下表格:學習
當從接口數據位數爲16Bits時,從側的地址自動按照數據位數計算地址。大數據
哈哈,那麼關鍵點就是這裏。疑惑迎刃而解。ui
四、補充:Avalon總線概述spa
詳情可查閱上面提供的連接。設計
一種經常使用的模式是NIOS II CPU做爲Avalon-MM的主接口,verilog模塊寫的外設爲從接口。在目錄「*:\altera\10.1\nios2eds\components\altera_nios2\HAL\inc」下有<io.h><alt_types.h>等。其中<io.h>有以下宏定義: code
1 #define __IO_CALC_ADDRESS_NATIVE(BASE, REGNUM) \ 2 ((void *)(((alt_u8*)BASE) + ((REGNUM) * (SYSTEM_BUS_WIDTH/8)))) 3 #define IORD(BASE, REGNUM) \ 4 __builtin_ldwio (__IO_CALC_ADDRESS_NATIVE ((BASE), (REGNUM))) 5 #define IOWR(BASE, REGNUM, DATA) \ 6 __builtin_stwio (__IO_CALC_ADDRESS_NATIVE ((BASE), (REGNUM)), (DATA))
以上是靜態地址對齊。操做的地址會直接給到verilog模塊。component
1 #define __IO_CALC_ADDRESS_DYNAMIC(BASE, OFFSET) ((void *)(((alt_u8*)BASE) + (OFFSET))) 2 #define IORD_32DIRECT(BASE, OFFSET) \ 3 __builtin_ldwio (__IO_CALC_ADDRESS_DYNAMIC ((BASE), (OFFSET))) 4 #define IORD_16DIRECT(BASE, OFFSET) \ 5 __builtin_ldhuio (__IO_CALC_ADDRESS_DYNAMIC ((BASE), (OFFSET))) 6 #define IORD_8DIRECT(BASE, OFFSET) \ 7 __builtin_ldbuio (__IO_CALC_ADDRESS_DYNAMIC ((BASE), (OFFSET))) 8 9 #define IOWR_32DIRECT(BASE, OFFSET, DATA) \ 10 __builtin_stwio (__IO_CALC_ADDRESS_DYNAMIC ((BASE), (OFFSET)), (DATA)) 11 #define IOWR_16DIRECT(BASE, OFFSET, DATA) \ 12 __builtin_sthio (__IO_CALC_ADDRESS_DYNAMIC ((BASE), (OFFSET)), (DATA)) 13 #define IOWR_8DIRECT(BASE, OFFSET, DATA) \ 14 __builtin_stbio (__IO_CALC_ADDRESS_DYNAMIC ((BASE), (OFFSET)), (DATA))
以上是動態地址對齊,此時的Avalon總線就是Memory Controller的合格完成者。