2024/8/26
开新坑,本文更新至学完滤波器为止,目前学习了FIR与IIR
1.基础知识
1.1 二进制表述
定点数有原码、反码及补码三种表示法,这三种表示法在 FPGA 设计中使用得十分普遍, 下面分别进行讨论。
1)原码表示法原码表示法是指符号位加绝对值的表示法。例如,二进制数(x)2=0D110表示的是+0.75;(x)2=1D110表示的是−0.75
2)反码表示法正数的反码与原码相同。将负数的原码除符号位外的所有位取反,即可得到负数的反码
3)补码表示法正数的补码、反码及原码完全相同,负数的补码与反码之间有一个简单的换算关系,即补码等于反码在最低位加1。
1.2浮点数表示
浮点数是属于有理数中某特定子集的数的数字表示,在计算机中用来近似表示任意某个 实数。具体来说,这个实数由一个整数或定点数(即尾数)乘以某个基数的整数次幂得到。 这种表示方法类似于基数为 10 的科学记数法。 一个浮点数 A 可由两个数 m 和 e 来表示,即 A = m × b e 。
在这种表示方法中,我们选择 一个基数 b(记数系统的基)和精度 B(使用多少位来存储)。m(即尾数)是 B 位二进制数, 如±d.ddd…ddd。如果 m 的第一位是非 0 整数,则 m 称为规格化后的数据。一些数据格式使 用一个单独的符号位(s 代表“+”或者“−”)来表示正负,这样 m 必须是正的。e 在浮点数 中表示基的指数。
1.3 补充
FPGA 中的二进制数可以分为定点数和浮点数两种格式,虽然浮点数的加 减法运算相对于定点数而言,在运算步聚和实现难度上都要复杂得多,但基本的运算仍然是 通过将浮点数分解为定点数运算以及移位等运算步骤来实现的。
需要注意的是,与十进制数运算规则相同,即做加减法运算时,参加运算的两个数的小 数点位置必须对齐,且结果的小数点位置相同。
常数乘法可以通过左移运算得到完全准确的结果, 而常数除法运算却不可避免地存在运算误差。显然,采用分解方法的除法运算只能得到近似 正确的结果,且分解运算的项数越多,精度越高。
对两个长度为 N 的二进制数进行加法运算时,需要采用 N+1 位数据才能获得完全准确的结果。如果需要采用 N 位数据存放结果,那么取低 N 位时就会产 生溢出,得出错误结果,取高 N 位时则不会出现溢出,运算结果相当于减小了 1/2。
运算前后小数点右边的数据位数(也是小数的位数)是固定不变的。 实际上,在 Verilog HDL 语言环境中,如果对两个长度为 N 的数据进行加法运算,为了得到 N+1 位的准确结果,必须先对参加运算的数进行一位符号位扩展
要保证运算结果不溢出,我 们需要计算滤波器输出的最大值,并以此推算输出的有效数据位数。方法其实十分简单,只 需要计算所有滤波器系数绝对值之和,再计算表示该绝对值之和所需的最小无符号二进制数 据位 n,则滤波器输出的有效数据位数为 N+n。
1.4掌握IP
加减法器IP
乘法器IP
除法器IP
浮点数IP
2.FIR与IIR
2.1FIR与IIR滤波器的不同
(1)通常,在满足同样幅频响应设计指标情况下,FIR 滤波器阶数是 IIR 滤波器阶数的 5~ 10 倍。
(2)FIR 滤波器能得到严格的线性相位特性(当 FIR 滤波器系数具有对称性时);IIR 滤 波器在相同的阶数情况下,具有更好的幅度特性,但相位特性是非线性的。
(3)FIR 滤波器的单位脉冲响应是有限长的,一般采用非递归结构,是稳定的系统,即 使在有限精度运算时,误差也较小,即受有限字长效应的影响较小;IIR 滤波器必须采用递归 结构,极点在单位圆内时才能稳定,这种具有反馈的结构,由于运算的舍入处理,易引起振 荡现象(参见例 3-3)。
(4)FIR 滤波器的运算是一种卷积运算,它可以利用快速傅里叶变换和其他快速算法来 实现,运算速度快;IIR 滤波器无法采用类似的快速算法。
(5)在设计方法上,IIR 滤波器可以利用模拟滤波器现成的设计公式、数据和表格等资料; FIR 滤波器则不能借助模拟滤波器的设计成果。由于计算机设计软件的发展,FIR 滤波器、IIR 滤波器的设计均可以采用现成的函数,因此在工程设计中两者的设计难度均已大幅降低。
(6)IIR 滤波器主要用于设计规格化的、频率特性为分段恒定的标准滤波器;FIR 滤波器 要灵活得多,适应性更强。
(7)在 FPGA 设计中,FIR 滤波器可以采用现成的 IP 核进行设计,工作量较小;IIR 滤 波器可用的 IP 核很少,一般需要手动编写代码,工作量较大。
(8)当给定幅频特性且不考虑相位特性时,采用 IIR 滤波器较好;当要求严格线性相位 特性或幅度特性不同于典型模拟滤波器特性时,通常采用 FIR 滤波器。
2.软件细节
具体情况为利用matlab产生信号的TXT文件,将TXT文件利用TB导入到FPGA的寄存器中去,然后利用寄存器读取TXT形成信号,读入到调用的FIR模块中,并对模块进行验证。
1.matlab产生TXT程序如下:
2.matlab产生COE程序如下:
data_txt=zeros(1,N); data_txt=string(data_txt); for i=1:N data_txt(i) = dec2hex(s(i)); %data_txt{i}=dec2bin(s(i)); %data_txt(i) = s(i) ; end fid=fopen('mix_Data.txt','w'); fprintf(fid,'%s\r\n',data_txt); fclose(fid); fild = fopen("mix_800_200hz_signal.coe","wt"); %写入coe文件头 fprintf(fild,"%s\n","MEMORY_INITIALIZATION_RADIX=10;"); %10进制数 fprintf(fild,"%s\n","MEMORY_INITIALIZATION_VECTOR="); for i = 1:N s0(i) = round(s(i)+2 ^ 11 - 1); %四舍五入取整数 if s0(i)<0 %负数强制变成0,范围在0-255 s0(i) = 0 end if i == N fprintf(fild,"%d",s0(i)); %数据写入 fprintf(fild,"%s",";"); %最后一个数据使用分号 else fprintf(fild,"%d",s0(i)); %数据写入 fprintf(fild,"%s\n",","); %最后一个数据使用分号 end end fclose(fild);
3.Verilog-tb读取TXT程序如下:
initial begin $readmemh("C:/Users/Administrator/Desktop/SORCE/matlab/filter/mix_Data.txt",matlab_signal); addr = 10'd0; end always #320 begin data_out = matlab_signal[addr][11:0] ; addr = addr + 10'd1;
注意点有:
1.TXT必须以16进制来存储,而且每一个数据换一行
2.位置是左竖线而不是右竖线
3.通过控制延时来控制数据的读入
4.数据必须是signed的,也就是有符号类型的数据
文章评论