Having trouble with my FIR filter, help much appreciated.

Discussion in 'VHDL' started by marlan.mcleish@googlemail.com, Feb 1, 2007.

  1. Guest

    Hi, I am doing my FYP and it involves the usage of an FIR filter with
    dynamic updating coefficients. my issue is I needed to redesign it to
    get data, coefficients and perform the MAC process independently and
    concurrently. This meant I needed to use signals (previously used
    variables) this has cause me no end of grief and I cant understand
    why. Basically I have split the MAC operation into a component called
    tap, I need to process 20 taps before new data can be accepted. since
    I am using signals instead of variables I can just wrap around the
    operation to the next cycle or at least not sure how. basically I have
    been about to get 5 taps done in 1 clock but not sure how to do the
    remaining 15, after looking at my code it will be more coherent.
    (another issue is that now the component wont connect to the signals,
    have no clue why.) Heres the code for the FIR section (taps not
    included as its trivial and I know that part works):

    --------------------------------header of fir
    filter-------------------------------
    library ieee;
    use ieee.std_logic_1164.all;

    entity fir is
    generic(
    ntaps: integer:= 20;
    nbits: integer:= 10
    );

    port(
    coef_i, coef_q: in std_logic_vector(nbits-1 downto 0);
    data_i, data_q: in std_logic_vector(nbits-1 downto 0);
    clk: in std_logic;
    send_coef, send_data: in std_logic;
    request_coef, request_data: out std_logic;
    result_i, result_q: out std_logic_vector(nbits-1 downto 0)
    );
    end fir;
    -----------------------------body of fir
    filter------------------------------------
    architecture behaviour of fir is
    type reg1 is array (ntaps-1 downto 0) of std_logic_vector(nbits-1
    downto 0);
    type reg2 is array (ntaps downto 0) of std_logic_vector(nbits-1
    downto 0);

    signal coefreg_i, coefreg_q: reg1;
    signal sum_i, sum_q: reg2;
    signal datareg_i, datareg_q: reg1;
    signal clk_slow: std_logic;
    signal i, count: integer := 0;

    component tap
    generic(
    nbits: integer
    );
    port(
    clk: in std_logic;
    cin_i, cin_q: in std_logic_vector(nbits-1 downto 0);
    din_i, din_q: in std_logic_vector(nbits-1 downto 0);
    prv_sum_i, prv_sum_q: in std_logic_vector(nbits-1 downto 0);
    nxt_sum_i, nxt_sum_q: out std_logic_vector(nbits-1 downto 0)
    );
    end component;

    begin
    ----------------------combinational requesting
    logic---------------------
    request_coef <= '1' when send_coef = '0' else '0';
    request_data <= '1' when send_data = '0' and count = 3 else '0';
    --create multiple processes so that the filter is pipelined thus no
    --process is dependent on a previous process so no waiting
    ----------------------------gets
    coeficients-----------------------------
    get_coef: process(clk, send_coef)
    begin
    --when there is a change of clk and its high process the statements
    below
    if (clk'event and clk = '1') then
    --get new coeficient, store into coeficient register when coef_load
    high
    if(send_coef = '1') then
    coefreg_i(i) <= coef_i;
    coefreg_q(i) <= coef_q;
    if i < ntaps-1 then
    i <= i+1;
    else
    i <= 0;
    end if;
    end if;
    else
    end if;
    end process get_coef;
    ---------------------------frequency
    division----------------------------
    slow_clk: process(clk)
    begin
    if (clk'event and clk = '1') then
    if count < 3 then
    count <= count + 1;
    else
    clk_slow <= not(clk_slow);
    count <= 0;
    end if;
    end if;
    end process slow_clk;
    -----------------------------gets new
    data-------------------------------
    get_data: process(clk_slow, send_data)
    begin
    if (clk_slow'event and clk_slow = '1') then
    --get new data, perform first tap and store result when data_load high
    if(send_data = '1') then
    datareg_i <= data_i & datareg_i(ntaps-1 downto 1);
    datareg_q <= data_q & datareg_q(ntaps-1 downto 1);
    end if;
    else
    end if;
    end process get_data;
    -----------------------------perform tap
    n-------------------------------
    tapgen: for k in 0 to 4 generate
    tapcore: tap
    generic map(
    nbits => nbits
    )
    port map(
    clk => clk,
    cin_i => coefreg_i(k), cin_q => coefreg_q(k),
    din_i => datareg_i(k), din_q => datareg_q(k),
    prv_sum_i => sum_i(k), prv_sum_q => sum_q(k),
    nxt_sum_i => sum_i(k+1), nxt_sum_q => sum_q(k+1)
    );
    end generate tapgen;

    result_i <= sum_i(5);
    result_q <= sum_i(5);
    end behaviour;
    ------------------------------end of fir
    filter------------------------------------


    Any helps much appreciated.

    Thanks

    Marlan McLeish
     
    , Feb 1, 2007
    #1
    1. Advertising

  2. Neo Guest

    On Feb 1, 9:24 pm, wrote:
    > Hi, I am doing my FYP and it involves the usage of an FIR filter with
    > dynamic updating coefficients. my issue is I needed to redesign it to
    > get data, coefficients and perform the MAC process independently and
    > concurrently. This meant I needed to use signals (previously used
    > variables) this has cause me no end of grief and I cant understand
    > why. Basically I have split the MAC operation into a component called
    > tap, I need to process 20 taps before new data can be accepted. since
    > I am using signals instead of variables I can just wrap around the
    > operation to the next cycle or at least not sure how. basically I have
    > been about to get 5 taps done in 1 clock but not sure how to do the
    > remaining 15, after looking at my code it will be more coherent.
    > (another issue is that now the component wont connect to the signals,
    > have no clue why.) Heres the code for the FIR section (taps not
    > included as its trivial and I know that part works):
    >
    > --------------------------------header of fir
    > filter-------------------------------
    > library ieee;
    > use ieee.std_logic_1164.all;
    >
    > entity fir is
    > generic(
    > ntaps: integer:= 20;
    > nbits: integer:= 10
    > );
    >
    > port(
    > coef_i, coef_q: in std_logic_vector(nbits-1 downto 0);
    > data_i, data_q: in std_logic_vector(nbits-1 downto 0);
    > clk: in std_logic;
    > send_coef, send_data: in std_logic;
    > request_coef, request_data: out std_logic;
    > result_i, result_q: out std_logic_vector(nbits-1 downto 0)
    > );
    > end fir;
    > -----------------------------body of fir
    > filter------------------------------------
    > architecture behaviour of fir is
    > type reg1 is array (ntaps-1 downto 0) of std_logic_vector(nbits-1
    > downto 0);
    > type reg2 is array (ntaps downto 0) of std_logic_vector(nbits-1
    > downto 0);
    >
    > signal coefreg_i, coefreg_q: reg1;
    > signal sum_i, sum_q: reg2;
    > signal datareg_i, datareg_q: reg1;
    > signal clk_slow: std_logic;
    > signal i, count: integer := 0;
    >
    > component tap
    > generic(
    > nbits: integer
    > );
    > port(
    > clk: in std_logic;
    > cin_i, cin_q: in std_logic_vector(nbits-1 downto 0);
    > din_i, din_q: in std_logic_vector(nbits-1 downto 0);
    > prv_sum_i, prv_sum_q: in std_logic_vector(nbits-1 downto 0);
    > nxt_sum_i, nxt_sum_q: out std_logic_vector(nbits-1 downto 0)
    > );
    > end component;
    >
    > begin
    > ----------------------combinational requesting
    > logic---------------------
    > request_coef <= '1' when send_coef = '0' else '0';
    > request_data <= '1' when send_data = '0' and count = 3 else '0';
    > --create multiple processes so that the filter is pipelined thus no
    > --process is dependent on a previous process so no waiting
    > ----------------------------gets
    > coeficients-----------------------------
    > get_coef: process(clk, send_coef)
    > begin
    > --when there is a change of clk and its high process the statements
    > below
    > if (clk'event and clk = '1') then
    > --get new coeficient, store into coeficient register when coef_load
    > high
    > if(send_coef = '1') then
    > coefreg_i(i) <= coef_i;
    > coefreg_q(i) <= coef_q;
    > if i < ntaps-1 then
    > i <= i+1;
    > else
    > i <= 0;
    > end if;
    > end if;
    > else
    > end if;
    > end process get_coef;
    > ---------------------------frequency
    > division----------------------------
    > slow_clk: process(clk)
    > begin
    > if (clk'event and clk = '1') then
    > if count < 3 then
    > count <= count + 1;
    > else
    > clk_slow <= not(clk_slow);
    > count <= 0;
    > end if;
    > end if;
    > end process slow_clk;
    > -----------------------------gets new
    > data-------------------------------
    > get_data: process(clk_slow, send_data)
    > begin
    > if (clk_slow'event and clk_slow = '1') then
    > --get new data, perform first tap and store result when data_load high
    > if(send_data = '1') then
    > datareg_i <= data_i & datareg_i(ntaps-1 downto 1);
    > datareg_q <= data_q & datareg_q(ntaps-1 downto 1);
    > end if;
    > else
    > end if;
    > end process get_data;
    > -----------------------------perform tap
    > n-------------------------------
    > tapgen: for k in 0 to 4 generate
    > tapcore: tap
    > generic map(
    > nbits => nbits
    > )
    > port map(
    > clk => clk,
    > cin_i => coefreg_i(k), cin_q => coefreg_q(k),
    > din_i => datareg_i(k), din_q => datareg_q(k),
    > prv_sum_i => sum_i(k), prv_sum_q => sum_q(k),
    > nxt_sum_i => sum_i(k+1), nxt_sum_q => sum_q(k+1)
    > );
    > end generate tapgen;
    >
    > result_i <= sum_i(5);
    > result_q <= sum_i(5);
    > end behaviour;
    > ------------------------------end of fir
    > filter------------------------------------
    >
    > Any helps much appreciated.
    >
    > Thanks
    >
    > Marlan McLeish


    Looks like you are taking each co-eff at a time, so that means you
    will take 20 clocks just to laod the coeffts so there is no point in
    doing all your calc in one cycle. You can just do a coefft*data_sample
    operation each clock and put it in the acculmulator and do like wise
    in subsequent clock cycles adding to the accumulator your results so
    after 20 clock cycles you will have your first ouput ready and then
    you will have outputs each clock cycle.

    cheers
     
    Neo, Feb 2, 2007
    #2
    1. Advertising

  3. Guest

    Hi, sorry I didnt explain properly, the filter will start with 20
    coefficients already pre-loaded, I have just not put that part in yet.
    I need to evaluate all 20 taps within 4 clock cycles.
     
    , Feb 2, 2007
    #3
  4. Neo Guest

    On Feb 2, 11:45 pm, ""
    <> wrote:
    > Hi, sorry I didnt explain properly, the filter will start with 20
    > coefficients already pre-loaded, I have just not put that part in yet.
    > I need to evaluate all 20 taps within 4 clock cycles.


    So if thats all you want you just have to do 5MAC operations per
    clock. From your code above that has to be done by your tap_core. If
    your 5 tap_core modules output is finally getting added up( is it?)
    then that result is what you are looking for.

    hope this helps.
     
    Neo, Feb 6, 2007
    #4
  5. Neo Guest

    On Feb 2, 11:45 pm, ""
    <> wrote:
    > Hi, sorry I didnt explain properly, the filter will start with 20
    > coefficients already pre-loaded, I have just not put that part in yet.
    > I need to evaluate all 20 taps within 4 clock cycles.


    Oops I am sorry, I forgot, what about the 20 inputs you need? do you
    get it in 20 clocks? then still my first reply holds.
     
    Neo, Feb 6, 2007
    #5
  6. Guest

    On 6 Feb, 08:21, "Neo" <> wrote:
    > On Feb 2, 11:45 pm, ""
    >
    > <> wrote:
    > > Hi, sorry I didnt explain properly, the filter will start with 20
    > > coefficients already pre-loaded, I have just not put that part in yet.
    > > I need to evaluate all 20 taps within 4 clock cycles.

    >
    > Oops I am sorry, I forgot, what about the 20 inputs you need? do you
    > get it in 20 clocks? then still my first reply holds.


    Hi, yes I get 20 inputs over 20 clocks , in a continuous system
    whereby a further 20 taps come in and the previous 20 taps must
    already of been process by that time so yes my code above does this.
    my issue is that I cant get it to increment properly, after I do the
    first 5 I am unsure how to do the next 15 remaining taps. I cant make
    the value of the index increment e.g. (k+i) where i = i+8 (incremented
    per clock), as I get an error stating that the index is not static.
    How would I go about incrementing the index.
     
    , Feb 8, 2007
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Emel
    Replies:
    0
    Views:
    3,646
  2. Emel
    Replies:
    0
    Views:
    899
  3. Simon
    Replies:
    2
    Views:
    298
    Joerg Jooss
    Jul 17, 2004
  4. windandwaves
    Replies:
    18
    Views:
    707
    Spartanicus
    Mar 19, 2005
  5. erick232

    need help in VHDL FIR filter

    erick232, Jun 26, 2010, in forum: VHDL
    Replies:
    0
    Views:
    599
    erick232
    Jun 26, 2010
Loading...

Share This Page