+ Post New Thread
Results 1 to 17 of 17
  1. #1
    Full Member level 4
    Points: 1,734, Level: 9

    Join Date
    Jan 2014
    Posts
    234
    Helped
    1 / 1
    Points
    1,734
    Level
    9

    Manually implementation of a FIR filter in a FPGA.

    Hello folks!

    I am trying to implement manually a 4 order FIR filter in a FPGA. Therefore I have a VHDL module which is able to generate a sinusoidal signal of whatever frequency with an amplitude which goes from 0 to 65535 (16 bits) designed previously with a script in matlab:

    Sinusoidal Matlab script:

    Code:
    N=100;
    fs=200;
    f=1;
    ts=1/fs;
    t = ts*(0:N-1);
    x=0;
    x=(((2^16)/2)-1)*sin(2*pi*f*t-pi/2);
    x=(((2^16)/2)-1)+x;
    x=round(x);
    filename = 'SinusSignal.xlsx'
    xlswrite(filename,x);
    plot(t,x)
    WaveGenerator.vhd module:

    Code:
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    --use IEEE.STD_LOGIC_ARITH.all;
    --use ieee.std_logic_unsigned.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 WaveGenerator is
        Generic ( DEBUG     : BOOLEAN  := false;-- True for simulations
    	          ROM_DEPTH : INTEGER  := 100); -- Number of items of the ROM
        Port    ( CLK         : in STD_LOGIC;   -- Input Clock
                  RST         : in STD_LOGIC;   -- High level reset			  
                  WAVE_GEN    : out STD_LOGIC_VECTOR (15 downto 0)); -- Waveform data output
    end WaveGenerator;
    
    architecture Behavioral of WaveGenerator is
    
    -- Signals to generate the waveform
    signal dataout     : unsigned (15 downto 0);
    signal table_index       : integer range 0 to ROM_DEPTH;
    signal table_index_down  : std_logic; -- table_index_down = '1' => walk down the table; ='0' walk up the table
    --ROM for storing the table values generated by MATLAB for the 
    -- 1/4 of a sinus signal
    type table_type is array (0 to ROM_DEPTH-1) of integer range 0 to 65535; 
    signal table : table_type :=(
         0    ,16   ,65	  ,145	,258  ,403  ,580  ,789  ,1029 ,1301 ,
    	 1604 ,1937 ,2301 ,2695 ,3119 ,3571 ,4053 ,4563 ,5101 ,5666 ,
    	 6258 ,6876 ,7520 ,8188 ,8881 ,9597 ,10336,11098,11881,12684,
    	 13507,14349,15210,16087,16981,17891,18815,19754,20705,21668,
    	 22641,23625,24618,25619,26627,27641,28660,29683,30710,31738,
    	 32767,33796,34824,35851,36874,37893,38907,39915,40916,41909,
    	 42893,43866,44829,45780,46719,47643,48553,49447,50324,51185,
    	 52027,52850,53653,54436,55198,55937,56653,57346,58014,58658,
    	 59276,59868,60433,60971,61481,61963,62415,62839,63233,63597,
    	 63930,64233,64505,64745,64954,65131,65276,65389,65469,65518
    	 );
    	
    begin
    	
    	--Process to generate the signal
    	process(CLK,RST)
    	begin
    		if RST = '1' then
    			table_index <= 0;
    			table_index_down <= '0';
    			dataout <= to_unsigned(table(0),dataout'length);
    		elsif rising_edge(CLK) then 			
    			-- walking the table    
    			if table_index_down = '0' then -- walk up the table
    				if table_index < ROM_DEPTH-1 then
    					table_index <= table_index + 1;
    				else			
    					table_index_down <= '1';
    					table_index      <= table_index;
    				end if;
    			else                           -- walk down the table
    				if table_index > 0 then			
    					table_index <= table_index - 1;
    				else
    					table_index_down <= '0';
    					table_index      <= table_index;
    				end if;
    			end if;
    		dataout <= to_unsigned(table(table_index),dataout'length);				        	
    		end if;
    	end process;
    
    	-- Output of the SignalGenerator.
    	WAVE_GEN <= std_logic_vector (dataout);
    
    
    end Behavioral;
    I used Matlab to design a low pass filter (see pic1 and pic2 attached)

    I converted the fixed point coefficients into Q7 format

    0.15939331054688 @ Q7 = 0x14
    0.38282775878906 @ Q7 = 0x31
    0.38282775878906 @ Q7 = 0x31
    0.15939331054688 @ Q7 = 0x14

    This is the code of the 4 order FIR VHDL filter:

    Code:
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    -- Uncomment the following library declaration if using
    -- arithmetic functions with UNSIGNED or UnUNSIGNED values
    use IEEE.NUMERIC_STD.ALL;
    use ieee.std_logic_unsigned.all; --unsigned arithmetics library 
    use ieee.std_logic_signed.all; --unsigned arithmetics library
    
    -- Uncomment the following library declaration if instantiating
    -- any Xilinx leaf cells in this code.
    --library UNISIM;
    --use UNISIM.VComponents.all;
    
    entity FIR_FILTER_N2 is
        Generic ( DEBUG   : BOOLEAN  := false);              -- True for simulations		      
        Port ( CLK        : in STD_LOGIC;
               RST        : in STD_LOGIC;
               FILTER_IN  : in STD_LOGIC_VECTOR (15 downto 0);
               FILTER_OUT : out STD_LOGIC_VECTOR (15 downto 0));
    end FIR_FILTER_N2;
    
    architecture Behavioral of FIR_FILTER_N2 is
    
    -- FIR coefficients.
    type FIR_COEFF is array (0 to 3) of signed (7 downto 0); 
    signal B : FIR_COEFF;
    
    -- Multiplication signals
    type X_ARRAY is array (0 to 3) of signed (15 downto 0); 
    signal X : X_ARRAY;
    type W_ARRAY is array (0 to 3) of signed (31 downto 0); 
    signal W : W_ARRAY;
    signal Y : signed (15 downto 0);
    
    -- FIR signals.
    type MUL_ARRAY is array (0 to 3) of signed (31 downto 0); 
    signal MUL : MUL_ARRAY;
    
    signal TAP_CNT : unsigned (7 downto 0);
    signal Z1 : signed (31 downto 0);
    signal Z2 : signed (31 downto 0);
    signal Z3 : signed (31 downto 0);
    signal ADD1 : signed (31 downto 0);
    signal ADD2 : signed (31 downto 0);
    signal ADD3 : signed (31 downto 0);
    
    begin
    
    ----------------------Low pass filter 6kHz --> 12kHz -12 dB-----------------
    -- Coefficients assigments
    -- B(0) <=  "11110111";
    -- B(1) <=  "00001001";
    -- B(2) <=  "00100110";
    -- B(3) <=  "00110011";
    
    B(0) <=  x"14";
    B(1) <=  x"31";
    B(2) <=  x"31";
    B(3) <=  x"14";
    
    --Multiplication
    gen_MULT16x16 : for I in 0 to 3 generate
    	X(I) <= resize(B(I), X(I)'length);
    	Y <= signed(FILTER_IN);
    	i_MUL16x16: entity work.MUL16x16
    		port map (	
    			CLK      => CLK,
    			X        => X(I),
    			Y        => Y,
    			W        => W(I)
    		);    
    	MUL(I)<=W(I);
    end generate gen_MULT16x16;
    
    process (RST,CLK)
    begin
    	if RST = '1' then
    		TAP_CNT <= (others => '0');		
    	elsif rising_edge (CLK) then
    		if TAP_CNT = 0 then
    			Z1 <= MUL(3);
    			TAP_CNT	<= TAP_CNT + 1;
    		elsif TAP_CNT = 1 then
    			ADD1 <= Z1 + MUL(2);
    			TAP_CNT	<= TAP_CNT + 1;
    		elsif TAP_CNT = 2 then
    			Z2 <= ADD1;
    			TAP_CNT	<= TAP_CNT + 1;
    		elsif TAP_CNT = 3 then			
    			ADD2 <= Z2 + MUL(1);
    			TAP_CNT	<= TAP_CNT + 1;
    		elsif TAP_CNT = 4 then						
    			Z3 <= ADD2;
    			TAP_CNT	<= TAP_CNT + 1;
    		elsif TAP_CNT = 5 then									
    			ADD3 <= Z3 + MUL(0);
    			TAP_CNT <= (others => '0');		
    		end if;				
    	end if;
    end process;
    
    FILTER_OUT <= std_logic_vector(resize(ADD3,FILTER_OUT'length));
    
    end Behavioral;
    After running the simulations in modelsim I always get a noisy output of the FIR filter for all the frequencies configured for the sinusoidal signal generated by the WaveGenerator.vhdl module (See pic3 with InputFreq=3.3MHz and pic4 with InputFreq=500KHz)

    Anyone can tell me why is happening this issue??

    Thanks in advance.

  2. #2
    Super Moderator
    Points: 47,675, Level: 53
    Awards:
    Most Frequent Poster

    Join Date
    Apr 2014
    Posts
    9,739
    Helped
    2347 / 2347
    Points
    47,675
    Level
    53

    Re: Manually implementation of a FIR filter in a FPGA.

    Hi,

    I didn´t go through your code in detail.

    But it looks like some overflow.
    This may be caused
    * either because of the FIR filter internal sum is too large (you may need some bits headroom)
    * or because of the FIR filter characteristic. This may cause some frequencies to be emphasised, which need some additional headroom
    * or because of signed/unsigend problems. You say 0...65535 this is unsigned. But the FIR filter may expect signed: -32768 ...0 ...+32767.

    I´d say the signed/unsigned problem is most likely.
    Check on this.

    After that:
    Try with reduced input amplitude ( at least 1/4) and see what happens.

    Klaus



  3. #3
    Super Moderator
    Points: 27,178, Level: 40
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    6,174
    Helped
    1518 / 1518
    Points
    27,178
    Level
    40

    Re: Manually implementation of a FIR filter in a FPGA.

    Code:
    FILTER_OUT <= std_logic_vector(resize(ADD3,FILTER_OUT'length));
    I'm pretty sure this this line drops the 16 most significant bits of the ADD3 signed vector.

    I would check the entire 32-bit ADD3 output first and see how many of the important bits you dropped.



    •   Alt15th March 2017, 00:21

      advertising

        
       

  4. #4
    Advanced Member level 3
    Points: 4,416, Level: 15

    Join Date
    Feb 2015
    Posts
    728
    Helped
    217 / 217
    Points
    4,416
    Level
    15

    Re: Manually implementation of a FIR filter in a FPGA.

    wave generator seems to only use the upper two quadrants, at least from looking at the process.

    I'm not sure on mul16x16, what inputs/outputs are signed/unsigned.

    The fir filter is also odd because the input seems to be accepted every cycle, but there is a sequential fsm for the accumulation.



  5. #5
    Full Member level 4
    Points: 1,734, Level: 9

    Join Date
    Jan 2014
    Posts
    234
    Helped
    1 / 1
    Points
    1,734
    Level
    9

    Re: Manually implementation of a FIR filter in a FPGA.

    Hello guys!

    First of all thank you for the quick answer.

    I have been doing some tests more and I would like to do some comments respecting to that...

    1) Without touching the original code which I posted before, I run a simulation displaying the ADD3 waveform (See pic1 attached). On pic1 it is possible to see how the ADD3 waveform is a square signal!!!!!!! And definitely this is not normal...The noisy Filter Out signal is also a square signal and noise it is bacause a problem with the "resize" function...Notice that the input freq of the filter = 500KHz....

    The code of the Mul16x16 is this:

    Code:
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    -- Uncomment the following library declaration if using
    -- arithmetic functions with UNSIGNED or UnUNSIGNED values
    use IEEE.NUMERIC_STD.ALL;
    use ieee.std_logic_unsigned.all; --unsigned arithmetics library 
    use ieee.std_logic_signed.all; --unsigned arithmetics library
    
    
    -- Uncomment the following library declaration if instantiating
    -- any Xilinx leaf cells in this code.
    --library UNISIM;
    --use UNISIM.VComponents.all;
    
    entity MUL16x16 is    
        Port ( 
    		CLK      :in STD_LOGIC;
    		X        :in  SIGNED (15 downto 0);
            Y        :in  SIGNED (15 downto 0);
            W        :out SIGNED (31 downto 0)        
        );
    end MUL16x16;
    
    architecture Behavioral of MUL16x16 is
    
    signal W_AUX : SIGNED (31 downto 0);
    
    begin
    
    W_AUX <= X*Y;
    
    process(CLK)
    begin
    	if rising_edge (CLK) then
    		W <= W_AUX;
    	end if;
    end process;
    
    end Behavioral;
    2) I modified the code of the wavegenerator.vhd module in order to create a sinusoidal signed signal between -32768 +32767 and I divided by "2" the output signal of the wavegenerator. And the resuts were a little weird: For an input filter freq = 500KHz the the signal looks nice in ADD3 ( See pic2 attached). However when the input filter freq = 3.3MHz, an attenuation of 30dB should be produced and the ADD3 signal keeps the same amplitude than before with 500KHz input signal (See pic3).

    The code of the wavegenerator is this:

    Code:
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    --use IEEE.STD_LOGIC_ARITH.all;
    --use ieee.std_logic_unsigned.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 WaveGenerator is
        Generic ( DEBUG     : BOOLEAN  := false;-- True for simulations
    	          ROM_DEPTH : INTEGER  := 100); -- Number of items of the ROM
        Port    ( CLK         : in STD_LOGIC;   -- Input Clock
                  RST         : in STD_LOGIC;   -- High level reset			  
                  WAVE_GEN    : out STD_LOGIC_VECTOR (15 downto 0)); -- Waveform data output
    end WaveGenerator;
    
    architecture Behavioral of WaveGenerator is
    
    -- Signals to generate the waveform
    signal dataout     : signed (15 downto 0);
    signal table_index       : integer range 0 to ROM_DEPTH;
    signal table_index_down  : std_logic; -- table_index_down = '1' => walk down the table; ='0' walk up the table
    
    --ROM for storing the table values generated by MATLAB for the 
    -- 1/4 of a sinus signal from 0 to 65536	 
    type table_type is array (0 to ROM_DEPTH-1) of integer range -32768 to 32767; 
    signal table : table_type :=(
         -32767,-32751,-32702,-32622,-32509,-32364,-32187,-31978,-31738,-31466,
    	 -31163,-30830,-30466,-30072,-29648,-29196,-28714,-28204,-27666,-27101,
    	 -26509,-25891,-25247,-24579,-23886,-23170,-22431,-21669,-20886,-20083,
    	 -19260,-18418,-17557,-16680,-15786,-14876,-13952,-13013,-12062,-11099,
    	 -10126,-9142 ,-8149 ,-7148 ,-6140 ,-5126 ,-4107 ,-3084 ,-2057 ,-1029 ,
    	 0     ,1029  ,2057  ,3084  ,4107  ,5126  ,6140  ,7148  ,8149  ,9142  ,
    	 10126 ,11099 ,12062 ,13013 ,13952 ,14876 ,15786 ,16680 ,17557 ,18418 ,
    	 19260 ,20083 ,20886 ,21669 ,22431 ,23170 ,23886 ,24579 ,25247 ,25891 ,
    	 26509 ,27101 ,27666 ,28204 ,28714 ,29196 ,29648 ,30072 ,30466 ,30830 ,
    	 31163 ,31466 ,31738 ,31978 ,32187 ,32364 ,32509 ,32622 ,32702 ,32751 	
    	 );	
    
    	 
    begin
    	
    	--Process to generate the signal
    	process(CLK,RST)
    	begin
    		if RST = '1' then
    			table_index <= 0;
    			table_index_down <= '0';
    			dataout <= to_signed(table(0),dataout'length)/2;
    		elsif rising_edge(CLK) then 			
    			-- walking the table    
    			if table_index_down = '0' then -- walk up the table
    				if table_index < ROM_DEPTH-1 then
    					table_index <= table_index + 1;
    				else			
    					table_index_down <= '1';
    					table_index      <= table_index;
    				end if;
    			else                           -- walk down the table
    				if table_index > 0 then			
    					table_index <= table_index - 1;
    				else
    					table_index_down <= '0';
    					table_index      <= table_index;
    				end if;
    			end if;
    		dataout <= to_signed(table(table_index),dataout'length)/2;				        	
    		end if;
    	end process;
    
    	-- Output of the SignalGenerator.
    	WAVE_GEN <= std_logic_vector (dataout);
    
    
    end Behavioral;

    On this point I have two questions:

    1) Any idea why the FIR filter does not attenuate the amplitude of the input signal? Could be an error in the calculation of the FIR coefficients?
    2) How to design a FIR filter with only posititive input values?

    Greetings,

    EP

    Click image for larger version. 

Name:	pic1.jpg 
Views:	8 
Size:	189.6 KB 
ID:	136958Click image for larger version. 

Name:	pic2.jpg 
Views:	5 
Size:	210.1 KB 
ID:	136959Click image for larger version. 

Name:	pic3.jpg 
Views:	4 
Size:	209.1 KB 
ID:	136960



  6. #6
    Super Moderator
    Points: 47,675, Level: 53
    Awards:
    Most Frequent Poster

    Join Date
    Apr 2014
    Posts
    9,739
    Helped
    2347 / 2347
    Points
    47,675
    Level
    53

    Re: Manually implementation of a FIR filter in a FPGA.

    Hi,

    1) Any idea why the FIR filter does not attenuate the amplitude of the input signal? Could be an error in the calculation of the FIR coefficients?
    usually for two different frequencies you need two different sine tables.
    My assumption is:
    That you just modified the data_rate for the sine generation and used the same sine table.
    If you then used the same (modified) data rate for the FIR filer, then it should be obvious that there is no change in amplitide. The FIR filter then calculates with the same values but faster.


    2) How to design a FIR filter with only posititive input values?
    Why?
    Why make handstands?
    Why make it "non standard"?
    --> if you need more resolution than adjust bit width.

    The next is:
    For a low pass filter this may theoretically work, but for a high pass filter or a band pass filter this simply can´t work, because the output will always go negative.

    Klaus



  7. #7
    Full Member level 4
    Points: 1,734, Level: 9

    Join Date
    Jan 2014
    Posts
    234
    Helped
    1 / 1
    Points
    1,734
    Level
    9

    Re: Manually implementation of a FIR filter in a FPGA.

    Hi KlausST

    You are right, I am using the same sine table and what I change is the clock frequency to increase or decrease the speed reading of the table...So I increase/decrease the data rate, right. But then if I want to simulate this FIR filter with this wavegenerator.vhd module, i need to create a new script in Matlab in order to estimate new values for the sine signal...

    This is the matlab script to generate 100 samples of a sine signal:

    Code:
    N=100;
    fs=200;
    f=1;
    ts=1/fs;
    t = ts*(0:N-1);
    x=0;
    x=(((2^16)/2)-1)*sin(2*pi*f*t-pi/2);
    x=(((2^16)/2)-1)+x;
    x=round(x);
    filename = 'SinusSignal.xlsx'
    xlswrite(filename,x);
    plot(t,x)
    This script gives you 100 samples of a 1/4 of the sine signal. Then you can estimate the rest of the sine signal (see wavegenerator.vhd).
    As you can see, the Fs=200 (Hz). Thefore according to the coefficients, the Fc=3MHZ, this sine signal always go trhough the FIR without any attenuation...The question is how to generate 100 samples of a sine signal with Matlab in order to simulate an attenuated sine signal after go through the FIR filter?

    Thanks in advance.



    •   Alt15th March 2017, 10:22

      advertising

        
       

  8. #8
    Super Moderator
    Points: 47,675, Level: 53
    Awards:
    Most Frequent Poster

    Join Date
    Apr 2014
    Posts
    9,739
    Helped
    2347 / 2347
    Points
    47,675
    Level
    53

    Re: Manually implementation of a FIR filter in a FPGA.

    Hi,

    if the current 100 point sine solution equals a 500kHz signal,

    then you should produce a sine table with 15 entries per sine --> 3.333MHz

    or 6 full waves within 91 entries. --> 3.297 MHz

    Klaus



    •   Alt15th March 2017, 10:49

      advertising

        
       

  9. #9
    Full Member level 2
    Points: 3,558, Level: 14

    Join Date
    May 2001
    Posts
    136
    Helped
    8 / 8
    Points
    3,558
    Level
    14

    Re: Manually implementation of a FIR filter in a FPGA.

    Hi,
    you can try open cores DDS sinthesyzers to generate the input frequency, in this way you can easily change frequency or sweep it.

    Stefano



  10. #10
    Full Member level 4
    Points: 1,734, Level: 9

    Join Date
    Jan 2014
    Posts
    234
    Helped
    1 / 1
    Points
    1,734
    Level
    9

    Re: Manually implementation of a FIR filter in a FPGA.

    @mvmmmboy: That could be a good option. I will try it if I am not able to run my own wavegenerator...

    @KlausST: I am not able to attenuate the incomming signal to the filter. Maybe I am doing something wrong. I will describe you the scenario:

    1) I generate a sinu signal of 1MHz with the next Matlab code.

    Code:
    N=50;
    fs=100e6;
    f=1e6;
    ts=1/fs;
    t = ts*(0:N-1);
    x=0;
    x=(((2^16)/2)-1)*sin(2*pi*f*t-pi/2);
    x=round(x);
    filename = 'SinusSignal_1M.xlsx'
    xlswrite(filename,x);
    plot(t,x)
    2) I generate a sinu signal of 1MHz with the next Matlab code.

    Code:
    N=4;
    fs=100e6;
    f=15.5e6;
    ts=1/fs;
    t = ts*(0:N-1);
    x=0;
    x=(((2^16)/2)-1)*sin(2*pi*f*t-pi/2);
    x=round(x);
    filename = 'SinusSignal_15M5.xlsx'
    xlswrite(filename,x);
    plot(t,x)
    3) I model a LP FIR filter (See pic1 and pic2 attached)
    Click image for larger version. 

Name:	FilterCoefficients.jpg 
Views:	0 
Size:	68.9 KB 
ID:	137178Click image for larger version. 

Name:	FilterMatlab.jpg 
Views:	1 
Size:	144.8 KB 
ID:	137179

    4) I convert the coefficients into Q7 format:

    0.34989364024691172 @ Q7=0x2D
    0.12031844969512598 @ Q7=0x0F
    0.12031844969512598 @ Q7=0x0F
    0.34989364024691172 @ Q7=0x2D

    5) I use the FIR filter code showed above in my first post to filter out the sinus signal

    6) The results are

    6.1) 1MHz sinus signal ==> No attenuation and there is also an amplification!!! (See pic3 attached)

    Click image for larger version. 

Name:	pic3.jpg 
Views:	3 
Size:	275.5 KB 
ID:	137180

    6.2) 15.5MHz sinus signal ==> No attenuation and there is also an amplification!!! (See pic4 attached)

    Click image for larger version. 

Name:	pic4.jpg 
Views:	2 
Size:	257.2 KB 
ID:	137181

    Could it be that there is an error in the filter design with Matlab?? Because I think that the 4 FIR tap VHDL implementation is ok right?

    Thanks in advance!!!



  11. #11
    Super Moderator
    Points: 233,774, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    40,388
    Helped
    12337 / 12337
    Points
    233,774
    Level
    100

    Re: Manually implementation of a FIR filter in a FPGA.

    According to the wave window, the sine frequencies are not 1 MHz and 15 MHz.

    Apparently you still don't manage to scale ADD3 into FILTER_OUT, respectively to display the data with correct number format.



  12. #12
    Super Moderator
    Points: 27,178, Level: 40
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    6,174
    Helped
    1518 / 1518
    Points
    27,178
    Level
    40

    Re: Manually implementation of a FIR filter in a FPGA.

    Quote Originally Posted by FvM View Post
    Apparently you still don't manage to scale ADD3 into FILTER_OUT, respectively to display the data with correct number format.
    This means you need to be taking the UPPER bits not the lower bits of ADD3 and assign them to FILTER_OUT, don't use resize, grab the correct bit slice directly, resize won't work correctly it grabs the lower bits.

    probably something more like:
    Code:
    FILTER_OUT <= ADD3(ADD3'LEFT downto (ADD3'LEFT-FILTER_OUT'LENGTH+1));
    Though I may be remembering the wrong attribute names.



  13. #13
    Full Member level 4
    Points: 1,734, Level: 9

    Join Date
    Jan 2014
    Posts
    234
    Helped
    1 / 1
    Points
    1,734
    Level
    9

    Re: Manually implementation of a FIR filter in a FPGA.

    Hi FvM,
    I am delivering samples of the sinus signal at 50MHz (input clock of the WaveGenerator.vhd). But i created it with MATLAB with a sample frequency of 100MHz. It means the input clock of the WaveGenerator.vhd should be set to 100MHz to create sinus signal at 1MHz and 15.5MHz right?
    Regards,

    - - - Updated - - -

    Hi ads-see

    I will try it tomorrow. Maybe this is the reason because the amplitude of the output signal looks like a gain....

    Thanks!!



  14. #14
    Advanced Member level 3
    Points: 4,416, Level: 15

    Join Date
    Feb 2015
    Posts
    728
    Helped
    217 / 217
    Points
    4,416
    Level
    15

    Re: Manually implementation of a FIR filter in a FPGA.

    resize, for signed in numeric_std, will take the msb and then the N-1 lsbs in this case. This is why the waveform looks like a bunch of random positive values then a bunch of random negative values.

    In terms of the design, nearly everything is wrong.

    the wave generator is listed for "quarter sine" but is actually a half sine.

    you do the parallel multiplications, then have a serial accumulator that runs at half rate. you probably want the adder tree.

    You select the lsbs for some reason.

    You freely have 16x16 multipliers (probably larger) in the FPGA, but you quantize the coefficients to 8 bit.

    You should be using a easier test signal -- an impulse. you should see the 4 coefficients as the output by definition. You should also try a worst case full scale signal of (-fullscale, -fullscale, -fullscale, -fullscale) Basically, values of -fullscale for positive coefs and +fullscale for negative. The goal is to ensure the accumulator can't overflow.



    •   Alt22nd March 2017, 04:16

      advertising

        
       

  15. #15
    Super Moderator
    Points: 233,774, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    40,388
    Helped
    12337 / 12337
    Points
    233,774
    Level
    100

    Re: Manually implementation of a FIR filter in a FPGA.

    It means the input clock of the WaveGenerator.vhd should be set to 100MHz to create sinus signal at 1MHz and 15.5MHz right?
    It didn't consider what the frequency should be, just looked at the waveform.



  16. #16
    Full Member level 4
    Points: 1,734, Level: 9

    Join Date
    Jan 2014
    Posts
    234
    Helped
    1 / 1
    Points
    1,734
    Level
    9

    Re: Manually implementation of a FIR filter in a FPGA.

    Ok guys I think that I am already get it....

    You were right FvM, I set the frequency of the WaveGenerator.vhd to run the sinus signals at 1MHz and 15.5MHz and see the pics attached to observe what happens.

    Pic1 => Sinus signal running at 1MHz ==> No attenuation, everything ok.

    Click image for larger version. 

Name:	pic1.jpg 
Views:	2 
Size:	299.1 KB 
ID:	137203

    Pic2 => Sinus signal running at 15.5MHz ==> The signal is totally degraded and there is a phase shift of 90º!!! Can anybody explain why this is happening??

    Click image for larger version. 

Name:	pic2.jpg 
Views:	2 
Size:	297.5 KB 
ID:	137204

    Thanks at all!



  17. #17
    Super Moderator
    Points: 233,774, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    40,388
    Helped
    12337 / 12337
    Points
    233,774
    Level
    100

    Re: Manually implementation of a FIR filter in a FPGA.

    Still have difficulties to match the generator and filter sampling rates seen in the waveform with the design specifications.

    Apparently the filter is running at a lower rate as the generator, ratio is 5:16. Having only 5 samples per sine period doesn't look very nice, as expectable.



--[[ ]]--