赞
踩
目录
“FIR(Finite Impulse Response)滤波器:有限长单位冲激响应滤波器,又称为非递归型滤波器,是数字信号处理系统中最基本的元件,它可以在保证任意幅频特性的同时具有严格的线性相频特性,同时其单位抽样响应是有限长的,因而滤波器是稳定的系统。因此,FIR滤波器在通信、图像处理、模式识别等领域都有着广泛的应用。”
根据转置FIR 滤波器的原理,设计并调试一个滤波器长度为4的 DaubechiesDB4转置FIR滤波器,该滤波器的系数为G(Z)=0.48301+0.8365Z-1 +0.2241Z-2-0.1294Z-3。若将系数变换成8位(加上符号位)精度模式,则G(Z)=124/256+214Z-1/256+57Z-2/256-33Z-3/256
因此Y(n)=124 X(n)/256+214X(n-1)/256+57X(n-2)/256-33X(n-3)/256。并用GW48系列或其他EDA实验开发系统(事先应选定拟采用的实验芯片的型号)进行硬件验证。
图2.1 顶层电路图
整体思路分析:
首先是疑问:便是信号由什么产生? 如何传输让 FIR滤波器进行运算?当滤波器运算结果通过什么模块能够在数码管上显示?
那么来根据疑问来设计模块:为了能够控制整个程序是否运行,加入了按键控制模块。
为了驱动整个程序运行需要时钟的输入,可以由外部时钟或者内部时钟,这里我选择的外部时钟,要能够让人能够看见变化,需要对外部时钟进行分频,于是加入了分配器模块
为了能够测量多个数据,需要加入输入控制模块
为了能够将滤波器多次运算的结果分批次显示到数码管上需要添加输出控制模块
要在数码管上显示其中动态显示和动态扫描是缺少不了的,可以想象这个程序就是一个工厂的流水线工程流水线是源源不断的通过传输带传输产品,然后通过一系列加工然后输出,发货到全国各地
由整体电路图可以看出需要按键控制(KG)模块、分频器(CLKGEN)模块。动态扫描(CTRLS)模块、动态显示(DISPLAY)模块、FIR滤波器模块、输入控制(KZSR)模块、输出控制(XSKZQ)模块共七个模块。常用模块可以移植
- --前端控制
- LIBRARY IEEE;
- USE IEEE.STD_LOGIC_1164.ALL;
- USE IEEE.STD_LOGIC_UNSIGNED.ALL;
- --USE IEEE.STD_LOGIC_ARITH.ALL;
- ENTITY KZSR IS
- PORT(CLK:IN STD_LOGIC;
- XOUT:OUT STD_LOGIC_VECTOR(8 DOWNTO 0);
- LOAD:OUT STD_LOGIC;
- COUT:OUT STD_LOGIC_VECTOR(8 DOWNTO 0));
- END ENTITY KZSR;
- ARCHITECTURE ART OF KZSR IS
- SIGNAL SEL:STD_LOGIC_VECTOR(3 DOWNTO 0);
- SIGNAL A:STD_LOGIC_VECTOR(3 DOWNTO 0);
- BEGIN
- PROCESS(SEL,CLK)
- BEGIN
- IF CLK'EVENT AND CLK='0' THEN
- SEL<=SEL+'1';
- ELSE
- NULL;
- END IF;
- IF CLK'EVENT AND CLK='0' THEN
- A<=A+'1';
- ELSE NULL;
- END IF;
- CASE A IS
- WHEN "0000"=>LOAD<='0';
- WHEN "0001"=>LOAD<='0';
- WHEN "0010"=>LOAD<='0';
- WHEN "0011"=>LOAD<='0';
- WHEN OTHERS=>LOAD<='1';
- END CASE;
- CASE SEL IS
- WHEN "0000"=>COUT<="001111100";XOUT<="000000000";
- WHEN "0001"=>COUT<="011010110";XOUT<="000000000";
- WHEN "0010"=>COUT<="000111001";XOUT<="000000000";
- WHEN "0011"=>COUT<="111011111";XOUT<="000000000";
- WHEN "0100"=>XOUT<="001100100";COUT<="000000000";
- WHEN "0101"=>XOUT<="010010110";COUT<="000000000";
- WHEN "0110"=>XOUT<="011001000";COUT<="000000000";
- WHEN "0111"=>XOUT<="011111010";COUT<="000000000";
- WHEN OTHERS=>XOUT<="000000000";COUT<="000000000";
- END CASE;
- END PROCESS;
- END ARCHITECTURE ART;
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- --后端控制
- LIBRARY IEEE;
- USE IEEE.STD_LOGIC_1164.ALL;
- USE IEEE.STD_LOGIC_UNSIGNED.ALL;
- USE IEEE.STD_LOGIC_ARITH.ALL;
- ENTITY XSKZQ IS
- PORT (ABCD:IN STD_LOGIC_VECTOR(10 DOWNTO 0); --是FIR运算的位宽
- G,S,B,Q:OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); --分离出四位的每一位数字 ,可以理解为拆分器
- END ENTITY XSKZQ;
- ARCHITECTURE ART OF XSKZQ IS
- SIGNAL TEMP1,TEMP2,TEMP3,TEMP4:INTEGER RANGE 0 TO 9; --相对于最大四位数,每个位数的数值
- SIGNAL T0,T1,T2,T3:INTEGER RANGE 0 TO 10#9999#; --这个四个数据的结果
- BEGIN
- PROCESS (ABCD) IS
- BEGIN
- T0<=CONV_INTEGER(ABCD);T1<=T0-T0/1000*1000;T2<=T1-T1/100*100;T3<=T2-T2/10*10;--CONV是转换函数
- TEMP1<=T3; --这个才是提出每一个数据
- TEMP2<=(T2-T3)/10;
- TEMP3<=(T1-T2)/100;
- TEMP4<=(T0-T1)/1000;
- CASE TEMP1 IS
- WHEN 0 =>G<="0000";
- WHEN 1 =>G<="0001";
- WHEN 2 =>G<="0010"; --后面代码对于DISPLAY里面的数字
- WHEN 3 =>G<="0011";
- WHEN 4 =>G<="0100";
- WHEN 5 =>G<="0101";
- WHEN 6 =>G<="0110";
- WHEN 7 =>G<="0111";
- WHEN 8 =>G<="1000";
- WHEN 9 =>G<="1001";
- WHEN OTHERS=>G<="0000";
- END CASE;
- CASE TEMP2 IS
- WHEN 0 =>S<="0000";
- WHEN 1 =>S<="0001";
- WHEN 2 =>S<="0010";
- WHEN 3 =>S<="0011";
- WHEN 4 =>S<="0100";
- WHEN 5 =>S<="0101";
- WHEN 6 =>S<="0110";
- WHEN 7 =>S<="0111";
- WHEN 8 =>S<="1000";
- WHEN 9 =>S<="1001";
- WHEN OTHERS=>S<="0000";
- END CASE;
- CASE TEMP3 IS
- WHEN 0 =>B<="0000" ;
- WHEN 1 =>B<="0001";
- WHEN 2 =>B<="0010";
- WHEN 3 =>B<="0011";
- WHEN 4 =>B<="0100";
- WHEN 5 =>B<="0101";
- WHEN 6 =>B<="0110";
- WHEN 7 =>B<="0111";
- WHEN 8 =>B<="1000";
- WHEN 9 =>B<="1001";
- WHEN OTHERS=>B<="0000";
- END CASE;
- CASE TEMP4 IS
- WHEN 0 =>Q<="0000" ;
- WHEN 1 =>Q<="0001";
- WHEN 2 =>Q<="0010";
- WHEN 3 =>Q<="0011";
- WHEN 4 =>Q<="0100";
- WHEN 5 =>Q<="0101";
- WHEN 6 =>Q<="0110";
- WHEN 7 =>Q<="0111";
- WHEN 8 =>Q<="1000";
- WHEN 9 =>Q<="1001";
- WHEN OTHERS=>Q<="0000";
- END CASE;
- END PROCESS;
- END ARCHITECTURE ART;
-
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- --FIR.VHD 8号口动态扫描 ,6号口为外部时钟3M
- LIBRARY LPM;
- USE LPM.LPM_COMPONENTS.ALL;
- LIBRARY IEEE;
- USE IEEE.STD_LOGIC_1164.ALL;
- USE IEEE.STD_LOGIC_ARITH.ALL;
- USE IEEE.STD_LOGIC_UNSIGNED.ALL;
- ENTITY FIR IS
- GENERIC(W1:INTEGER:=9;
- W2:INTEGER:=18;
- W3:INTEGER:=19;
- W4:INTEGER:=11;
- L:INTEGER:=4;
- MPIPE:INTEGER:=3);
- PORT(CLK:IN STD_LOGIC;
- LOAD_X:IN STD_LOGIC;
- X_IN:IN STD_LOGIC_VECTOR(W1-1 DOWNTO 0);
- C_IN:IN STD_LOGIC_VECTOR(W1-1 DOWNTO 0);
- Y_OUT:OUT STD_LOGIC_VECTOR(W4-1 DOWNTO 0));
- END ENTITY FIR;
- ARCHITECTURE ART OF FIR IS
- SUBTYPE N1BIT IS STD_LOGIC_VECTOR(W1-1 DOWNTO 0);
- SUBTYPE N2BIT IS STD_LOGIC_VECTOR(W2-1 DOWNTO 0);
- SUBTYPE N3BIT IS STD_LOGIC_VECTOR(W3-1 DOWNTO 0);
- TYPE ARRAY_N1BIT IS ARRAY(0 TO L-1) OF N1BIT;
- TYPE ARRAY_N2BIT IS ARRAY(0 TO L-1) OF N2BIT;
- TYPE ARRAY_N3BIT IS ARRAY(0 TO L-1) OF N3BIT;
- SIGNAL X:N1BIT;
- SIGNAL Y:N3BIT;
- SIGNAL C:ARRAY_N1BIT;
- SIGNAL P:ARRAY_N2BIT;
- SIGNAL A:ARRAY_N3BIT;
- BEGIN
- LOAD:PROCESS IS
- BEGIN
- WAIT UNTIL CLK='1';
- IF (LOAD_X='0')THEN
- C(L-1)<=C_IN;
- FOR I IN L-2 DOWNTO 0 LOOP
- C(I)<=C(I+1);
- END LOOP;
- ELSE
- X<=X_IN; --获得一个采样运算
- END IF;
- END PROCESS LOAD;
- SOP:PROCESS(CLK)IS --乘加运算
- BEGIN
- IF CLK'EVENT AND(CLK='1')THEN
- FOR I IN 0 TO L-2 LOOP --计算加法
- A(I)<=(P(I)(W2-1)&P(I))+A(I+1);
- END LOOP;
- A(L-1)<=P(L-1)(W2-1)&P(L-1);
- END IF;
- Y<=A(0);
- END PROCESS SOP;
- MULGEN:FOR I IN 0 TO L-1 GENERATE
- MULS:LPM_MULT --乘法运算
- GENERIC MAP(LPM_WIDTHA=>W1,LPM_WIDTHB=>W1,
- LPM_PIPELINE=>MPIPE,
- LPM_REPRESENTATION=>"SIGNED",
- LPM_WIDTHP=>W2,
- LPM_WIDTHS=>W2)
- PORT MAP(CLOCK=>CLK,DATAA=>X,
- DATAB=>C(I),RESULT=>P(I));
- END GENERATE;
- Y_OUT<=Y(W3-1 DOWNTO W3-W4);
- END ARCHITECTURE ART;
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
CLK是通过分配器获得的1hz的时钟,COUT是FIR滤波器系数,XOUT是输入数字。LOAD是控制FIR滤波器是否工作。当下降沿到来的时候,A和SEL进行加1操作,A决定LOAD的数值,LOAD决定FIR滤波器是否工作,SEL控制传输的数据,当LOAD=0的时候FIR滤波器开始工作。
首先需要将FIR滤波器的系数输入,COUT<=001111100化为二进制就是滤波器的第一个系数:124
后面依次类推即可,把FIR滤波器的4位系数(FIR滤波器的系数是固定死的)输入完成后便输入运算的数值。如果要调整运算的数字的个数,可以通过只改变波形中X—IN的值即可。
当LOAD为低电平时,将滤波器的系数输入,当LOAD为高电平时,将需要计算的数值输入进去,例如输入的X(1)为100则X(n)为100,X(n-1),X(n-2),,X(n-3)都为0,待人方程可得48,同理将第二个数字输入进去,则前俩个数字为有效数字,后俩位为0、
可以看到输入4个数字之后输入便是数字0,所以输入到第七个时,只有X(n-3)有数字,其他均为0,当第八个输入时,四个输入均为0,则输出为0。
(只改变仿真波形的输入值,硬件并不会出现任何改变,需要改动代码,硬件才会变化)
XSKZQ为输出代码控制,由于要分多次在数码管上显示,而又因为输入的数据是多位的
(类比于流水线,只需要把核心的程序设置好了,后面不管来多少产品都可以进行处理)
先将FIR滤波器运算的四位数STD_LOGIC类型的数据通过CONV_INTEGER类型转换成实数,并且将4位数的实数提出每个位数,例如 0150 分离出 0、1、5、0 每个位数通过传输到DISPLAY端来驱动数码管是否显示数据。
图6.1 硬件锁定图
由于要显示到数码管所以要配置引脚,其中选择产生时钟的由外部时钟产生,配置为六号口为时钟空,与3M频率的接口相连,通过分频器产生1S的时钟周期信号,CLK2为动态扫描端口,配置为8号端口。配置按键为8号按键。
要注意一点RTL图和原理图含义是不一样的。
图6.2 整体RTL图
大家还会遇到一些其他问题可以在底下提出,大家互相交流学习。
(如果需要源代码,后面我会进行开源)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。