首页->【FPGA/CPLD助学小组】

6 0

例说FPGA连载53NAND Flash实例之Avalon-MM总线

特权同学,版权所有

配套例程和更多资料下载链接:

http://pan.baidu.com/s/1c0nf6Qc

1.jpg 

 

话说Avalon-MM总线就好像一条康庄大道,而各个主机或是从机都是通过一条专用通道连接到这条主干线上。主机有访问各个从机的主动权,一个系统中的主机可以不止一个,CPU可以是主机,DMA也可以是。当CPU通过康庄大道访问从机A的时候,DMA也可以通过这条康庄大道访问从机A以外的其他从机,二者互不冲突。但是,如果CPU访问从机ADMA也试图访问从机A,那么我们就发现最终通往从机A的那条“专用通道”就要抗议了,一山难容二虎啊。此时我们就必须考虑加入一些仲裁逻辑,可以让某个主机优先访问,也可以遵循“先来后到”的准则。

回到概念上来,Avalon-MM总线所针对的是主从连接、可以用地址进行访问的通信。对于很多嵌入式的软件工程师,他们潜意识里已经把这些复杂外设的驱动控制理解为对datasheet里那些大大小小的寄存器所对应的地址进行读读写写了。问题也的确这么简单,而Avalon-MM接口就是顺着大家的这种惯常思维(毕竟这已成为了一种标准了)应运而生。其实简单的Avalon-MM接口时序和前面介绍的INTEL接口或是MOTOROLA接口很是有几分相似。所以,大家也不用太恐惧,面对Avalon-MM我们有信心,不仅是弄懂它,更是要玩转它。

因为在实例就是要来做一个与NIOS II连接的Avalon-MM从机组件,所以我们会在实践中更深入的接触Avalon-MM这位漂亮的美眉(MM)。这里为了让大家对Avalon-MM总线的通信方式有一些直观的认识,就列举一个最简单的Avalon-MM主从工作机制进行讨论,也就是之前的例程我们使用GPIO配置为Output外设时的写操作。

就拿第工程实例3PIO_LED外设来看,我们可以先回顾一下当初定义这个外设的功能。无非就是一个1位输出的GPIO外设,当我们软件编程时往其对应地址写入数据值就可以控制LED引脚的输出电平状态。其硬件连接关系大体如图6.8所示。

2.jpg 

6.8 简单的NIOS II处理器与外设互联接口

那么我们可能还会更关心这个硬件连接的具体实现细节,也就是Avalon-MM总结的控制时序。如图6.9所示,打开工程管理窗口中的pio_led模块代码,这个代码是根据我们在Qsys中配置的PIO_LED外设自动生成的。

3.jpg 

6.9 工程代码层次结构

PIO_LED的从机接口逻辑代码如下。

module vip_qsys_pio_led (

                          // inputs:

                           address,

                           chipselect,

                           clk,

                           reset_n,

                           write_n,

                           writedata,

 

                          // outputs:

                           out_port,

                           readdata

                        );

 

  output           out_port;

  output  [ 31: 0] readdata;

  input   [  1: 0] address;

  input            chipselect;

  input            clk;

  input            reset_n;

  input            write_n;

  input   [ 31: 0] writedata;

 

  wire             clk_en;

  reg              data_out;

  wire             out_port;

  wire             read_mux_out;

  wire    [ 31: 0] readdata;

  assign clk_en = 1;

  //s1, which is an e_avalon_slave

  assign read_mux_out = {1 {(address == 0)}} & data_out;

  always @(posedge clk or negedge reset_n)

    begin

      if (reset_n == 0)

          data_out <= 0;

      else if (chipselect && ~write_n && (address == 0))

          data_out <= writedata;

    end

 

 

  assign readdata = {32'b0 | read_mux_out};

  assign out_port = data_out;

 

endmodule

如图6.10所示,从工程的RTL视图里也可以看到PIO_LED外设的接口信号,和代码里的接口是一致的。

4.jpg 

6.10 PIO外设的RTL视图

这些接口中,作为inputs的信号中,时钟信号clk、复位信号reset_n是由系统提供的。其他几个信号如地址信号address、片选信号chipselect、写选通信号write_n和写入数据writedata都是Avalon总线上的常用信号。简单的来看,使用这几个信号组成的Avalon总线接口写时序如图6.11所示。

5.jpg

6.11 PIO外设的写时序波形

写选通信号和片选信号的有效时钟周期数也都是可变的,甚至地址和数据的有效时钟宽度也都是可调整的。由此足见Avalon接口的灵活性,尤其在开发者自己设计Avalon从机作为Qsys上的一个自定义组件时,我们更是可以根据从机的实际状况将各个接口信号的时序关系调整到一个最优的状态。

回过头来,再看前面给出的从机底层代码,用文字描述可能会显得比读代码更枯燥,因为波形都给出来了,有点基础的朋友恐怕都更愿意去对照着波形解读代码。这里的接口代码只是一种最简洁的写法,里面有一些技巧,我们可以模仿,但是不要把思路限制住,我们要活学活用,如此你才会逐渐发觉——设计原来如此简单。

 

 

 


楼主可见