Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
9 years ago

Trouble with CIC filter

I'm trying to implement a CIC decimation filter( with R = 1000, M = 1 and N = 2 ) and Fs = 1 MHz without using the CIC IP core. Using matlab implementation I found out that the suppression of the CIC filter will be 26.58 dB for all frequencies above 500Hz which is relatively good for my project. But on implementing the CIC filter whenever I'm passing a signal of 1KHz, the output of the cic filter is a dc offset which is the expected result but on passing frequencies above 5KHz I'm getting output of the CIC filter as noise. Can anyone please help me finding what's wrong with the code. The attachment contains the matlab freq response.

The data input is 12 bit, so the output will be 32 bit as per the CIC filter register growth equation.

ENTITY cic_filter IS

PORT(

clk_in : IN std_logic; -- input sample rate clock(1 MHz)

data_in : IN std_logic_vector(11 downto 0); -- sample data in, Q12._

clk_out : OUT std_logic; -- output clock (clk_in / 1000)

data_out : OUT std_logic_vector(31 downto 0) -- data out

);

END cic_filter;

ARCHITECTURE behavior OF cic_filter IS

-- latched, 32-bit data in

signal l_data_in : signed(31 downto 0);

-- outputs for each integrator stage

signal integrator_out_1, integrator_out_2 : signed(31 downto 0) := (others => '0');

-- delayed outputs for each integrator stage

signal l_integrator_out_1, l_integrator_out_2 : signed(31 downto 0) := (others => '0');

-- inputs for each comb stage

signal comb_in_1, comb_in_2 : signed(31 downto 0) := (others => '0');

-- delayed inputs for each comb stage

signal l_comb_in_1, l_comb_in_2 : signed(31 downto 0) := (others => '0');

-- decimation clock

signal clk_decimated : std_logic;

signal count : natural range 1 to 1000 := 1;

begin

l_data_in <= resize(signed(data_in),32);

integrators : process( clk_in )

begin

if( rising_edge(clk_in) ) then

-- sums

integrator_out_1 <= (l_data_in) + l_integrator_out_1;

integrator_out_2 <= integrator_out_1 + l_integrator_out_2;

-- delays

l_integrator_out_1 <= integrator_out_1;

l_integrator_out_2 <= integrator_out_2;

end if;

end process;

decimation_clock : process( clk_in )

begin

if( rising_edge(clk_in) ) then

if( count = 1000 ) then

count <= 1;

clk_decimated <= '1';

else

count <= count + 1;

clk_decimated <= '0';

end if;

end if;

end process decimation_clock;

clk_out <= clk_decimated;

combs : process( clk_decimated )

begin

if( rising_edge(clk_decimated) ) then

-- decimation of integrator output

comb_in_1 <= integrator_out_2;

-- sums

comb_in_2 <= comb_in_1 - l_comb_in_1;

data_out <= std_logic_vector( comb_in_2 - l_comb_in_2 );

-- delays

l_comb_in_1 <= comb_in_1;

l_comb_in_2 <= comb_in_2;

end if;

end process;

end behavior;

11 Replies