📄 fir-40ntap-4order.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 + -