konradb
Newbie level 6
vhdl FIR
I have the following code for an FIR.
It doesn't seem to be working,
Any comments? Does the principle look ok?
I have the following code for an FIR.
It doesn't seem to be working,
Any comments? Does the principle look ok?
Code:
Library IEEE;
Use IEEE.Std_Logic_1164.all;
use IEEE.Std_Logic_arith.all;
use IEEE.Std_Logic_signed.all;
entity tim_FIR is port
(
CLK_I : in std_logic;
RST_I : in std_logic;
t1_SAM_I : in std_logic; -- next sample
t1_ACK_O : out std_logic;
t1_DAT_I : in std_logic_vector(15 downto 0);
t2_SAM_O : out std_logic; -- next sample
t2_ACK_I : in std_logic;
t2_DAT_O : out std_logic_vector(15 downto 0);
t2_SAT_O : out std_logic; -- saturation
t2_OVR_O : out std_logic; -- overflow
t2_ERR_O : out std_logic -- error
);
end tim_FIR;
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
architecture Behaviour of tim_FIR is
-- Signal Declarations
type typeState is (IDLE, CALC_FIR, OUTPUT_RESULT, WAIT_ACK);
signal iState : typeState;
signal A_int: integer range -32767 to 32767;
signal result_int: integer range -32767 to 32767;
signal sum_int: integer range -2147483647 to 2147483647;
type int16array is array (0 to 63) of integer range -32767 to 32767;
signal Y : int16array;
-- created with Microchip dsPIClite
-- S/R=500K LP=28K
----=[ Coefficents Array ]=----
constant COEF : int16array := (
16#000A#, 16#000C#, 16#0009#, 16#0000#, 16#FFEF#, 16#FFD9#, 16#FFC3#, 16#FFB4#, 16#FFB4#,
16#FFCC#, 16#FFFD#, 16#0043#, 16#0095#, 16#00E0#, 16#010D#, 16#0106#, 16#00BB#, 16#0028#,
16#FF5A#, 16#FE6F#, 16#FD98#, 16#FD0D#, 16#FD0A#, 16#FDBE#, 16#FF43#, 16#0194#, 16#048D#,
16#07E8#, 16#0B49#, 16#0E49#, 16#1089#, 16#11BD#, 16#11BD#, 16#1089#, 16#0E49#, 16#0B49#,
16#07E8#, 16#048D#, 16#0194#, 16#FF43#, 16#FDBE#, 16#FD0A#, 16#FD0D#, 16#FD98#, 16#FE6F#,
16#FF5A#, 16#0028#, 16#00BB#, 16#0106#, 16#010D#, 16#00E0#, 16#0095#, 16#0043#, 16#FFFD#,
16#FFCC#, 16#FFB4#, 16#FFB4#, 16#FFC3#, 16#FFD9#, 16#FFEF#, 16#0000#, 16#0009#, 16#000C#,
16#000A#
);
----=[ ----------------- ]=----
begin
-- this process sets all time signal outputs
-- falling clock edge
clk_edge_down : process(RST_I, CLK_I)
begin
if CLK_I'EVENT and CLK_I = '0' then
case iState is
when IDLE =>
t2_SAM_O <= '0';
when CALC_FIR =>
if t1_SAM_I = '1' then
t1_ACK_O <= '1';
else
t1_ACK_O <= '0';
end if;
when OUTPUT_RESULT =>
t2_DAT_O(15 downto 0) <= conv_std_logic_vector(result_int,16);
t2_SAM_O <= '1';
when WAIT_ACK =>
when Others =>
end case;
t2_SAT_O <= '0';
t2_OVR_O <= '0';
t2_ERR_O <= '0';
end if;
end process;
-- this process catches all time signal inputs
-- and processes internal logic
-- rising clock edge
clk_edge_up : process(RST_I, CLK_I)
variable count : integer range 0 to 64;
variable clock : integer range 0 to 64;
begin
if CLK_I'EVENT and CLK_I = '1' then
if RST_I = '1' then
iState <= IDLE;
----=[ Clear Array of samples ]=----
count := 0;
while count < 64 loop --32 is n+1
Y(count) <= 0;
count := count + 1;
end loop;
------------------------------------
result_int <= 0;
sum_int <= 0;
else
-- internal state machine
case iState is
when IDLE =>
if t1_SAM_I = '1' then
iState <= CALC_FIR;
-- New Sample
clock := 0;
Y(0) <= conv_integer(signed(t1_DAT_I));
sum_int <= conv_integer(signed(t1_DAT_I));
----=[ Shift Array of samples ]=----
count := 0;
while count < 63 loop
Y(count+1) <= Y(count);
count := count + 1;
end loop;
------------------------------------
end if;
when CALC_FIR =>
if clock = 63 then
iState <= OUTPUT_RESULT;
result_int <= sum_int; -- output result
else
clock := clock + 1; -- MAC
sum_int <= sum_int + Y(clock) * COEF(clock);
end if;
when OUTPUT_RESULT =>
iState <= WAIT_ACK;
when WAIT_ACK =>
if t2_ACK_I = '1' then
iState <= IDLE;
end if;
when Others =>
iState <= IDLE;
end case;
end if;
end if;
end process;
end Behaviour;
--------------------------------------------------------------------------------