Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

vhdl FIR - code for FIR is not working

Status
Not open for further replies.

konradb

Newbie level 6
Newbie level 6
Joined
May 28, 2009
Messages
13
Helped
2
Reputation
4
Reaction score
0
Trophy points
1,281
Activity points
1,386
vhdl FIR

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;
--------------------------------------------------------------------------------
 

vhdl FIR

Cannot remember my VHDL now and the data types so I'll assume this is allowed ;-)

signal result_int: integer range -32767 to 32767;
signal sum_int: integer range -2147483647 to 2147483647;

However, how does this translate?

result_int <= sum_int;

Don't you want to shift sum_int first (based on COEF base) before assigning to result_int?
 

Re: vhdl FIR

However, how does this translate?

result_int <= sum_int;

Not quite sure, hence posting the code.
intergers are not quite the same as vectors, is the above compiler dependant?
I'm using altium with altera quartus.

the following line is corrected

Code:
-- New Sample
 sum_int <= conv_integer(signed(t1_DAT_I))* COEF(0);

I realsie that I have been feeding the FIR with duff data.
 

vhdl FIR

after your correction, are you getting the desired outcome?

depending on the precision you want as well as where the "decimal point" in on your input sample, COEF and desired output are, you might need to shift your output appropriately.
 

vhdl FIR

Typically, result_int would be copied from the high order word of sum_int rather than from the low order word as done now. Otherwise, there should be at least saturation logic. It's also basically possible to achieve an overflow of sum_int with large input signals.

The scaling of in- and output signals, coefficients and intermediate results is part of the filter design, so you should know about.
 

Check this FIR on VHDL - **broken link removed**.
It should work well.
 

    konradb

    Points: 2
    Helpful Answer Positive Rating
Thanks, I shall try it.

My code did work but Quartus only gave a maximum clock of 30MHz which was too slow.
I altered the code for parrallel operation but Quartus only gave a maximum clock of 16MHz for this!
I have bought Quartus subscription to use the in built filters, but these use the Avalon streaming interface which is not so simple to connect to.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top