Having trouble with my FIR filter, help much appreciated.

M

marlan.mcleish

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
 
N

Neo

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
 
M

marlan.mcleish

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.
 
N

Neo

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.
 
N

Neo

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.
 
M

marlan.mcleish

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top