Сообщение от
Кокон
Ага и до проекта это дойтет
удачи
про спартан 3 и adsp21261 поверю
Мало того - можно даже дома сделать
Offтопик:
Это C
/**************************************************************
Filter type: Low Pass
Filter model: Butterworth
Filter order: 10
Sampling Frequency: 44 KHz
Cut Frequency: 20.000000 KHz
Coefficents Quantization: 16-bit
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 = -1.000000 + j 0.000000
z = -1.000000 + j 0.000000
Z domain Poles
z = -0.799984 + j -0.166318
z = -0.799984 + j 0.166318
z = -0.766873 + j -0.101934
z = -0.766873 + j 0.101934
z = -0.850768 + j -0.222547
z = -0.850768 + j 0.222547
z = -0.750758 + j -0.034564
z = -0.750758 + j 0.034564
z = -0.918982 + j -0.266509
z = -0.918982 + j 0.266509
***************************************************************/
#define Ntap 50
#define DCgain 32768
__int16 fir(__int16 NewSample) {
__int16 FIRCoef[Ntap] = {
-57,
-28,
124,
-224,
321,
-407,
473,
-511,
513,
-473,
387,
-251,
68,
160,
-429,
728,
-1048,
1375,
-1697,
2000,
-2269,
2493,
-2661,
2765,
29936,
2765,
-2661,
2493,
-2269,
2000,
-1697,
1375,
-1048,
728,
-429,
160,
68,
-251,
387,
-473,
513,
-511,
473,
-407,
321,
-224,
124,
-28,
-57,
128
};
static __int16 x[Ntap]; //input samples
__int32 y=0; //output sample
int n;
//shift the old samples
for(n=Ntap-1; n>0; n--)
x[n] = x[n-1];
//Calculate the new output
x[0] = NewSample;
for(n=0; n<Ntap; n++)
y += FIRCoef[n] * x[n];
return y / DCgain;
}
=======================================
А это VHDL
----------------------------------------------------------------
-- FIR 50 Taps
-- Coefficents Quantization: 16-bit
-- Filter type: Low Pass
-- Filter model: Butterworth
-- Filter order: 10
-- Sampling Frequency: 44 KHz
-- Cut Frequency: 20.000000 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 = -1.000000 + j 0.000000
-- z = -1.000000 + j 0.000000
--
-- Z domain Poles
-- z = -0.799984 + j -0.166318
-- z = -0.799984 + j 0.166318
-- z = -0.766873 + j -0.101934
-- z = -0.766873 + j 0.101934
-- z = -0.850768 + j -0.222547
-- z = -0.850768 + j 0.222547
-- z = -0.750758 + j -0.034564
-- z = -0.750758 + j 0.034564
-- z = -0.918982 + j -0.266509
-- z = -0.918982 + j 0.266509
--
-- Signal Resolution: 16-bit
-- Coefficients Quantization: 16-bit
-- 1 multiplier(s)
-- 994 FFs for the filter*
-- 816 FFs for the coefficients*
-- 51 clks output latency
-- 2244000 Hz for Fclk
-- 44000 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 := 50
);
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"ffc7";
ROMDATA(1) <= x"ffe4";
ROMDATA(2) <= x"007c";
ROMDATA(3) <= x"ff20";
ROMDATA(4) <= x"0141";
ROMDATA(5) <= x"fe69";
ROMDATA(6) <= x"01d9";
ROMDATA(7) <= x"fe01";
ROMDATA(8) <= x"0201";
ROMDATA(9) <= x"fe27";
ROMDATA(10) <= x"0183";
ROMDATA(11) <= x"ff05";
ROMDATA(12) <= x"0044";
ROMDATA(13) <= x"00a0";
ROMDATA(14) <= x"fe53";
ROMDATA(15) <= x"02d8";
ROMDATA(16) <= x"fbe8";
ROMDATA(17) <= x"055f";
ROMDATA(18) <= x"f95f";
ROMDATA(19) <= x"07d0";
ROMDATA(20) <= x"f723";
ROMDATA(21) <= x"09bd";
ROMDATA(22) <= x"f59b";
ROMDATA(23) <= x"0acd";
ROMDATA(24) <= x"74f0";
ROMDATA(25) <= x"0acd";
ROMDATA(26) <= x"f59b";
ROMDATA(27) <= x"09bd";
ROMDATA(28) <= x"f723";
ROMDATA(29) <= x"07d0";
ROMDATA(30) <= x"f95f";
ROMDATA(31) <= x"055f";
ROMDATA(32) <= x"fbe8";
ROMDATA(33) <= x"02d8";
ROMDATA(34) <= x"fe53";
ROMDATA(35) <= x"00a0";
ROMDATA(36) <= x"0044";
ROMDATA(37) <= x"ff05";
ROMDATA(38) <= x"0183";
ROMDATA(39) <= x"fe27";
ROMDATA(40) <= x"0201";
ROMDATA(41) <= x"fe01";
ROMDATA(42) <= x"01d9";
ROMDATA(43) <= x"fe69";
ROMDATA(44) <= x"0141";
ROMDATA(45) <= x"ff20";
ROMDATA(46) <= x"007c";
ROMDATA(47) <= x"ffe4";
ROMDATA(48) <= x"ffc7";
ROMDATA(49) <= x"0080";
ROMDATA(50) <= 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;
думаю и так понятно что реальней дотянуть до проекта...
Добавлено через 3 минуты
Сообщение от
Кокон
на 21261 очень хорошо и все доступно
Вообщето они для дешевых ресиверов - но тут явно сгодится.
21261 фиксен поинт. А человек хочет небось выше 120Дб получить
Пардон, перепутал, Шарк плавучку поддерживает
Социальные закладки