一开始,想当然地认为,应该直接把CY7C68013A控制器挂接在Avalon总线上,然后用一个TX_DMA通道和一个RX_DMA通道将CY7C68013A控制器(在Avalon总线架构中)与SDRAM控制器相连,但在写完控制器的VHDL代码后做实验时,Nios CPU(Avalon总线上的CPU)好像跟我捉迷藏似的,无论我如何改变时序参数或者按照Avalon协议去做修改,最后仅能实现我预期的一小部分功能,实在是令人失望,主要问题就是:读传输会卡死,很莫名奇妙!我用示波器观测过read信号,它只会出现一次有效地跳变,前提是我安排了两次读传输周期!这个Bug我至今未解决。
呵呵,后面我仔细分析了一下,其实将CY7C68013A控制器直接挂接到Avalon总线上是很傻的做法,原因有3:
(1)无论是CY7C68013A控制器还是Avalon总线都有各自的流控协议,而两者间的差异势必会导致USB数据链路上的拥塞,造成不必要的带宽损失。
(2)CY7C68013A控制器的FIFO空/满信号最终会映射到Avalon总线上的readdatavalid和waitrequest信号上,这样一来当USB host根本没法送USB帧时,如果Nios CPU却偏偏要去读CY7C68013A的OUT端点就会造成readdatavalid无限期的挂起(无效),反之如果Nios CPU向CY7C68013A的IN端点去写数据,而USB host却不进行任何读传输,那么waitrequest也会被无限期挂起(无效)。这样一来,从物理层上而言,这样的挂接是不合适的。
(3)进行DMA传输时DMA Master最希望看见的传输源(Data Source)或者接收方(Data Sink)是类似于SRAM的那种不具备任何流控属性的传输源。因为这样才能充分发挥DMA的优势——Bulk Chunk of Data Transfer。
那该怎么办呢,其实很简单,我开始时真TM2了,把简单问题复杂化了。利用Pingpong思想,直接开两块SRAM Buffer ,然后进行切换,一切搞定。当一块在被Avalon访问时另一块用于和CY7C68013A通信,反之亦然,这样一来,有几个无与伦比的优势就被天然的引入了!
(1)由于用了双缓冲,则Avalon时钟域(200MHz)和CY7C68013A时钟域(48MHz)被直接隔离。
(2)如果将缓冲区深度加大,则传输带宽将会非常接近它的理论上限,因为传输的实际单位是frame(256bytes)
(3)这是典型的异步寄存器控制架构,完全可以通过设置一个Status寄存器和一个Ctrl寄存器完成最终的DMA控制(这属于程序上的控制)
(4)由于采用了SRAM作为中介,CY7C68013A控制器与Avalon的接口也被极大地简化了,其实就是同步SRAM接口,又简单又具备高带宽,何乐而不为之?
呵呵,继续努力得。。。