FIR滤波器的设计

FIR(Finite Impulse Response)滤波器:有限长单位冲激响应滤波器,又称为非递归型滤波器,是数字信号处理系统中最基本的元件,它可以在保证任意幅频特性的同时具有严格的线性相频特性,同时其单位抽样响应是有限长的,因而滤波器是稳定的系统。因此,FIR滤波器在通信、图像处理、模式识别等领域都有着广泛的应用。

该滤波器的系数为G(Z)=0.48301+0.8365Z +0.2241Z2-0.1294Z-3。若将系数变换成8位(加上符号位)精度模G(Z)=124/256+2147/256+57Z--/256-33Z-3/256,因此Y(n)=124 X(n)/256+214X(n-1)/256+57X(n-2)/256-33X(n-3)/256。

顶层程序

--DTFIB.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 DTFIR IS
  PORT(K:IN STD_LOGIC;
       CLK:IN STD_LOGIC;
		 CLK2:IN STD_LOGIC;
		 COM:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
		 SEG:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END ENTITY DTFIR;

ARCHITECTURE ART OF DTFIR IS
  COMPONENT KG IS
    PORT(CLK:IN STD_LOGIC;
         K:IN STD_LOGIC;
		   TIMES:OUT STD_LOGIC);
    END COMPONENT KG;
  COMPONENT CLKGEN IS
    PORT(CLK: IN STD_LOGIC;
         NEWCLK: OUT STD_LOGIC);
	  
    END COMPONENT CLKGEN;	 
  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
    GENERIC(W1:INTEGER:=9;
			   W2:INTEGER:=18;
			   W3:INTEGER:=19;
			   W4:INTEGER:=11;
			   L:INTEGER:=4;
			   MPIPE:INTEGER:=3);
    PORT(CLK,LOAD_X:IN STD_LOGIC;
		   X_IN,C_IN:IN STD_LOGIC_VECTOR(W1-1 DOWNTO 0);
		   Y_OUT:OUT STD_LOGIC_VECTOR(W4-1 DOWNTO 0));  
    END COMPONENT FIR;
	 
  COMPONENT XSKZQ IS
      PORT (ABCD:IN STD_LOGIC_VECTOR(10 DOWNTO 0);
            G,S,B,Q:OUT STD_LOGIC_VECTOR(3 DOWNTO 0));  
     END COMPONENT XSKZQ;
	 
  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: 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;
  SIGNAL CK:STD_LOGIC; 
  SIGNAL S0,S1,S2:STD_LOGIC; 
  SIGNAL SD:STD_LOGIC_VECTOR(8 DOWNTO 0);
  SIGNAL SL:STD_LOGIC_VECTOR(8 DOWNTO 0);
  SIGNAL SM:STD_LOGIC_VECTOR(10 DOWNTO 0);
  SIGNAL G,S,B,Q:STD_LOGIC_VECTOR(3 DOWNTO 0);
  SIGNAL SE:STD_LOGIC_VECTOR(2 DOWNTO 0);
  BEGIN
  U0: KG PORT MAP(CLK=>CLK,K=>K,TIMES=>S0);
  U1: CLKGEN PORT MAP(S0,CK);
  U2: KZSR PORT MAP(CK,SD,S1,SL);
  U3: FIR PORT MAP(CK,S1,SD,SL,SM); 
  U4: XSKZQ PORT MAP(SM,G,S,B,Q);
  U5: CTRLS PORT MAP(CLK2,SE);
  U6: DISPLAY PORT MAP(SE,G,S,B,Q,COM,SEG);
  
  END ARCHITECTURE ART;

--XSKZQ.VHD后端控制的源程序

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;

--KZSR.VHD前端控制的源程序

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;

 display源程序

--DISPLAY.VHD
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY DISPLAY IS  
  PORT(SEL: IN STD_LOGIC_VECTOR(2 DOWNTO 0);
       DATAIN: IN STD_LOGIC_VECTOR(15 DOWNTO 0);
       COM: OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
       SEG: OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
		 G,S,B,Q:STD_LOGIC_VECTOR(3 DOWNTO 0));
END ENTITY DISPLAY;
ARCHITECTURE ART OF DISPLAY IS
  SIGNAL DATA:STD_LOGIC_VECTOR(3 DOWNTO 0);
  BEGIN  
  PROCESS(SEL) IS
    BEGIN
    CASE SEL IS
	   WHEN "000" => COM<="11111110";
	   WHEN "001" => COM<="11111101";
	   WHEN "010" => COM<="11111011";
	   WHEN "011" => COM<="11110111";
	   WHEN "100" => COM<="11101111";
	   WHEN "101" => COM<="11011111";
	   WHEN "110" => COM<="10111111";
    	WHEN "111" => COM<="01111111";
	   WHEN OTHERS => COM<="11111111";
    END CASE ;
  END PROCESS;
  PROCESS(SEL) IS
	 BEGIN
	 CASE SEL IS
		WHEN "000" =>DATA<=G;
	   WHEN "001" =>DATA<=S;
		WHEN "010" =>DATA<=B;
		WHEN "011" =>DATA<=Q;
		WHEN OTHERS=>DATA<="0000";
	 END CASE;
       CASE DATA IS
		WHEN "0000" => SEG<="00111111";--3FH
		WHEN "0001" => SEG<="00000110";--06H
		WHEN "0010" => SEG<="01011011";--5BH
		WHEN "0011" => SEG<="01001111";--4FH
		WHEN "0100" => SEG<="01100110";--66H
		WHEN "0101" => SEG<="01101101";--6DH
	   WHEN "0110" => SEG<="01111101";--7DH
		WHEN "0111" => SEG<="00000111";--07H
		WHEN "1000" => SEG<="01111111";--7FH
		WHEN "1001" => SEG<="01101111";--6FH
		WHEN OTHERS => SEG<="00000000";--00H
	 END CASE ;
  END PROCESS;
END ARCHITECTURE ART;

--CTRLS.VHD

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CTRLS IS
  PORT(CLK: IN STD_LOGIC;      
  SEL: OUT STD_LOGIC_VECTOR(2 DOWNTO 0));
END ENTITY CTRLS;
ARCHITECTURE ART OF CTRLS IS
  SIGNAL CNT: STD_LOGIC_VECTOR(2 DOWNTO 0);
  BEGIN
  PROCESS(CLK) IS
    BEGIN
    IF CLK'EVENT AND CLK='1' THEN
      IF CNT="111" THEN 
         CNT<="000";
       ELSE 
         CNT<=CNT+'1';
      END IF ;
   END IF;
  END PROCESS;
  SEL<=CNT;
END ARCHITECTURE ART;
--CLKGEN.VHD(分频器)
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY CLKGEN IS
  PORT(CLK:IN STD_LOGIC;--3 MHz 信号输入
       NEWCLK: OUT STD_LOGIC); --100Hz计时时钟信号输出
END ENTITY CLKGEN;
ARCHITECTURE ART OF CLKGEN IS
  --SIGNAL CNT:INTEGER RANGE 0 TO 10#29999#;--十进制计数预制数
  SIGNAL CNT:INTEGER RANGE 0 TO 10#29#;
  BEGIN
  PROCESS(CLK) IS --分频计数器,由3MHz时钟产生100 Hz信号
    BEGIN
    IF CLK'EVENT AND CLK='1'THEN
      --IF CNT=10#29999# THEN CNT<=0; --分频常数为 30 000
		IF CNT=10#29# THEN CNT<=0;
		ELSE CNT<=CNT+1;
      END IF;
    END IF;
  END PROCESS;
  PROCESS(CNT) IS --计数溢出信号控制
    BEGIN
    --IF CNT=10#29999# THEN NEWCLK<='1';
	 IF CNT=10#29# THEN NEWCLK<='1';
    ELSE NEWCLK<='0';
    END IF;
  END PROCESS;
END ARCHITECTURE ART;
--GK.VHD(按键控制)
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;

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

 

仿真结果

                                                         RTL视图

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值