Modelo de FSM de máquina de estado finito del filtro FIR en VHDL para FPGA

0

Quiero hacer un modelo FSM de FIR, para eso necesito escribir la línea del código de cálculo FIR en la implementación de FSM.

Aquí está el código real y correcto para FIR

entity fir_4tap is
  port(   Clk : in std_logic; --clock signal
          Clk_fast : in std_logic;
          --  Xin : in signed(7 downto 0); --input signal
          bit_in : in std_logic;
          bit_out : out std_logic;
          Yout : out signed(15 downto 0)  --filter output
  );
end fir_4tap;

architecture Behavioral of fir_4tap is
  signal add_out3 : signed(15 downto 0) := (others => '0');
  signal index : unsigned(2 downto 0) := (others =>'0');
  signal counter : unsigned(3 downto 0) := (others => '0');
  signal p : unsigned(1 downto 0) := (others => '0');
  signal k : unsigned(1 downto 0) := (others => '0');
  signal j : unsigned(1 downto 0) := (others => '0');
  type array_signed is array(8 downto 0) of signed(7 downto 0);
  signal z : array_signed := (others => "00000000");
  type array_signed1 is array(3 downto 0) of signed(7 downto 0);
  signal H : array_signed1 := (others => "00000000");
  signal Xin : array_signed1 := (others => "00000000");
begin
  z(0) <= to_signed(-3,8);
  z(1) <= to_signed(1,8); 
  z(2) <= to_signed(0,8);
  z(3) <= to_signed(-2,8);
  z(4) <= to_signed(-1,8); 
  z(5) <= to_signed(4,8); 
  z(6) <= to_signed(-5,8);
  z(7) <= to_signed(6,8); 
  z(8) <= to_signed(0,8);
  H(0) <= to_signed(-2,8);
  H(1) <= to_signed(-1,8);
  H(2) <= to_signed(3,8);
  H(3) <= to_signed(4,8);

  process (clk) 
  begin
    if (rising_edge(Clk)) then 
      index <= index +1;
      if (index = "111") then 
        Xin(to_integer(p)) <= z(to_integer(counter));                                              k <= p;
        p <= p + 1;
        ***-- This part of the code has problem, I want to write the line which is summing --up for add_out3 in a for loop.***
        add_out3 <= (others => '0');
        add_out3 <=  Xin(to_integer(k))*H(to_integer(j)) + Xin(to_integer(k-1))*H(to_integer(j+1)) + Xin(to_integer(k-2))*H(to_integer(j+2)) + Xin(to_integer(k-3))*H(to_integer(j+3));
        Yout <= add_out3;
      end if;
    end if;
  end process;
end Behavioral;

Ahora debajo está la implementación de FSM, intente por mí pero no obtener la misma muestra de salida que alguien. ¿Puede alguien decirme cuál podría ser el problema en el código?

---------------- Implementación FSM del filtro FIR ----------- ----------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;


entity test is
port(   Clk : in std_logic; --clock signal
          Clk_fast : in std_logic;
          bit_in : in std_logic;
          bit_out : out std_logic;
        Yout : out signed(15 downto 0)  --filter output
        );


end test;

architecture Behavioral of test is
signal data_buffer : signed(7 downto 0) := (others => '0');
signal index : unsigned(2 downto 0) := (others =>'0');


signal counter : unsigned(3 downto 0) := (others => '0');

type array_signed is array(8 downto 0) of signed(7 downto 0);
signal z : array_signed := (others => "00000000");

type array_signed1 is array(3 downto 0) of signed(7 downto 0);
signal H : array_signed1 := (others => "00000000");

signal input : signed(7 downto 0) := (others => '0');

type MULT_TYPE is array(3 downto 0) of signed(15 downto 0);
signal MULT_array : MULT_TYPE := (others => "0000000000000000");

type ADD_TYPE is array(3 downto 0) of signed(15 downto 0);
signal ADD_array : ADD_TYPE := (others => "0000000000000000");

constant ZERO : signed(15 downto 0) := (others => '0');

type state_type is (s0,s1,s2,s3);  --type of state machine.
signal current_s : state_type := s0;  --current and next state declaration.
signal next_s : state_type := s0; 

signal reset : std_logic := '0';
signal go : std_logic := '0';
signal change_state : std_logic := '0' ;
signal counter_FSM_monitor : unsigned( 6 downto 0) := "0000000"; 

begin

z(0) <= to_signed(-3,8);
z(1) <= to_signed(1,8); 
z(2) <= to_signed(0,8);
z(3) <= to_signed(-2,8);
z(4) <= to_signed(-1,8); 
z(5) <= to_signed(4,8); 
z(6) <= to_signed(-5,8);
z(7) <= to_signed(6,8); 
z(8) <= to_signed(0,8);

H(0) <= to_signed(-2,8);
H(1) <= to_signed(-1,8);
H(2) <= to_signed(3,8);
H(3) <= to_signed(4,8);




process (Clk) is
begin
if falling_edge(Clk) then 

data_buffer(to_integer(index)) <= bit_in;
index <= index +1;
if (index = "111") then 
input <= z(to_integer(counter));

counter <= counter + 1;
if(counter = "1000") then 
counter <= "0000";
end if; 
end if;
end if;
end process;


process (clk_fast)
begin

if (falling_edge(clk_fast)) then

counter_FSM_monitor <= counter_FSM_monitor + 1;

if( to_integer(counter_FSM_monitor) = 76) then 
counter_FSM_monitor <= "0000000";
end if;

case change_state is 

when '1' => 
current_s <= next_s;   --state change.                 

when '0' => --current_s <= s0;                 
when others =>
end case;
end if;
end process;

Process(current_s,input)
begin 
if ( to_integer(counter_FSM_monitor) < 64 ) then 
-- waiting for the Input
elsif (to_integer(counter_FSM_monitor) >= 64 and to_integer(counter_FSM_monitor) < 76) then 


---------------------------------------------- FSM ----------------------------------------


case current_s is 

when s0 => 
mult_array(0) <= input*H(3);
ADD_array(0) <= ZERO + mult_array(0);
next_s <= s1;
change_state <= '1';

when s1 => 
mult_array(1) <= input*H(2);
ADD_array(1) <= mult_array(1) + ADD_array(0);
next_s <= s2;
change_state <= '1';

when s2 => 
mult_array(2) <= input*H(1);
ADD_array(2) <= mult_array(2) + ADD_array(1);
next_s <= s3;
change_state <= '1';

when s3 => 
mult_array(3) <= input*H(0);
ADD_array(3) <= mult_array(3) + ADD_array(2);
Yout <= ADD_array(3);
next_s <= s0;
change_state <= '1';

when others => 
next_s <= s0;-- never comes here
change_state <= '1';
end case;
---------------------------------------------- FSM ----------------------------------------
end if;
end process;
end Behavioral;

No puedo recibir la misma salida que recibí con el primer código con el modelo FSM. El código FSM da la salida correcta para la primera salida, pero a partir de la segunda muestra da un resultado incorrecto. ¿Puede alguien decirme qué estoy haciendo mal?

    
pregunta user3217310

1 respuesta

3

Su segundo código "FSM" tiene muchos problemas, principalmente en el último proceso: process (current_s, input) . Solo algunos ejemplos para comenzar con:

  • Este es un proceso asíncrono, por lo que debe enumerar todas de las señales utilizadas dentro de la lista de sensibilidad. Si no lo hace, significa que la simulación no coincidirá con el comportamiento del hardware real.
  • Dado que no se asignan todas las salidas en cada ruta posible a través del código, está creando una enorme cantidad de cierres implícitos, que probablemente simularán el OK pero le darán muchos problemas en síntesis.

Además, esta es una pregunta mal hecha:

  • No documentaste la relación entre Clk y clk_fast .
  • No has formateado (por ejemplo, sangrado) el código para que otros puedan seguirlo fácilmente.
  • No comentaste el código para que pudiéramos averiguar cuál era tu intención .

De todos modos, en general, un FSM no es el enfoque recomendado para este tipo de problema. Lo que realmente necesita hacer es configurar un pipeline para hacer la aritmética FIR. Esto le permitiría eliminar el reloj rápido junto con la complicada lógica FSM. El módulo producirá la misma salida que el módulo original, excepto que se retrasará por el número de etapas en su canalización.

    
respondido por el Dave Tweed

Lea otras preguntas en las etiquetas