VHDL FIR滤波器的设计

  • 一.实验目的

  • 二.实验内容

  • 三.实验设计

  • 四.实验步骤

  • 五.实验结果

  • 一.目的
  • 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文本输入。

    设计思路:

    1FIR滤波器设计:

    图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;

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值