Debajo hay un filtro de 4 toques. Eso significa que el orden del filtro es 4 y por lo tanto tiene 4 coeficientes. La entrada es firmada tipo de 8 bits de ancho. La salida también es de tipo firmado con 16 bits de ancho. El diseño contiene dos archivos. Uno es el archivo principal con todas las multiplicaciones y sumadores definidos en él, y otro para definir la operación D flip flop.
El archivo principal se muestra a continuación:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity fir_4tap is
port( Clk : in std_logic; --clock signal
Xin : in signed(7 downto 0); --input signal
Yout : out signed(15 downto 0) --filter output
);
end fir_4tap;
architecture Behavioral of fir_4tap is
component DFF is
port(
Q : out signed(15 downto 0); --output connected to the adder
Clk :in std_logic; -- Clock input
D :in signed(15 downto 0) -- Data input from the MCM block.
);
end component;
signal H0,H1,H2,H3 : signed(7 downto 0) := (others => '0');
signal MCM0,MCM1,MCM2,MCM3,add_out1,add_out2,add_out3 : signed(15 downto 0) := (others => '0');
signal Q1,Q2,Q3 : signed(15 downto 0) := (others => '0');
begin
--filter coefficient initializations.
--H = [-2 -1 3 4].
H0 <= to_signed(-2,8);
H1 <= to_signed(-1,8);
H2 <= to_signed(3,8);
H3 <= to_signed(4,8);
--Multiple constant multiplications.
MCM3 <= H3*Xin;
MCM2 <= H2*Xin;
MCM1 <= H1*Xin;
MCM0 <= H0*Xin;
--adders
add_out1 <= Q1 + MCM2;
add_out2 <= Q2 + MCM1;
add_out3 <= Q3 + MCM0;
--flipflops(for introducing a delay).
dff1 : DFF port map(Q1,Clk,MCM3);
dff2 : DFF port map(Q2,Clk,add_out1);
dff3 : DFF port map(Q3,Clk,add_out2);
--an output produced at every positive edge of clock cycle.
process(Clk)
begin
if(rising_edge(Clk)) then
Yout <= add_out3;
end if;
end process;
end Behavioral;
El código VHDL para el componente DFF se proporciona a continuación:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity DFF is
port(
Q : out signed(15 downto 0); --output connected to the adder
Clk :in std_logic; -- Clock input
D :in signed(15 downto 0) -- Data input from the MCM block.
);
end DFF;
architecture Behavioral of DFF is
signal qt : signed(15 downto 0) := (others => '0');
begin
Q <= qt;
process(Clk)
begin
if ( rising_edge(Clk) ) then
qt <= D;
end if;
end process;
end Behavioral;
He escrito un pequeño código de banco de pruebas para probar el diseño. Contiene 8 entradas de prueba que se aplican en serie al módulo de filtro. Vea abajo:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY tb IS
END tb;
ARCHITECTURE behavior OF tb IS
signal Clk : std_logic := '0';
signal Xin : signed(7 downto 0) := (others => '0');
signal Yout : signed(15 downto 0) := (others => '0');
constant Clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: entity work.fir_4tap PORT MAP (
Clk => Clk,
Xin => Xin,
Yout => Yout
);
-- Clock process definitions
Clk_process :process
begin
Clk <= '0';
wait for Clk_period/2;
Clk <= '1';
wait for Clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
wait for Clk_period*2;
Xin <= to_signed(-3,8); wait for clk_period*1;
Xin <= to_signed(1,8); wait for clk_period*1;
Xin <= to_signed(0,8); wait for clk_period*1;
Xin <= to_signed(-2,8); wait for clk_period*1;
Xin <= to_signed(-1,8); wait for clk_period*1;
Xin <= to_signed(4,8); wait for clk_period*1;
Xin <= to_signed(-5,8); wait for clk_period*1;
Xin <= to_signed(6,8); wait for clk_period*1;
Xin <= to_signed(0,8);
wait;
end process;
END;
La pregunta principal es que el resultado de la simulación es bueno y si este código funcionará en el dispositivo fpga virtex 4. Estoy usando el software xilinx y este software tiene generadores de ip core pero no los estoy usando porque quiero obtener una buena codificación práctica.