
基于分布式算法的fir平方根升余弦多相滤波器的仿真_上传.doc
17页基于分布式算法的基于分布式算法的 FIR 平方根升余弦多相平方根升余弦多相滤波器的仿真、设计与实现滤波器的仿真、设计与实现实验要求实验要求设计的 FIR 根升余弦滤波器的参数要求如下: 序号序号参数名称参数名称参数参数1滤波器类型平方根升余弦 FIR 滤波器2阶数32 3信号传输速率8.448Mbps 4过采样点数4Points/bit 5升余弦系数0.6实验原理实验原理过采样与滤波器的多相实现过采样与滤波器的多相实现在通信系统中,不论是成型滤波器还是匹配滤波器都是对源信号进行过采样后的的信 号进行滤波【1】 图 1、过采样和滤波示意图如图 1 所示,将想经 I 倍过采样后得到,再经过冲击响应为1 1()x nT22()upxn T的 FIRLPF 得到输出序列22()h n T22()upyn T在时刻 的值,是由下式来计算:22()upyn T(1)将 带入(1)式有:(2)进一步定义,方程(2)变为:(3)由于是经 I 倍上采样得到的,即在每两个数据之间插入了 I-1 个 0,22()upxn T1 1()x nT因此,成立,所以方程(3)变为:(4)由方程(1)可看出,次滤波器是阶的,由于源序列是经过了 I 倍过采样的信号,2MI 故可以化简为方程(4) ,由此可看出,对于任意一个时刻,实际上只用到了 2M 个滤波器系数,当 i不同时,所用的滤波器系数不同,也就是将原来的一个阶滤波器分成了 I 个 2M 阶的2MI 滤波器来实现,这样降低了滤波器的阶数,从而减小了滤波延时,这种实现方式即称为滤波器的多相实现方式,其中称为第 i 相子滤波器。
此处,对信号进行 4 被过采样,滤波器阶数为 32,因此可将滤波器分为 4 相实现,每个子滤波器的阶数为 8假设原滤波器系数为,则每一相的子滤波器系数,应0131,......h hh时以下组合:子滤波器对应的原滤波器系数0( )h l0481216202428,,,,,,,h h h hhhhh1( )h l1591317212529,,,,,,,h h h hhhhh2( )h l26101418222630,,,,,,,h h hhhhhh3( )h l37111519232731,,,,,,,h h hhhhhh表 1、各子滤波器所对应的滤波系数 它的实现框图如图 2 所示:图 2、4 倍过采样的滤波器多相实现结构图FIR 滤波器的分布式算法实现滤波器的分布式算法实现由前一部分可知,对一个 I 过采样的信号进行滤波时,可以将滤波器拆为 I 个低阶滤 波器的组合来实现滤波过程这在一定程度上降低了运算量,减小了滤波延时;但是在 FPGA 实现时对于滤波的卷积过程的实现一般并不是直接按照卷积的定义,每输入一个数 据就去求一次卷积,这样运算的计算量仍然很大,基于此问题就提出了卷积过程的分布式 实现算法。
由于 FPGA 中数据大都是 std_logic_vector 类型,很适合进行二进制的乘加运算,分布 式算法正式基于二进制的乘加运算来实现的 由于卷积相当于将其中的一个序列倒序排列后进行内积运算可表示为【2】:(5)即是前面的滤波器系数的转置再平移 N 步,,即为输入的信息[ ]c n[ ]()c nh Nn[ ]x n序列,假设 FPGA 实现是输入数据是 B 位的,且用补码表示,则:[ ]x n(6)最高位是符号位,当>=0 时;当 4096FIRData((i - 1)*4 + 1) = FIRData((i - 1)*4 + 1) - 4096;endFIRData((i - 1)*4 + 2) = floor(FIRData((i - 1)*4 + 2)/2) + ROM1(BinDataTemp(k) + 1);if FIRData((i - 1)*4 + 2) > 4096FIRData((i - 1)*4 + 2) = FIRData((i - 1)*4 + 2) - 4096;endFIRData((i - 1)*4 + 3) = floor(FIRData((i - 1)*4 + 3)/2) + ROM2(BinDataTemp(k) + 1);if FIRData((i - 1)*4 + 3) > 4096FIRData((i - 1)*4 + 3) = FIRData((i - 1)*4 + 3) - 4096;endFIRData((i - 1)*4 + 4) = floor(FIRData((i - 1)*4 + 4)/2) + ROM3(BinDataTemp(k) + 1);if FIRData((i - 1)*4 + 4) > 4096FIRData((i - 1)*4 + 4) = FIRData((i - 1)*4 + 4) - 4096;endendend FPGA 实现时各模块的借口与时序设计实现时各模块的借口与时序设计在实现时,顶层我采用了 bdf 文件的形式,通过此图可以清晰的看出我的总体设计结 构。
设计中我将整个系统分成了 3 个层次,顶层控制模块负责将数据从数据源 ROM 中读 出,并且进行 4PAM 调制,并将调制信号送给滤波层次的顶层控制模块以进行滤波;滤波 层次的顶层模块则是利用前面以及传来的待滤波的数据,通过一个移位寄存器产生 4 个子 滤波器每次所需要的八个数据,移位寄存器初始化为全 0,经过 7 次移位后才开始产生所 需要的数据并将数据传给滤波的下一模块,这一层则是完成具体的滤波过程,对 4 个子滤 波模块分别处理,时序最为复杂 简化的总框图如下图所示:数据源ROM (1*1024)顶层控制模块4PAM数据ROM (12*4)滤波顶层模块 (地址产生模 块)滤波执行模块子滤波器1ROM (12*256)子滤波器2ROM (12*256)子滤波器3ROM (12*256)子滤波器4ROM (12*256)滤波后数据RAM (12*2048)图 4、系统总框图 顶层控制模块设计如下:图 5_1、顶层模块接口设计图 如图,clk、enable 信号是整个系统仅有的两个输入信号,其余信号根据端口名字不难 理解其意思,其中 FilteredDataRAM 有关的信号是最后将滤波数据读出来看是否正确,此 处我们通过直接查看 RAM 内容来验证,故此处不用。
各信号的时序图可用如下图来表示:图 5_2、FIR32Top 模块时序图 如上图所示,工作过程如下: (1)当当前滤波过程完成时即滤波模块传给顶层模块的 CurrentBitsCompleteFlags 信号 变为 1 有效后,紧接着的 clk 上升沿开始下一个周期 (2)周期开始后的第一件事是连续读两次 SourceROM 取出两个 0、1 数据 (3)读出两个 0、1 数据后紧接着的周期进行 4PAM 编码产生 PAM4ROM 读取地址 (4)读取 4PAM 调制数据 (5)调制数据准备好之后,就让 FIREn 有效,开始这一个周期的滤波运算操作, FIR32Top 模块又等待下一个 CurrentBitsCompleteFlags 上升沿的到来 滤波过程的顶层模块(地址产生模块)图 6_1、地址产生模块接口设计图该模块的时序设计如下图所示:图 6_2、FIR32AddGen 模块的时序图 由上图可知,FIR32AddGen 模块的工作过程如下: (1)下一层次 AddShift 模块的完成信号 CBCFASMFlags 信号有效,变为 1,触发 FIR32AddGen 模块的新周期开始。
(2)新周期开始后第一个 FIRClk 上升沿就让后面的 AddShift 模块停止工作,即让 AddShiftEn=0,同时 FIR32AddGen 内部的一位寄存器移位一次,以保存当前的最 近 7 个周期的数据,以便下一次使用 (3)下一周期让 CurrentBitsCompleteFlags 信号有效,告知 FIR32Top 模块,当前数据滤波过程已经完成,可以输入下一个数据了,接着就等待 FIR32Top 模块准备下一个 数据 (4)待 FIR32Top 模块数据准备好后,即 FIREn 又变为有效,接着就将当前的输入数据 读入 CurrentData 中 (5)下一个周期就让下一层 AddShift 模块开率对当前数据进行滤波,并且从此等待 CBCFASMFlags 信号的再一次有效 滤波器执行模块(Add+Shift 模块)图 7_1、AddShift 模块接口图此模块的时序图如下图所示:图 7_2、AddShift 模块时序图(开始和结束和最后一个 RAM 写周期)图 7_3、AddShift 模块时序图(总体)图 7_4、AddShift 模块时序图(某一次 AddShift 操作) 如图 7_2 所示: (1) 、AddShiftMEn 的上升沿之后开始一个新的 AddShift 周期,周期开始的第一件事就是 让 CBCFASMFlags 无效 (2) 、整个周期内比较复杂,因此我们通过图 7_3 来观察,整个 AddShift 周期内明显可分 为四部分,即对应 4 个子滤波器的滤波过程,此处他们是串行进行的,在实际应用中,他 们四个完全可以并行进行最后再将并行输出数据串行化即可。
此处,对应每个子滤波器都 有一次 RAM 的写操作,即整个周期内输出 4 个数据,也就是 1 个输入对应 4 个输出,即 4 倍过采样对于对 RAM 的写时序图可以看图 7_2 中表示出了,一个周期内最后一个 RAM 写过程 (3) 、对于一个子滤波器的内部过程,如实验原理中的分布式算法一样,此处由于数据是 12 位的,因此,一个过程包括对某片 ROM 的 12 次读取过程,另外就是每次读取后对数据 进行 Add、Shift 操作,图 7_4 表示出了某一次 AddShift 过程: 图中,某时刻 AddShiftClk 的上升沿是读取了 ROM1 的第 76 单元的数据为 4006(此 处的数据实际上是前一周期的数据,即输出数据整体上往后移动了 1 个 AddShift 周期,此 问题还有待解决) ,此时前面所有周期的累加和 AccumulateSum=1881,当 AccumulateTemp=4006 后,两者相加使 AccumulateSum=1791,接着又将 AccumulateSum 左移一位,最高位补 0 使 AccumulateSum=895,在等待下一次的 AddShift 操作。
存储模块的设计图 8_1、ROM 存储模块图 8_2、RAM 存储模块 如图 4(1)所示,各 ROM 存储块都采用 quartus 自带的 lpmrom 生成,都带有 address、clock、clken、q 几个端口,时序很简单,这里不再介绍实验结果及其验证实验结果及其验证本实验通过 matlab 和 vhdl 分别实现,并通过他们各自得出的滤波结果的对比来验证算 法设计和 vhdl 实现的正确性 用 matlab 实现是滤波后的结果如下图所示:292129312532195916643668391020202104 164310674642927611793278131023125 250217521407177724602976299229672439176319651791248429852951289325202083 169814871065617437619106816183813 234425202893295329952487177714021747 246030062993293224522167213016631727 166315851905245229322991298724541775 198118972433297130042971243318971979 177524542987299129222449191916011677 17061624212830442461280328183085323。
