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