一、一篇博文: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的合格完成者。