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?
Ihr zweiter „FSM“-Code hat viele Probleme, hauptsächlich im letzten Prozess – process (current_s, input)
. Nur ein paar Beispiele für den Anfang:
Außerdem ist dies eine schlecht gestellte Frage:
Clk
Sie haben die Beziehung zwischen und nicht dokumentiert clk_fast
.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.
user_1818839
Benutzer3217310
user_1818839