Finite-State-Machine-FSM-Modell des FIR-Filters in VHDL für FPGA

Ich möchte ein FSM-Modell von FIR erstellen, dafür muss ich eine FIR-Berechnungscodezeile in der FSM-Implementierung schreiben.

Hier ist der tatsächliche und korrekte Code für 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;

Jetzt ist unten die FSM-Implementierung, die ich ausprobiert habe, aber nicht das gleiche Ausgangsbeispiel als Eingabe erhält. Kann mir jemand sagen, was das Problem im Code sein könnte?

---------------- FSM-Implementierung des FIR-Filters ---------------------

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;

Ich kann nicht die gleiche Ausgabe erhalten, die ich mit dem ersten Code mit dem FSM-Modell erhalten habe. Der FSM-Code gibt die richtige Ausgabe für das erste Out, aber vom zweiten Out-Sample gibt es ein falsches Ergebnis. Kann mir jemand sagen, was ich falsch mache?

Ja, ich habe gehört, dass viele erfahrene Personen in der vhdl und Elektronik auf dem electronic.stackoverflow und nicht auf stackoverflow stehen. Die Wahrscheinlichkeit, einige Vorschläge / Hilfe zu erhalten, erhöht sich wahrscheinlich, wenn Sie die Frage hier posten, da ich dort keine zufriedenstellende Antwort erhalten habe.
Wenn Sie eine bessere Antwort wünschen als die, die Sie akzeptiert haben, stellen Sie eine bessere Frage. Niemand wird eine Testbench schreiben und diese Menge für Sie debuggen. Schreiben Sie Ihre eigene Testbench und vergleichen Sie die Zwischenergebnisse zwischen Ihren beiden (funktionierenden, aber zu großen) und (noch nicht funktionierenden FSM) Versionen. Wo sie sich unterscheiden, finden Sie heraus warum und beheben Sie es.

Antworten (1)

Ihr zweiter „FSM“-Code hat viele Probleme, hauptsächlich im letzten Prozess – process (current_s, input). Nur ein paar Beispiele für den Anfang:

  • Dies ist ein asynchroner Prozess, daher müssen Sie alle darin verwendeten Signale in der Sensitivitätsliste auflisten. Andernfalls entspricht die Simulation nicht dem Verhalten der tatsächlichen Hardware.
  • Da nicht jeder Ausgang jedem möglichen Pfad durch den Code zugewiesen ist, erstellen Sie eine enorme Anzahl impliziter Latches, die wahrscheinlich OK simulieren, Ihnen aber viele Probleme bei der Synthese bereiten.

Außerdem ist dies eine schlecht gestellte Frage:

  • ClkSie haben die Beziehung zwischen und nicht dokumentiert clk_fast.
  • Sie haben den Code nicht formatiert (z. B. eingerückt), um es anderen leichter zu machen, ihm zu folgen.
  • Sie haben den Code nicht kommentiert, damit wir herausfinden können, was Ihre Absicht war.

Wie auch immer, im Allgemeinen ist ein FSM nicht der empfohlene Ansatz für diese Art von Problem. Was Sie wirklich tun müssen, ist eine Pipeline einzurichten, um die FIR-Arithmetik durchzuführen. Dies würde es Ihnen ermöglichen, die schnelle Uhr zusammen mit der komplizierten FSM-Logik vollständig zu eliminieren. Das Modul erzeugt die gleiche Ausgabe wie das ursprüngliche Modul, außer dass es um die Anzahl der Stufen in Ihrer Pipeline verzögert wird.