I want to make a FSM model of FIR, for that I need to write FIR calculation code line in FSM implementation.
Here is the actual and correct code for 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;
Now Below is the FSM implementation try by me but not getting the same out sample as input can somebody tell me what could be the problem in the code?
----------------FSM implementation of the FIR filter ----------------------
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;
How ever I am not able to receive the same output which I received by the first code. FSM code gives the correct output for the first out but from the second out sample it gives wrong result.Can somebody tell me what I am doing wrong ?
This answer is for the initial version of the question but Now question has been changed. Made add_out3 a variable instead of a signal.
for i in 0 to 3 loop
add_out3 := add_out3 + Xin(k-i)*H(i);
end loop;
Did the above changes in the for loop It works fine. So the code in my question is a correct code for FIR also, works smoothly. Learnt that one needs to be very careful while using signal or variables. All the signals get a new value at the same time i.e at the end of clock period, while in variables values gets updated as assigned within a process. Tried to run the simulation step by step and figured out the problem.