NIOS II與存儲類外設鏈接時的問題

  1. 一篇博文:CPU與flash鏈接時地址線如何鏈接
  2. 問題:爲什麼16Bits數據線,卻連了地址線0
  3. 釋疑:奇妙的Avalon總線
  4. 補充:Avalon總線概述

一、一篇博文:CPU與flash鏈接時地址線如何鏈接ios

  Flash與S3C44B0X鏈接時地址線爲何要偏移一位編程

  文中介紹的是,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

  詳情可查閱上面提供的連接。設計

  • Avalon Memory Mapped Interface (Avalon-MM)
  • Avalon Conduit Interface:可鏈接FPGA引腳,也能夠相互鏈接(固然輸入對輸出)
  • Avalon Tri-State Conduit Interface (Avalon-TC) :注意通過三態橋後,就以字節爲單位編址了,如本文第1點所述,鏈接外設時A0或A0、A1就不能接了
  • Avalon Streaming Interface (Avalon-ST):適合大數據量直接傳輸
  • Avalon Interrupt Interface:中斷
  • Avalon Clock Interface
  • Avalon Reset Interface

  一種經常使用的模式是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的合格完成者。

相關文章
相關標籤/搜索