基于FPGA的数字滤波设计—FIR设计2
3.2.3双口RAM容量的计算和划分(固定边界的RAM实现循环缓冲机制)
首先介绍固定边界的RAM实现循环缓冲机制,如图3.6所示。RAM中保存四个最新数据样本的“时间历史”。将新数据值写入存储器时,覆盖最旧的值,可以在FPGA内部的固定边界RAM中实现这一延迟线。为方便存储器寻址,从存储器读取旧数据值时,应从刚写入值的位置之后的一个位置开始。例如,假设将x(4) 写入存储器位置0 ,则随后应从位置1、2、3、0读取数据值。可以将这个例子推广以支持任意抽头数。以这种方式寻址数据存储器位置时,地址发生器只需要按顺序提供地址,而不用考虑是寄存器读操作还是寄存器写操作。到达最后一个位置时,存储器指针必须复位到缓冲器的起始位置,因此这种数据存储缓冲器是循环的。系数与数据同时取出。所选的寻址方案决定了最旧的数据样本必须最先取出。因此,最后一个系数必须最先取出。系数可以反向存储在存储器中:h(N-1) 是第一个位置,h(0)是最后一个位置,地址发生器提供递增地址。或者,系数也可以正常方式存储,而对系数的访问则是从缓冲器的末端开始,地址发生器递减。在图7.12 所示的例子中,系数以逆序存储。
然后我们确定本设计所需的RAM容量。从结构中知道ADC需要向RAM中写入数据,而MAC单元需要从RAM中读出数据,所以,设计了一个双口RAM。对RAM的读写操作拥有两个独立的地址和数据总线。在操作过程中需要注意读写冲突。RAM所需要的容量可以由下述公式计算得来:
(3-1)
其中maxadd_ram为ram地址最大值,chan_num表示通道数,n为FIR阶数。
那么在本设计中,计算得maxadd_ram=1536,取大于1536最近的2的幂次方2048。这是由于FPGA内部定义的RAM容量必须为2的幂次方。所以双口RAM需要的容量为2048*16bits=8M4K,即需要8个M4K容量。RAM的需要11bits地址线。将11根地址线分成高低两个部分组成。高5位由通道数决定。低6位能够确定64个存储单元,和滤波阶数相对应。如图3.7所示。
这样为每个通道准备了64个存储单元。RAM读写操作说明:
1、Temp_Add作为指针,每次ADC有新值采集来时,Temp_Add自加1,结合通道值,作为写入地址。
2、在FIR计算时,Temp_Add对应的存储单元为最新值,Temp_Add+1为最旧值,Temp_Add自加64次读出当前通道保存的所以值,参与MAC乘累加运算。
3、必须保证读写不能冲突,所以在ADC模块的data_ok上升沿时执行写入操作,下降沿时开始运算。
3.2.4 基于FPGA的FIR滤波器的实现
分析了MAC单元和RAM单元后,就可以实现具体的FIR滤波器了。
从图3.5可知,实现FIR滤波器,数据经过了哪些资源模块,简单的连接这些模块可以实现数据路径的建立。建立好的数据路径就像是一条完整的生产线,但如何生产需要额外的控制单元,譬如,何时开始滤波,何时向RAM中写入数据,何时从RAM中读出数据,等等。这些关键的指令都需要控制模块在适当的时候发出。显然,现在缺少这些核心的控制模块。如图3.8所示,加入控制模块后的结构多了RAM的写入控制模块、MAC控制模块和数据输出调整模块。
其中,wr_ram_ctr模块,在检测到adc_data_ok上升沿后向ram中写入新采集到的数据;mac_ctr模块,作为FIR计算控制核心,在检测到adc_data_ok下降沿后开始计算FIR,即从RAM和ROM中读出数据,并决定何时结束FIR的计算;adjust_out主要完成归一化mac输出的结果,并调整数据时序。
设计过程中的注意点:
1、 数据和系数送到MAC单元的两个输入端口需要同步;
2、 每次FIR计算需要64次乘加运算,加上数据在寄存器之间延时,实际运算需要69个CLK系统时钟周期;
3、 每次FIR计算完毕需要对MAC内部寄存器清零。
文章评论(0条评论)
登录后参与讨论