Forum Discussion
Altera_Forum
Honored Contributor
10 years agodigital filter
hello everybody.
i am beginning with vhdl an i try to implement a digita filter on cyclone 2 This is the code i havebut i d ont understand why it doesnt work thk for help library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; entity filter is --generic ( FILTERLAENGE :natural:=6; -- FILTERKOEFF :array (natural range 0 to FILTERLAENGE - 1) of signed( 7 downto 0) :=(-1,-1,-1,-1,-1,-1) -- ); port ( clk : IN STD_LOGIC; reset : IN STD_LOGIC; filterGO : IN STD_LOGIC; filterEingang : IN STD_LOGIC_VECTOR (15 downto 0); filterAusgang : OUT STD_LOGIC_VECTOR (15 downto 0) ); end; architecture beh of filter is constant FILTERLAENGE: natural := 6; type t_memory is array (natural range 0 to FILTERLAENGE - 1) of signed(15 downto 0); type t_Koeff is array (natural range 0 to FILTERLAENGE - 1) of signed( 7 downto 0); constant FILTERKOEFF: t_Koeff := (to_signed(1, 8), to_signed(1, 8), to_signed(1, 8), to_signed(1, 8), to_signed(1, 8), to_signed(1, 8)); signal Speicher: t_memory; begin process(clk, reset) variable filterMult: signed(23 downto 0) := (others => '0'); variable filterSumme: signed(24 downto 0) := (others => '0'); begin if (reset = '0') then filterAusgang <= (others => '0'); Speicher <= (others => (others => '0')); elsif (rising_edge(clk)) then if (filterGO = '1') then -- held samples from "filterEingang" stored in Speicher for I in 0 to FILTERLAENGE - 2 loop Speicher(I) <= Speicher(I + 1); end loop; Speicher(FILTERLAENGE - 1) <= signed(filterEingang); -- filter operation y(n) = b0*x(n) + b1*x(n - 1) + ... + bn*x(0) filterSumme := (others => '0'); for I in 0 to FILTERLAENGE - 1 loop filterMult := FILTERKOEFF(I)*Speicher(FILTERLAENGE - (I + 1)); filterSumme:= filterSumme + resize(filterMult, 25); end loop; -- current filter result in "filterSumme" has 25 bits width -- needed y(n) has to be a 16 bits data filterAusgang <= std_logic_vector(resize(filterSumme, 16)); end if; end if; end process; end beh;8 Replies
- Altera_Forum
Honored Contributor
you are using multiply accumulate architecture. that is ok but you need to:
1) reset sum after adding full set of mult results 2) do not advance input until such result is finished and sum reset - Altera_Forum
Honored Contributor
thank very much for answering
my englisch is not so good. please can u write the 2 lines forme? and whats about the coefficients when i calculate then for example with mathlab should i convert then in binäre or something else? - Altera_Forum
Honored Contributor
--- Quote Start --- thank very much for answering my englisch is not so good. please can u write the 2 lines forme? and whats about the coefficients when i calculate then for example with mathlab should i convert then in binäre or something else? --- Quote End --- I think it is easier for you to change architecture to parallel multiply/add and so you don't need to worry about the accumulator reset and can advance input steam steadily. You can use integer for coeffs and convert them to signed as you have done. - Altera_Forum
Honored Contributor
my problem is when i calculate the coeff the are not interger
this is one example of the coef [0.000280, 0.003809, 0.010263, 0.013750, 0.010263, 0.003809, 0.000280] - Altera_Forum
Honored Contributor
--- Quote Start --- my problem is when i calculate the coeff the are not interger this is one example of the coef [0.000280, 0.003809, 0.010263, 0.013750, 0.010263, 0.003809, 0.000280] --- Quote End --- scale up enough for integer resolution e.g. round(0.00028*2^20) = 294 Then at final sum discard (20 LSBs or so, not critical but affects gain) - Altera_Forum
Honored Contributor
thaks a lot
- Altera_Forum
Honored Contributor
sorry one question again why 20? i have a 8 bits signal
- Altera_Forum
Honored Contributor
you can scale coeffs as required e.g.
hs=round(127*h/max(h)) or hs=round(256*h/sum(h)) %this keeps unity gain if you discard 8 lsbs at final output