热度 21
2013-8-24 14:04
3005 次阅读|
1 个评论
基于 DMA 组件的 SD 卡数码相框 本实例发布于《 SF-CY3 FPGA 套件开发指南 Ver6.15 ( by 特权同学) .pdf 》中,下载地址: http://pan.baidu.com/share/link?shareid=1370802231uk=2184597051 10.12.1 功能概述 如图所示,我们这一个实例要在上一个工程的基础上,添加一个 DMA 组件。这个 DMA 组件挂在 Avalon-MM 总线上,用于 NIOS II 处理器进行一些寄存器的读写,从而完成基本的组件控制功能;而 DMA 组件最核心的功能,当然是搬数据了,并且是在处理器不干涉的情况下,进行数据的搬运,它从某种意义上能够大大缓解处理器的运行负荷。对于我们这个设计,这个 DMA 组件完全是定制化的,咱自己用代码写,而功能也很专一,就是将 CH376 芯片的有效图片数据直接搬运到 LCD 控制器端进行缓存。如此一来,就不再需要上一个实例中那样让处理器读出 CH376 的图片数据,再写到 LCD 控制器端了。一般来说,这样一来通常是能够大大提升系统性能的。只不过,我们这个系统的速度瓶颈还是在于 CH376 的 SD 读写速度,所以和上一个实例相比,这个工程无法带来非常明显的性能提升。但是没有关系,我们的重点在于 DMA 组件的设计,希望大家能够 focus 到这个点上。 关于 DMA ,特权同学收录在《深入浅出玩转 FPGA 第二版》中的文章《 DMA 无处不在》,有较深入的介绍,大家不妨去看看。 10.12.2 DMA 外设组件设计 在我们的系统中, DMA 总线和周边各个组件的详细连接如图所示。连接到 Avalon-MM 总线作为从机,这条总线由片选信号、写选通信号(主机处理器写入)、 16bit 写数据总线、 2bit 地址总线和从机中断信号组成。这条总线不直接传输图片数据,而是用于处理器完成 DMA 组件的各个控制功能。如下表所示, Avalon-MM 总线对应操作的 4 个寄存器功能。 地址 有效位 描述 0 Bit1-0 Bit1: dma_lcd_sel – 该寄存器用于选择 LCD 图片数据传输是 NIOS II 方式(上一个实例的方式)还是 DMA 方式。为 1 时表示 DMA 方式,为 0 时表示 NIOS II 方式。 Bit0: dma_usb_sel – 该寄存器用于选择 CH376 总线的控制是 NIOS II 方式还是 DMA 方式。为 1 时表示 DMA 方式,为 0 时表示 NIOS II 方式。 1 Bit13-0 dma_wraddr – DMA 方式写数据到 LCD 控制器端的页地址寄存器,会自动递增。 2 Bit7-0 dma_dbnum – 本次 DMA 传输数据字节数,取值可以是 1-255 。 irq_enable – 在写该寄存器时,自动开启 DMA 的中断使能位。 3 Bit0 irq_enable – 清除当前 DMA 中断使能位。 深入 DMA 组件内部,我们来看它的各个逻辑接口是如何设计的。如图所示, Avalon-MM 从机接收到的各个控制信号相互协作,完成数据的收发中转。数据传输状态机在 DMA 功能启动并且 DMA 传输数据计数器的值不为零的情况下,将产生 376 并口总线时序读取当前的有效图片数据,并且产生后端 FIFO (后端模块 sdfifo_ctrl.v )写入数据所需的信号。而后端的 FIFO 在每满 160 个 Byte 后便产生一次 SDRAM 的页写操作,每次操作完成就会返回一个应答信号给我们的 DMA 组件,从而递增 Avalon-MM 总线可写入的页寄存器(地址 1 )。 另外,这里大家要注意, CH376 的并口总线虽然在 DMA 操作时处于 DMA 控制状态,但并非所有的 CH376 指令都是由 DMA 组件产生,这些指令还是和上一个实例一样由 NIOS II 处理器产生, DMA 组件只进行读数据的时序产生和控制。其实这是一个很典型的软硬件分工协同设计划分,把复杂的控制交给软件,把高重复性高速率要求的任务交给硬件来实现。 这里,我们还想对 Avalon-MM 从机的中断信号做一些扩展说明。如图所示,从机产生的 interrupt 信号可以是高电平有效( irq ),也可以是低电平有效( irq_n )。如我们选择的是低电平有效,那么就意味着我们的这个中断信号在一般情况下都应该保持高电平,而一旦跳变为低电平后,保持若干时间则 NIOS II 处理器就能够检测到从机发送来的这个中断信号,若是这个中断信号在软件编程时使能了,并且进行了中断函数注册,那么此时 NIOS II 软件就会进入中断函数执行相应的处理。 对于从机而言,我们产生一个中断后,如果这个中断一直保持在低电平,不拉高,那么 NIOS II 处理器就会发生一些异常,可能会一直不断的进出中断函数,这是我们不想看到的。怎么办?好解决,正如我们这个组件中若对地址 3 写数据 0x0 ,则关闭 DMA 组件的中断功能,那么久可以清除这个被拉低的中断信号,从而确保正常的软件继续工作。