zoukankan      html  css  js  c++  java
  • Nios II Avalon MM 外设地址对齐

    2010-09-02 22:07

    Nios II Avalon MM 外设地址对齐

    虽然Nios II CPU是32位构架,但是Avalon总线作为一种开放的总线结构,为了兼容各种位宽的CPU和外设,Avalon Interconnect Fabric地址总线使用的是字节寻址的方式,也就是A0地址一定指向外设的某个字节(但是不一定和外设地址线的A0连接,详后);而不是同CPU宽度的某个32bit空间。

    所以,在自定义Avalon MM外设的时候,如果是Avalon MM Master,地址线一定是32根,最低位寻址到一个字节(不一定会用到~~)。

    首先注意到Avalon MM Slave可以声明自己采用的地址对齐方式有两种:Native alignment 和Dynamic Alignment。

    动态地址对齐方式是将MM从设备的地址空间连续地映射到主设备空间。内存类型的从设备控制器应该采用这种方式。在这种方式下,主设备的每一次读传输(或写传输)对应从设备一次或多次读传输(或写传输)。譬如,主设备数据宽度为32bit,从设备为16bit,则主设备每发起一次读传输,从设备将被读两次,用于返回32bit数据(由Avalon Interconnect Fabric逻辑插入状态机实现,用户无需关心具体实现),同理,每一次写操作,从设备执行两次写入操作。Dynamic对齐方式数据宽度限定为8*2^n次方,即只能为8 16 32 64等值。

    源生地址对齐方式将从设备的自然数据宽度(即从设备DATABUS宽度)映射到主设备的单位数据宽度(即主设备的DATABUS宽度),假设主设备宽度为32比特,从设备为16比特,且假设从设备的0x00映射到主设备0x00;则从设备的0x02映射到主设备的0x04。寄存器表类型的外设可以考虑使用这种对齐方式。在这种对齐方式里面,主设备发起的每一次读传输(或写传输),只会对应从设备的一次读传输(或写传输),如果主设备数据宽度大于从设备,那么高位内容被零填充,如果主设备宽度小于从设备,则高位自动被抛弃(Truncated)。

    那么,如果要书写这些不同方式的外设,应该如何设定Avalon MM Slave控制器的地址线和可选的byteenable信号呢?其实,对于每一个从设备,地址线的最低位指向从设备单位数据宽度(one word)。在这里,word大小可以是8,16,32,64....而不用担心外设是用Dynamic还是Native地址对齐。

    如果是Dynamic外设,为了方便不同数据宽度的主设备读取,最好包含byteenable信号。byteenable信号为one hot编码,每一根信号线(lane)对应一个字节。信号的宽度取决于从设备数据总线的宽度,如果为16,则byteenable信号宽度为2.;如果为32bit,则byteenable信号宽度为4。这样在SOPC Builder生成系统的时候,Avalon Interconnect Fabric会自动适配这些信号线到具体的Fabric地址线,譬如外设宽度为16,则从设备控制器的A0连接到Fabric的A1。而Fabric的A0会看外设是否声明了byteenable信号,如果存在,则将A0译码成2bit宽度的Byteenable信号(并连接到外设声明的byteenable信号)。如果没有,则Fabric A0没有连接。

    如果是Native外设,从设备的地址线连接到内部Fabric的方式和Dynamic是一致的,只是没有了byteenable信号,以及低位地址线的译码。

    在SOPC Builder里面用component editor添加组件的时候,在Interface选项卡里,每个Avalon MM栏里面都有一个Deprecated子栏目,展开它,选择Slave Addressing的方式为Dynamic。如果是内存,还要勾选Memory Device。这个选项卡还真的有些猥琐,不注意还看不到,不过没办法,人家都说了是Deprecated。

    在Nios II EDS里面,提供两类IO指令来直接存取DYNAMIC外设和NATIVE外设,如下图:

    IORD和IOWR直接指定外设的基地址和偏移量,这个偏移量的话是Width of BUS的整数倍,也就是说,如果CPU为32bit宽度,则单位偏移量就是4个字节,也就是,写REGNUM==0的寄存器就是基地址的寄存器,REGNUIM==1的话就是第二个寄存器,地址的话自然是BASE_ADDR+4。

    而IORD_8DIRECT读取的正如后面所说,是BASE_ADDR+OFFSET位置的一个字节。

    不过我比较奇怪的是,如果我用IOWR_32DIRECT(BASE,2,DATA)之类的指令会出现什么后果呢,也就是说,BASE+OFFSET不是4的整数倍,但是却想去读取一个32bit的数据。感觉这种情况硬件是不支持的。。。

  • 相关阅读:
    利用 localStorage 储存css js
    实现图片延迟加载的一些 库
    less 应用
    vue 问题集合||
    一个简易的登录框
    python_协程方式操作数据库
    爬取知名社区技术文章_分析_1
    python_爬百度百科词条
    python_爬校花图片
    python_猜年龄
  • 原文地址:https://www.cnblogs.com/daydayupwoniu/p/3083841.html
Copyright © 2011-2022 走看看