⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fir-40ntap-4order.vhd

📁 Fir filter with 40tap, 4 order
💻 VHD
字号:
----------------------------------------------------------------
-- WinFilter version 0.8
-- http://www.winfilter.20m.com
-- akundert@hotmail.com
--
-- FIR 40 Taps
-- Coefficents Quantization: 16-bit
-- Filter type: Band Pass
-- Filter model: Butterworth
-- Filter order: 4
-- Sampling Frequency: 8 KHz
-- Fc1 and Fc2 Frequencies: 0.300000 KHz and 3.800000 KHz
--
-- Z domain Zeros
-- z = -1.000000 + j 0.000000
-- z = -1.000000 + j 0.000000
-- z = -1.000000 + j 0.000000
-- z = -1.000000 + j 0.000000
-- z = 1.000000 + j 0.000000
-- z = 1.000000 + j 0.000000
-- z = 1.000000 + j 0.000000
-- z = 1.000000 + j 0.000000
--
-- Z domain Poles
-- z = -0.861194 + j -0.053930
-- z = -0.861194 + j 0.053930
-- z = 0.797313 + j -0.075703
-- z = 0.797313 + j 0.075703
-- z = -0.932541 + j -0.137193
-- z = -0.932541 + j 0.137193
-- z = 0.893473 + j -0.199254
-- z = 0.893473 + j 0.199254
--
-- Signal Resolution: 16-bit
-- Coefficients Quantization: 16-bit
-- 1 multiplier(s)
-- 814 FFs for the filter*
-- 656 FFs for the coefficients*
-- 41 clks output latency
-- 328000 Hz for Fclk
-- 8000 Hz for Fsampling
-- * May change with synthezis optimization
------------------------------------------------------------------------------------------------------------------------

------------------------------------------------------------------------------------------------------------------------
--  Component multiplier
--  signed multiplier
------------------------------------------------------------------------------------------------------------------------

library IEEE;
    use IEEE.std_logic_1164.all;
    use IEEE.std_logic_arith.all;

entity multiplier is
    Port (
        GLOBAL_CLK     : in std_logic;
        GLOBAL_RESET   : in std_logic;
        A              : in std_logic_vector;
        B              : in std_logic_vector;
        Q              : out std_logic_vector
    );
end multiplier;

architecture rtl of multiplier is

signal A_tmp : signed( A'length-1 downto 0 );
signal B_tmp : signed( B'length-1 downto 0 );
signal prod_tmp : signed( Q'length-1 downto 0 );

begin

assert Q'length = (A'length + B'length)
    report "multiplier: Q length must equal A + B length" severity error;

-- A to signed value conversion
A_pro : process(A)
begin
    for i in A'length-1 downto 0 loop
        A_tmp(i) <= A(i);
    end loop;
end process A_pro;

-- B to signed value conversion
B_pro : process( B )
begin

    for i in B'length-1 downto 0 loop
        B_tmp(i) <= B(i);
    end loop;
end process B_pro;

-- multiplication
prod_tmp <= A_tmp * B_tmp;

-- Registered output
prod_pro : process(GLOBAL_CLK, GLOBAL_RESET) begin
    if (GLOBAL_RESET = '1') then
       for i in Q'length-1 downto 0 loop
           Q(i) <= '0';
       end loop;
    elsif rising_edge(GLOBAL_CLK) then
       for i in Q'length-1 downto 0 loop
           Q(i) <= prod_tmp(i);
       end loop;
    end if;
end process prod_pro;

end rtl;

------------------------------------------------------------------------------------------------------------------------
--  Component fir
--  Filter Top Level
------------------------------------------------------------------------------------------------------------------------

library IEEE;
    use IEEE.std_logic_1164.all;
    use IEEE.std_logic_arith.all;
    use IEEE.std_logic_unsigned.all;

entity fir is
    generic (
       Coef_Width_g    : integer := 16;
       NTAP_g          : integer := 40
    );
    port (
       GLOBAL_CLK      : in std_logic;
       GLOBAL_RESET    : in std_logic;
       X_IN            : in std_logic_vector;
       NEW_SAMPLE      : out std_logic;
       SATURATION_ERR  : out std_logic;
       Y_OUT           : out std_logic_vector
	);
end fir;

architecture size of fir is

component multiplier is
    Port (
        GLOBAL_CLK     : in std_logic;
        GLOBAL_RESET   : in std_logic;
        A              : in std_logic_vector;
        B              : in std_logic_vector;
        Q              : out std_logic_vector
    );
end component;

constant CoefScalingBitDrop_c : integer := 15;

type DELAYARRAY is array (0 to NTAP_g - 1) of std_logic_vector(X_IN'length-1 downto 0);
signal DELAY    : DELAYARRAY;

type ROMARRAY is array (0 to NTAP_g) of std_logic_vector(Coef_Width_g-1 downto 0);
signal ROMDATA : ROMARRAY;
signal ROMARRAY_Mux : std_logic_vector(Coef_Width_g-1 downto 0);

signal PROD_i : std_logic_vector(X_IN'length+Coef_Width_g-1 downto 0);
signal PROD, Y_I : std_logic_vector(X_IN'length+Coef_Width_g+NTAP_g-1 - 1 downto 0);
signal TAP_Counter : integer range 0 to NTAP_g;
constant ShiftCount_c : integer := 1;

signal X_IN_reg : std_logic_vector(X_IN'length-1 downto 0);

constant zeros : std_logic_vector(Y_I'length-1 downto 0) := (others => '0');
constant ones  : std_logic_vector(Y_I'length-1 downto 0) := (others => '1');

begin

assert Y_OUT'length = X_IN'length
	report "fir: Y_OUT and X_IN must be the same length" severity error;

ROMDATA(0) <= x"01b9";
ROMDATA(1) <= x"ff91";
ROMDATA(2) <= x"01fd";
ROMDATA(3) <= x"fe74";
ROMDATA(4) <= x"0201";
ROMDATA(5) <= x"fced";
ROMDATA(6) <= x"01b9";
ROMDATA(7) <= x"fb03";
ROMDATA(8) <= x"0120";
ROMDATA(9) <= x"f8ce";
ROMDATA(10) <= x"0044";
ROMDATA(11) <= x"f67b";
ROMDATA(12) <= x"ff43";
ROMDATA(13) <= x"f443";
ROMDATA(14) <= x"fe44";
ROMDATA(15) <= x"f26a";
ROMDATA(16) <= x"fd76";
ROMDATA(17) <= x"f12f";
ROMDATA(18) <= x"fd03";
ROMDATA(19) <= x"7b0d";
ROMDATA(20) <= x"fd03";
ROMDATA(21) <= x"f12f";
ROMDATA(22) <= x"fd76";
ROMDATA(23) <= x"f26a";
ROMDATA(24) <= x"fe44";
ROMDATA(25) <= x"f443";
ROMDATA(26) <= x"ff43";
ROMDATA(27) <= x"f67b";
ROMDATA(28) <= x"0044";
ROMDATA(29) <= x"f8ce";
ROMDATA(30) <= x"0120";
ROMDATA(31) <= x"fb03";
ROMDATA(32) <= x"01b9";
ROMDATA(33) <= x"fced";
ROMDATA(34) <= x"0201";
ROMDATA(35) <= x"fe74";
ROMDATA(36) <= x"01fd";
ROMDATA(37) <= x"ff91";
ROMDATA(38) <= x"01b9";
ROMDATA(39) <= x"004a";
ROMDATA(40) <= x"0000"; --dummy

-- IOs registers
process(GLOBAL_CLK, GLOBAL_RESET) begin
     if (GLOBAL_RESET = '1') then
        X_IN_reg        <= (others => '0');
        NEW_SAMPLE      <= '0';
        SATURATION_ERR  <= '0';
        Y_OUT           <= conv_std_logic_vector(0, Y_OUT'length);
     elsif rising_edge(GLOBAL_CLK) then
        X_IN_reg        <= X_IN;
        if TAP_Counter = ShiftCount_c then
            --update Y output
            NEW_SAMPLE		 <= '1';
        if Y_I( Y_I'length-1 downto CoefScalingBitDrop_c + Y_OUT'length - 1) = zeros(Y_I'length-1 - (CoefScalingBitDrop_c + Y_OUT'length - 1) downto 0)
        or Y_I( Y_I'length-1 downto CoefScalingBitDrop_c + Y_OUT'length - 1) =  ones(Y_I'length-1 - (CoefScalingBitDrop_c + Y_OUT'length - 1) downto 0) then
             SATURATION_ERR     <= '0';
             Y_OUT              <= Y_I(CoefScalingBitDrop_c + Y_OUT'length-1 downto CoefScalingBitDrop_c);
        else
            SATURATION_ERR     <= '1';
            if Y_I(Y_I'length-1) = '0' then
                --positive saturation
                Y_OUT    <= '0' & ones(Y_OUT'length-2 downto 0);
            else
                --negative saturation
                Y_OUT    <= '1' & zeros(Y_OUT'length-2 downto 0);
            end if;
         end if;
        else
            NEW_SAMPLE		 <= '0';
        end if;
    end if;
end process;

-- TAP_Counter process
process(GLOBAL_CLK, GLOBAL_RESET) begin
   if (GLOBAL_RESET = '1') then
       ROMARRAY_Mux <= (others => '0');
       TAP_Counter	<= 0;
   elsif rising_edge(GLOBAL_CLK) then
       ROMARRAY_Mux <= ROMDATA(TAP_Counter);
       if TAP_Counter	= NTAP_g then
           TAP_Counter <= 0;
       else
           TAP_Counter <= 	TAP_Counter + 1;
       end if;
    end if;
end process;

-- right shift registers
process(GLOBAL_CLK, GLOBAL_RESET) begin
     if (GLOBAL_RESET = '1') then
        for i in 0 to NTAP_g-1 loop
            DELAY(i) <= (others => '0');
        end loop;
     elsif rising_edge(GLOBAL_CLK) then
        for i in 1 to NTAP_g-1 loop
            DELAY(i) <= DELAY(i-1);
        end loop;
       if TAP_Counter = ShiftCount_c then
           DELAY(0)    <= X_IN_reg;
       else
           DELAY(0)    <= DELAY(NTAP_g-1);
       end if;

    end if;
end process;

-- multiplier instantiation
mult_inst : multiplier
port map(
	GLOBAL_CLK	=> GLOBAL_CLK,
	GLOBAL_RESET=> GLOBAL_RESET,
	A 			=> ROMARRAY_Mux,
	B 			=> DELAY(NTAP_g-2),
	Q			=> PROD_i
);

--sign extension
sign_ext_p : process(PROD_i) begin
	for i in 0 to PROD_i'length-1 loop
		PROD(i) <= PROD_i(i);
	end loop;
	for i in PROD_i'length to PROD'length-1 loop
		PROD(i) <= PROD_i(PROD_i'length-1);
	end loop;
end process sign_ext_p;

-- summation
process(GLOBAL_CLK, GLOBAL_RESET) begin
   if (GLOBAL_RESET = '1') then
       Y_I             <= (others => '0');
   elsif rising_edge(GLOBAL_CLK) then
       if TAP_Counter	= ShiftCount_c then
           Y_I             <= (others => '0');
       else
           Y_I             <=   (Y_I(Y_I'length-1) & Y_I(Y_I'length-2 downto 0) )
                            + (PROD(PROD'length-1) & PROD(PROD'length-2 downto 0) );
       end if;
   end if;
end process;

end size;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -