Jump to content
  • 0

FIR compiler 7.2 stopband


Ahmed Alfadhel

Question

Hi ,

According to the Tfilter tool parameters (first attached picture) and the frequency response of FIR IP core (second attached picture) the passband is : 16 kHz to 17 kHz, and stopband1 is: 0 to 15.5 kHz and stopband2 is: 17.5 kHz to 24 kHz .   

I tested (simulated) the filter with 16 kHz , 24 kHz , 64 kHz, 500 kHz, and 1000 kHz. The simulation results are shown below respectively.

16kHz_35dB.thumb.JPG.84a3c590eb26b4965447baceb622204f.JPG

16 kHz

24kHz_35dB.JPG

24 kHz

64kHz_35dB.JPG

64 kHz

500kHz_35dB.JPG

500 kHz

1000kHz_35dB.JPG

1000 kHz

I noticed there is no attenuation in each of 24 kHz, 64 kHz !!!

While 500 kHz, 1000 kHz appeared attenuated.

The question is: why the FIR filter doesn't attenuate the frequencies that are located in the stopband?

Note :in each attached picture the first sinewave is the input to the FIR Filter, while the second one is the output (filtered). 

Thanks.

Filter_parameters_T2.JPG

freq_response_FIR_IP.JPG

TheDesign.JPG

 

 

 

 

Link to comment
Share on other sites

13 answers to this question

Recommended Posts

... and how about a simple impulse response test (feed a stream of zeroes with an occasional 1 and check that the filter coefficients appear at the output).

Just wondering, isn't there a "ready / valid" interface also at the output if you expand the port with "+"?

Link to comment
Share on other sites

12 hours ago, Ahmed Alfadhel said:

I think I have to build my own IP core (impulse generator), in order to do the the impulse test .

true but it's a five-line job e.g. in Verilog

reg[15:0] counter = 0;
reg [15:0] impulse = 0;
always @(posedge clk) begin
	counter <= counter + 1;
	impulse <= (counter == 0) ? 16'h7FFF : 0;
end

plus the protocol interface (e.g. trigger a new valid sample if counter[7:0] == 0)

Link to comment
Share on other sites

yes, it's the highest positive 16 bit signed number 32767 (0x8FFF is the smallest negative number, -32768).

You could also consider 0x4000, which is a single bit, makes your coefficients easier to recognize in the output (because multiplying with this number is a single bit shift operation).

Link to comment
Share on other sites

On 6/17/2019 at 7:48 AM, xc6lx45 said:

... and how about a simple impulse response test (feed a stream of zeroes with an occasional 1 and check that the filter coefficients appear at the output).

Just wondering, isn't there a "ready / valid" interface also at the output if you expand the port with "+"?

Hi @xc6lx45, @D@n, @hamster

I built my own IP core for impulse generation. And I run the simulation test. I don't know how to view the impulse response !?

 Code :

---------------------------------------------------------------------------------- 
-- Engineer: Ahmed Alfadhel
-- 
-- Create Date: 06/19/2019 09:46:48 PM
-- Design Name: 
-- Module Name: Impulse - Behavioral
-- Project Name: 
-- Target Devices: 
-- Tool Versions: 
-- Description: Clk = 200 MHz
-- 
-- Dependencies: 
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
-- 
----------------------------------------------------------------------------------


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity Impulse is
    Port ( clk : in STD_LOGIC;
           impulse_data : out STD_LOGIC_VECTOR (7 downto 0);
           Valid : out STD_LOGIC;
           Ready : in STD_LOGIC);
end Impulse;

architecture Behavioral of Impulse is

signal o_impulse    : std_logic_vector(7 downto 0) := X"00";
signal s_Valid    : std_logic := '0';
constant maxcount  : integer := 4000;

begin
   impulse_data <= o_impulse;
   Valid <= s_Valid;
   LFSR_proc: process(clk)
   
    variable counter: unsigned(14 downto 0) := to_unsigned(0, 15);
    
   begin
     if(rising_edge(clk)) then
        
        counter := counter +1;
        
          if (counter = maxcount) then
            o_impulse <= X"40";
            s_Valid <= '1';
            counter := (others => '0');
          else
            o_impulse <= X"00";
            s_Valid <= '0';
          end if;
     end if;
   end process LFSR_proc;

end Behavioral;
________________________________________________________________________________

Kindly ,see the attached snapshots for simulation. The second snapshot is just a zoom out for the first one.

simulation3fir.JPG

simulation4fir.JPG

Sys_design.JPG

Link to comment
Share on other sites

@Ahmed Alfadhel,

Cool, you know how your filter should respond!

But ... does it respond that way?

You were suggesting that your filter wasn't working.  One of the first things to check is whether or not the filter, as implemented, continues to have the response you designed.  Measuring the impulse response, and then comparing it to your predicted response above, can be valuable to that end.    There are a lot of bugs that might get caught by this, to include issues associated with properly setting the coefficients in memory, truncating them to fixed bit widths, etc.

Dan

Link to comment
Share on other sites

I think you should go back to the basics. Set up a simple FIR filter e.g. [1 2 3 4 5 6 7] impulse response, and get your simulation working that an input of [..0, 1, 0.....0] gives something that resembles [1 2 3 4 5 6 7]. In your simulation this is not the case (the filter has 123 different coefficients, your simulation shows only a single output value).

Link to comment
Share on other sites

@Ahmed Alfadhel,

(Just read the prior, prior note--showing the beginnings of an impulse response ...)

To get the "answer" from a trace file, there's a couple of things you can do:

  1. I use gtkwave for viewing traces.  It has the option to view something as an analog value.  You can do that and generally reflect that your impulse response has the right shape.  That's useful, but it won't get you from a -20 dB stopband to a -80 dB stop band.
  2. What you really need to do is to take that impulse response and run an FFT on it.  No, I don't mean dumping the impulse response into an FFT component, but rather taking the values of the impulse response from the filter and sending those values into an FFT.
  3. This often requires the ability to save values from your trace into a file of some kind of type that Matlab or Octave can read.

I've done the same with a filter of my own, and you can red my report on it (and the links to how I did it) here.

Dan

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...