VHDL FIR滤波器的设计
FIR滤波器的设计 VHDL
-
一.实验目的
-
二.实验内容
-
三.实验设计
-
四.实验步骤
-
五.实验结果
- 一.目的
-
1.学习Quartus II/ISE Design Suite软件的基本使用方法。
2.掌握GW48系列或其他EDA实验开发系统的基本使用方法。
3. 学习VHDL程序设计中LPM兆功能块的程序调用及参数传递方法。
4. 学习数字信号处理算法的分析、设计、编程与调试方法,包括参数的量化、数据的延迟、流水线的使用、仿真数据的输入、仿真结果的分析等。
-
二.内容
-
根据图示的转置FIR滤波器的原理,设计并调试好一个成一个滤波器长度为4的DaubechiesDB4转置FIR滤波器,并用GW48系列或其他EDA实验开发系统进行硬件验证。
图1转置结构的FIR滤波器
三.设计
-
简单介绍:FIR滤波器的全称是Finite Impulse Respond Filter。中文全称是有限脉冲响应滤波器,它也叫做非递归型滤波器。它的作用和所有的滤波器一样,通过算法来使某刻的值处在一个更为准确的值,这句话看着很绕,但是在后面的三种算法的介绍中,应该可以理解我在这里说的这句话的含义。实现数字滤波,就必须要有数字信号,所以这里要通过A/D转换,来使得模拟信号变为数值,才好带入算法中计算,然后用D/A转换,输出模拟信号。
总体设计:设计一个FIR滤波器,编写按键的源程序KG.VHD,动态扫描的源程序CTRLS.VHD,动态计数的源程序DISPLAY.VHD,分频器(CLKGEN)模块,FIR滤波器模块、输入控制(KZSR)模块、输出控制(XSKZQ)模块,由模块构成顶层电路FIR滤波器的源程序TOP.VHD,其中底层和顶层电路均采用VHDL文本输入。
设计思路:
1、FIR滤波器设计:
图2转置结构的FIR滤波器
G(Z)=0.48301+0.8365Z-1+0.2241Z-2-0.1294Z-3
G(Z) =124/256+214Z-1/256+572-2/256-33Z-3/256
Y(n)=124X(n)/256+214X(n-1)/256+57X(n-2)/256-33X(n-3)/256
四.步骤
-
1.分析:设计一个FIR滤波器,编写按键的源程序KG.VHD,动态扫描的源程序CTRLS.VHD,动态计数的源程序DISPLAY.VHD,分频器(CLKGEN)模块,FIR滤波器模块、输入控制(KZSR)模块、输出控制(XSKZQ)模块,由模块构成顶层电路FIR滤波器的源程序TOP.VHD,其中底层和顶层电路均采用VHDL文本输入。
-
2、文件及工程的建立,用VHDL文件编辑好各个模块的源程序,工程编译观察工程是否实现
图5.1 编译程序结果图
3、工程仿真,建立仿真文件,观察仿真结果
对FIR仿真
图5.2 FIR波形仿真图
4、芯片管脚的锁定:
选择硬件相关的芯片EP3C55F484并对程序进行引脚锁定,对应给的常用的引脚锁定图进行锁定。选择好按键和时钟的引脚锁定,其数码管以常用的进行锁定。
图5.4 引脚锁定图
- 逻辑综合结果,查看程序RTL仿真图,熟悉整体电路状态。
-
图5.5 程序RTL视图
- 编程下载及验证,硬件验证功能是否实现
-
图5.6 硬件验证
五 .结果
1、输入端代码分析
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,同理将第二个数字输入进去,则前2个数字为有效数字,后2位为0、0,可以看到输入4个数字之后输入便是数字0,所以输入到第七个时,只有X(n-3)有数字,其他均为0,当第八个输入时,四个输入均为0,则输出为0。只改变仿真波形的输入值,硬件并不会出现任何改变,需要改动代码,硬件才会变化
2.输出端代码分析:
XSKZQ为输出代码控制,由于要分多次在数码管上显示,而又因为输入的数据是多位的
(类比于流水线,只需要把核心的程序设置好了,后面不管来多少产品都可以进行处理)
先将FIR滤波器运算的四位数STD_LOGIC类型的数据通过CONV_INTEGER类型转换成实数,并且将4位数的实数提出每个位数,例如 0200分离出 0、2、0、0 每个位数通过传输到DISPLAY端来驱动数码管是否显示数据。
3.FIR波形仿真分析
图6.5 TESTCL波形仿真图
4.RTL仿真分析
图6.6 程序RTL视图
5.源程序设计
-KG的源程序
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY KG IS
PORT(CLK:IN STD_LOGIC;
K:IN STD_LOGIC;
TIMES:OUT STD_LOGIC);
END ENTITY KG;
ARCHITECTURE ART OF KG IS
BEGIN
PROCESS(CLK,K)IS
BEGIN
IF K='1' THEN
TIMES<=CLK;
ELSE
TIMES<='0';
END IF;
END PROCESS;
END ARCHITECTURE ART;
-- KZSR的源程序
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;
-- XSKZQ的源程序
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_Y:IN STD_LOGIC_VECTOR(10 DOWNTO 0);
ABCD_X:IN STD_LOGIC_VECTOR(8 DOWNTO 0);
G,S,B,Q,C,A,D,F:OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END ENTITY XSKZQ;
ARCHITECTURE ART OF XSKZQ IS
SIGNAL TEMP1,TEMP2,TEMP3,TEMP4,TEMP5,TEMP6,TEMP7,TEMP8:INTEGER RANGE 0 TO 9;
SIGNAL T0,T1,T2,T3,T5,T6,T7,T8:INTEGER RANGE 0 TO 10#9999#;
BEGIN
PROCESS (ABCD_X) IS
BEGIN
T0<=CONV_INTEGER(ABCD_x);
T5<=CONV_INTEGER(ABCD_Y);
T1<=T0-T0/1000*1000;T2<=T1-T1/100*100;T3<=T2-T2/10*10;
TEMP1<=T3;
TEMP2<=(T2-T3)/10;
TEMP3<=(T1-T2)/100;
TEMP4<=(T0-T1)/1000;
T6<=T5-T5/1000*1000;T7<=T6-T6/100*100;T8<=T7-T7/10*10;
TEMP5<=T8;
TEMP6<=(T7-T8)/10;
TEMP7<=(T6-T7)/100;
TEMP8<=(T5-T6)/1000;
CASE TEMP1 IS
WHEN 0 =>G<="0000";
WHEN 1 =>G<="0001";
WHEN 2 =>G<="0010";
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;
……
END PROCESS;
END ARCHITECTURE ART;
-- KG2的源程序
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY KG_2 IS
PORT(CLK:IN STD_LOGIC;
K:IN STD_LOGIC;
X:IN STD_LOGIC_VECTOR(8 DOWNTO 0);
Y:IN STD_LOGIC_VECTOR(10 DOWNTO 0);
X_OUT:OUT STD_LOGIC_VECTOR(8 DOWNTO 0);
Y_OUT:OUT STD_LOGIC_VECTOR(10 DOWNTO 0));
END ENTITY KG_2;
ARCHITECTURE ART OF KG_2 IS
BEGIN
PROCESS(CLK,K)IS
BEGIN
IF K='1' THEN
X_OUT<=X;
ELSE
Y_OUT<=Y;
END IF;
END PROCESS;
END ARCHITECTURE ART;
-- FIR的源程序
--FIR.VHD
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;
-- TOP的源程序
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
--USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY TOP IS
PORT(CLK,CLK2,K1,K2:IN STD_LOGIC;
COM:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
SEG:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END ENTITY TOP;
ARCHITECTURE ART OF TOP IS
COMPONENT CLKGEN IS
PORT(CLK: IN STD_LOGIC;
NEWCLK: OUT STD_LOGIC);
END COMPONENT CLKGEN;
COMPONENT CTRLS IS
PORT(CLK:IN STD_LOGIC;
SEL:OUT STD_LOGIC_VECTOR(2 DOWNTO 0));
END COMPONENT CTRLS;
COMPONENT DISPLAY IS
PORT(SEL:IN STD_LOGIC_VECTOR(2 DOWNTO 0);
G,S,B,Q,C,A,D,F:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
COM:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
SEG:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END COMPONENT DISPLAY;
COMPONENT KG IS
PORT(CLK:IN STD_LOGIC;
K:IN STD_LOGIC;
TIMES:OUT STD_LOGIC);
END COMPONENT KG;
COMPONENT XSKZQ IS
PORT (ABCD_X:IN STD_LOGIC_VECTOR(8 DOWNTO 0);
ABCD_Y:IN STD_LOGIC_VECTOR(10 DOWNTO 0);
G,S,B,Q,C,A,D,F:OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END COMPONENT XSKZQ;
COMPONENT 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 COMPONENT KZSR;
COMPONENT FIR IS
PORT(CLK:IN STD_LOGIC;
LOAD_X:IN STD_LOGIC;
X_IN:IN STD_LOGIC_VECTOR(8 DOWNTO 0);
C_IN:IN STD_LOGIC_VECTOR(8 DOWNTO 0);
Y_OUT:OUT STD_LOGIC_VECTOR(10 DOWNTO 0));
END COMPONENT FIR;
SIGNAL S1,S2,S4:STD_LOGIC;
SIGNAL S3,S5:STD_LOGIC_VECTOR(8 DOWNTO 0);
SIGNAL S6:STD_LOGIC_VECTOR(10 DOWNTO 0);
SIGNAL G1,B1,S_1,Q1,C1,A1,D1,F1:STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL SEL_1:STD_LOGIC_VECTOR(2 DOWNTO 0);
BEGIN
U1:KG PORT MAP(CLK=>CLK,K=>K1,TIMES=>S1);
U2:CLKGEN PORT MAP(CLK=>S1,NEWCLK=>S2);
U3:KZSR PORT MAP(CLK=>S2,XOUT=>S3,LOAD=>S4,COUT=>S5);
U4:FIR PORT MAP(CLK=>S2,LOAD_X=>S4,X_IN=>S3,C_IN=>S5,Y_OUT=>S6);
U7:XSKZQ PORT MAP(ABCD_X=>S3,ABCD_Y=>S6,G=>G1,S=>S_1,B=>B1,Q=>Q1,C=>C1,A=>A1,D=>D1,F=>F1);
U8:CTRLS PORT MAP(CLK=>CLK2,SEL=>SEL_1);
U9:DISPLAY PORT MAP(SEL=>SEL_1,G=>G1,S=>S_1,B=>B1,Q=>Q1,C=>C1,A=>A1,D=>D1,F=>F1,COM=>COM,SEG=>SEG);
END ARCHITECTURE ART;
更多推荐
所有评论(0)