by alfo84 » 29 Sep 2013, 22:28
Ho aperto un nuovo topic per reinserire il codice di un filtro fir, utilizzando cicli for, in una forma più chiara e più leggibile.
- Code: Select all
-------------------------------- Realizzazione del filtro FIR1 --------------------------------
-- Librerie --
library IEEE;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
-----------------------------------------------------------------------------------------------
-- Entità --
entity filtro_FIR1 is
generic (
num_bit : integer :=16; -- ho messo 16 bit e non 10 altrimenti il coeff 9914
num_taps : integer :=4 -- non posso rappresentarlo con solo 10 bit!!!
);
port(
clock_FIR1 : in std_logic;
reset_FIR1 : in std_logic;
enable_FIR1 : in std_logic;
data_in_FIR1 : in signed(num_bit-1 downto 0);
data_out_FIR1 : buffer signed(num_bit-1 downto 0) -- uscita del filtro fir sullo stesso -- numero di bit dell'ingresso
); -- numero di bit
end filtro_FIR1;
-----------------------------------------------------------------------------------------------
-- Architettura --
architecture filtro_FIR1 of filtro_FIR1 is
component Reg_N
port(
clk : in std_logic;
res : in std_logic;
en : in std_logic;
d : in signed(num_bit-1 downto 0);
q : out signed(num_bit-1 downto 0)
);
end component;
component moltiplicatore_parity_bit
port(
m1 : in signed(num_bit-1 downto 0);
m2 : in signed(num_bit-1 downto 0);
out_parity : out signed(num_bit-1 downto 0)
);
end component;
-- definiamo due nuovi tipi --
type matrix is array(0 to num_taps) of signed(num_bit-1 downto 0); -- num_taps e non nun_taps-1 altrimenti dà errore
type T_coeff is array (0 to num_taps-1) of integer;
constant coeff_2 : T_coeff := (991, -807, -807, 991);
-- "0000001111011111" ricorda coeff_2_1 = 0.09914 (moltiplico per 1000)
-- "1111110011011001" ricorda coeff_2_0 = -0.08071 (moltiplico per 1000)
signal d_FIR1 : matrix; -- campioni
signal t_FIR1 : matrix; -- risultato moltiplicazione a parità di bit
signal COEF_2 : matrix; -- coefficienti c_2
begin
d_FIR1(0) <= data_in_FIR1;
ciclo_Reg_N: for i in 0 to num_taps-1 generate
blocco_ritardo_elementare: Reg_N
port map(clock_FIR1,reset_FIR1,enable_FIR1,d_FIR1(i),d_FIR1(i+1));
end generate ciclo_Reg_N;
ciclo_coefficienti: for i in 0 to num_taps-1 generate
COEF_2(i) <= to_signed(coeff_2(i),num_bit);
end generate ciclo_coefficienti;
ciclo_moltiplicazione_parity_bit: for i in 0 to num_taps-1 generate
blocco_moltiplicazione_parity_bit: moltiplicatore_parity_bit
port map(d_FIR1(i),COEF_2(i),t_FIR1(i));
end generate ciclo_moltiplicazione_parity_bit;
-- somma su 16 bit
process(data_out_FIR1, t_FIR1)
begin
for i in 0 to num_taps-1 loop
data_out_FIR1 <= data_out_FIR1 + t_FIR1(i);
end loop;
end process;
end filtro_FIR1;
-----------------------------------------------------------------------------------------------
----------------------- Implementazione del registro a N bit -----------------------
-- Librerie --
library IEEE;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
------------------------------------------------------------------------------------
-- Entità --
entity Reg_N is
generic (num_bit : integer :=16);
port(
clk : in std_logic;
res : in std_logic;
en : in std_logic;
d : in signed(num_bit-1 downto 0);
q : out signed(num_bit-1 downto 0)
);
end Reg_N;
--ricorda che Tclk < Td/2 (per assicurarsi di prendere tutti i valori in ingresso(d))
-- Architettura --
architecture Reg_N of Reg_N is
begin
process(clk) -- sincrono
begin
if rising_edge(clk) then
if (en='1') then
if (res='0') then
q<=d;
elsif(res='1') then
q<=(others =>'0');
end if;
end if;
end if;
end process;
end Reg_N;
------------------------------------------------------------------------------------
--------------------------------- Moltiplicatore a parità del numero di bit ---------------------------------
-- Librerie --
library IEEE;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
-- La libreria "std_logic_arith" non viene utilizzata essendo ormai obsoleta.
-------------------------------------------------------------------------------------------------------------
-- Entità --
entity moltiplicatore_parity_bit is
generic(num_bit : integer :=16);
port(
m1 : in signed(num_bit-1 downto 0);
m2 : in signed(num_bit-1 downto 0);
out_parity : out signed(num_bit-1 downto 0)
);
end moltiplicatore_parity_bit;
-------------------------------------------------------------------------------------------------------------
-- Architettura --
architecture moltiplicatore_parity_bit of moltiplicatore_parity_bit is
-- Segnali --
signal m_full : signed(2*num_bit-1 downto 0); -- risultato della moltiplicazione sul doppio dei bit
signal m_round : signed(2*num_bit-1 downto 0);
signal one : signed(2*num_bit-1 downto 0);
begin
m_full <= m1 * m2;
one <= to_signed(1,2*num_bit); -- converte " 1 " in un signed a 2*num_bit
m_round <= m_full + SHIFT_LEFT(one,num_bit-1); -- rounding
out_parity <= m_round(2*num_bit-1 downto num_bit); -- fine rounding
end moltiplicatore_parity_bit;
-------------------------------------------------------------------------------------------------------------