199 lines
3.8 KiB
VHDL
199 lines
3.8 KiB
VHDL
library IEEE;
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
|
use IEEE.NUMERIC_STD.ALL;
|
|
use work.filter_pkg.all;
|
|
|
|
entity Filter is
|
|
generic (
|
|
CLK_FREQ : integer := 200e6;
|
|
DATA_RATE: integer := 250e3;
|
|
|
|
|
|
SIMETRIC : boolean := TRUE;
|
|
CONSTANTS : array_of_integers := (-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8)
|
|
|
|
);
|
|
port (
|
|
clk_i : in std_logic;
|
|
enable: in std_logic;
|
|
reset: in std_logic;
|
|
|
|
d_i : in std_logic;
|
|
d_o : out std_logic;
|
|
p_o : out std_logic_vector(9 downto 0)
|
|
);
|
|
end Filter;
|
|
|
|
architecture Behavioral of Filter is
|
|
|
|
--~ Array con las constantes, ordenadas de 0 a N
|
|
constant K : array_of_integers := reorder_array(CONSTANTS, SIMETRIC);
|
|
--~ Tamaño del array
|
|
constant N : integer := K'length;
|
|
--~ Frecuencia a la que se samplea la entrada
|
|
constant SAMPLE_RATE : integer := DATA_RATE * (N-1);
|
|
|
|
--~ Shift Register
|
|
signal LSR : std_logic_vector(N-1 downto 0) := (others => '0');
|
|
|
|
|
|
--~ Constante y señales para el contador/divisor de frecuencia
|
|
constant MAX_COUNT : integer := CLK_FREQ / (SAMPLE_RATE);
|
|
signal counter : integer range 0 to MAX_COUNT - 1 := 0;
|
|
signal sample_clk_s : std_logic := '0';
|
|
|
|
|
|
--~ Acumulador:
|
|
signal accum: integer range -MAX_RANGE to MAX_RANGE := 0;
|
|
signal i : integer range 0 to N-1 := 0;
|
|
signal i_rst : std_logic := '0';
|
|
|
|
|
|
signal d_s : std_logic := '0';
|
|
signal p_s : std_logic_vector(9 downto 0) := (others => '0');
|
|
|
|
type STATUS_T is ( wait_start,
|
|
clear,
|
|
sum_loop );
|
|
|
|
signal state, next_state : STATUS_T := wait_start;
|
|
|
|
|
|
|
|
|
|
begin
|
|
|
|
d_o <= d_s;
|
|
p_o <= p_s;
|
|
|
|
--~ Proceso sincrónico para cambio de estados
|
|
stateProcess:
|
|
process(clk_i)
|
|
begin
|
|
if ( rising_edge(clk_i) ) then
|
|
if ( reset = '1' ) then
|
|
state <= wait_start;
|
|
elsif ( enable = '1' ) then
|
|
state <= next_state;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
|
|
--~ Tranciciones entre estados
|
|
stateTransition:
|
|
process(state,i,sample_clk_s)
|
|
begin
|
|
case state is
|
|
when wait_start =>
|
|
i_rst <= '0';
|
|
|
|
if ( sample_clk_s = '1' ) then
|
|
next_state <= clear;
|
|
else
|
|
next_state <= wait_start;
|
|
end if;
|
|
|
|
when clear =>
|
|
i_rst <= '1';
|
|
|
|
next_state <= sum_loop;
|
|
|
|
when sum_loop =>
|
|
i_rst <= '0';
|
|
|
|
if ( i = N-1 ) then
|
|
next_state <= wait_start;
|
|
else
|
|
next_state <= sum_loop;
|
|
end if;
|
|
|
|
end case;
|
|
end process;
|
|
|
|
|
|
|
|
--~ Proceso sincrónico para contador interno y para acumulador
|
|
process(clk_i)
|
|
begin
|
|
if ( rising_edge(clk_i) ) then
|
|
|
|
if ( enable = '1' ) then
|
|
if ( i_rst = '1' ) then
|
|
i <= 0;
|
|
accum <= 0;
|
|
|
|
else
|
|
if ( i < N-1 ) then
|
|
i <= i + 1;
|
|
|
|
if ( LSR(i) = '1' ) then
|
|
accum <= accum + K(i);
|
|
else
|
|
accum <= accum - K(i);
|
|
end if;
|
|
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
|
|
|
|
--~ Latch de la salida,
|
|
--~ Si. la salida va a estar latcheada
|
|
OutputLatch:
|
|
process(clk_i)
|
|
begin
|
|
if ( rising_edge(clk_i) ) then
|
|
if ( enable = '1' and sample_clk_s = '1' and i = N-1 ) then
|
|
p_s <= std_logic_vector(to_signed(accum,p_s'length));
|
|
|
|
if ( accum > 0 ) then
|
|
d_s <= '1';
|
|
else
|
|
d_s <= '0';
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
|
|
|
|
--~ Registro de desplazamiento para el sobremuestreo
|
|
LSRprocess:
|
|
process ( clk_i )
|
|
begin
|
|
if ( rising_edge(clk_i) ) then
|
|
if ( reset = '1' ) then
|
|
LSR <= ( others => '0' );
|
|
|
|
elsif ( enable = '1' and sample_clk_s = '1' ) then
|
|
LSR( 0 ) <= d_i;
|
|
LSR( N-1 downto 1 ) <= LSR( N-2 downto 0 );
|
|
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
--~ Divisor de frecuencia, para obtener la frecuencia de sampleo
|
|
sample_clk_s <= '1' when counter = MAX_COUNT -1 else '0';
|
|
|
|
ClkDiv:
|
|
process( clk_i, reset )
|
|
begin
|
|
if ( rising_edge(clk_i) ) then
|
|
if ( enable = '1' ) then
|
|
if ( counter = MAX_COUNT -1 ) then
|
|
counter <= 0;
|
|
else
|
|
counter <= counter + 1;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
end Behavioral;
|
|
|