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的合格完成者。

相关文章
相关标签/搜索