- 一篇博文:CPU与flash连接时地址线如何连接
- 问题:为何16Bits数据线,却连了地址线0
- 释疑:奇妙的Avalon总线
- 补充:Avalon总线概述
1、一篇博文:CPU与flash连接时地址线如何连接
文中介绍的是,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数据时,就是外设地址2、3的数据组合。当工程师编程访问地址2的int16数据时,就是外设地址1的数据。 在看《嵌入式C文章精华》时遇到了此问题,学习此文后感觉茅塞顿开。2、问题:为何16Bits数据线,却连了地址线0
在接手的一个FPGA的开发项目中使用了512K的SRAM,数据线16位,地址线18位。 电路设计中全部地址线都连了,包括A0。Verilog模块作为Memory Controller,并没有做相应处理。 为什么还能跑的正常呢? 难道是将错就错而变对?(这个常见,有些设计故意把地址线顺序反过来,读写能对应起来就OK,防止被盗版) 由于NIOS II的软件程序中,访问的数据位数不是确定的,有8Bits、16Bits、32Bits,肯定会出错。 为什么能跑呢?3、释疑:奇妙的Avalon总线 FPGA开发中verilog写的SRAM模块,经过Avalon总线与NIOS II CPU交互。那么Memory Controller的功能就是在Avalon总线中实现的。 查阅altera提供的技术文档: 可以找到如下表格: 当从接口数据位数为16Bits时,从侧的地址自动按照数据位数计算地址。哈哈,那么关键点就是这里。疑惑迎刃而解。
4、补充:Avalon总线概述
详情可查阅上面提供的链接。
- 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>有如下宏定义:
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模块。
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的合格完成者。