Forum Discussion

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

To high result, serial fir filter VHDL

Hey, I'm beginner at VHDL and I have a problem with my serial fir filter with LUT:

LUT table: not all


library ieee;
 use ieee.std_logic_1164.all;
 use ieee.std_logic_arith.all;
 entity lut_table is
 port(     
       x0,x1,x2,x3,x4,x5,x6,x7,x8  : in std_logic;
       table_out : out std_logic_vector(13 downto 0)
 ); 
end lut_table; 
architecture arch of lut_table is 
 signal table_in : std_logic_vector( 8 downto 0);
 begin 
 table_in <= x8 & x7 & x6 & x5 & x4 & x3 & x2 & x1 & x0;  
 with table_in select        
        table_out <= "00000000000000" when "000000000",     
                            "00000001101110" when "000000001",    
                            "11111110111011" when "000000010",     
                            "00000000101001" when "000000011",    
                            "11111011000000" when "000000100",     
                            "11111100101110" when "000000101",     
                            "11111001111011" when "000000110",    
                            "11111011101001" when "000000111",     
                            "00010001000101" when "000001000",     
                            "00010010110011" when "000001001",    
                            "00010000000000" when "000001010",     
                            "00010001101110" when "000001011",
                            etc.
end arch.

Main unit:


library ieee;
 use ieee.std_logic_1164.all;
 use ieee.numeric_std.all;
 use ieee.math_real.all;
 entity filtr_fir_da is  
port (  
clk, rst      : in std_logic;
 data_in     : in std_logic_vector(7 downto 0);
 data_out   : out std_logic_vector(27 downto 0) 
); 
end filtr_fir_da;  
architecture arch of filtr_fir_da is  
signal acc_reg, acc_next                                : signed(27 downto 0);
 signal data_out_reg,data_out_next                 : signed(27 downto 0); 
signal tableout                                              : std_logic_vector(13 downto 0);
 signal adress_reg, adress_next                      : unsigned (3 downto 0);
 signal d0_reg,d1_reg,d2_reg,d3_reg,d4_reg,d5_reg,d6_reg,d7_reg,d8_reg            : std_logic; 
signal d0_next,d1_next,d2_next,d3_next,d4_next,d5_next,d6_next,d7_next,d8_next : std_logic;   
type x_table is array (0 to 8) of std_logic_vector(7 downto 0); 
signal datat_reg,datat_next                                                                                          : x_table; 
 type STYPE is (load,count,result);
 signal state_reg, state_next : STYPE; 
 component lut_table port(   
             x0,x1,x2,x3,x4,x5,x6,x7,x8 : in std_logic;
             table_out : out std_logic_vector(13 downto 0) 
  );
 end component;  
 begin  
lut: lut_table port map(    
         x0 => d0_reg,x1 => d1_reg,x2 => d2_reg,x3 => d3_reg,x4 => d4_reg,x5 => d5_reg,x6 => d6_reg,x7 => d7_reg,x8 => d8_reg,
         table_out => tableout 
);  
process(rst,clk)
 begin    
       if rst = '1' then        
          state_reg <= load; 
      elsif rising_edge(clk) then       
         state_reg <= state_next;    
end if; end process;  
 process(rst, clk) 
begin
        if rst = '1' then        
          adress_reg <= "0000";        
          data_out_reg <= (others => '0');      
          acc_reg <= (others => '0');       
          datat_reg <= (others => (others => '0'));       
          d0_reg <= '0'; d1_reg <= '0'; d2_reg <= '0'; d3_reg <= '0'; d4_reg <= '0'; d5_reg <= '0'; d6_reg <= '0'; d7_reg <= '0'; d8_reg <= '0';    
    elsif rising_edge(clk) then
         adress_reg <= adress_next;         
        acc_reg <= acc_next;       
        data_out_reg <= data_out_next;       
        datat_reg <= datat_next;     
        d0_reg <= d0_next;d1_reg <= d1_next;d2_reg <= d2_next;d3_reg <= d3_next;d4_reg <= d4_next;d5_reg <= d5_next;d6_reg <= d6_next;d7_reg <= d7_next;d8_reg <=d8_next;    
   end if;
 end process; 
 process(state_reg,adress_reg,data_out_reg,d0_reg,d1_reg,d2_reg,d3_reg,d4_reg,d5_reg,d6_reg,d7_reg,d8_reg,acc_reg,datat_reg,datat_next,tableout,data_in)
  begin 
      state_next <= state_reg; 
      adress_next <= adress_reg;
      acc_next <= acc_reg;
      data_out_next <= data_out_reg;
      datat_next <= datat_reg;
      d0_next <= d0_reg;d1_next <= d1_reg;d2_next <= d2_reg;d3_next <= d3_reg;d4_next <= d4_reg;d5_next <= d5_reg;d6_next <= d6_reg;d7_next <= d7_reg;d8_next <= d8_reg;
case state_reg is
        when load =>          
                datat_next(8) <= datat_reg(7);  
                datat_next(7) <= datat_reg(6);     
                datat_next(6) <= datat_reg(5);        
                datat_next(5) <= datat_reg(4);        
                datat_next(4) <= datat_reg(3);          
                datat_next(3) <= datat_reg(2);        
                datat_next(2) <= datat_reg(1);          
                datat_next(1) <= datat_reg(0);           
                datat_next(0) <= data_in;            
                state_next <= count;          
  
      when count =>        
               if adress_reg < "0111" then            
                  d0_next <= datat_reg(0)(to_integer(adress_reg)); 
                  d1_next <= datat_reg(1)(to_integer(adress_reg));   
                  d2_next <= datat_reg(2)(to_integer(adress_reg));   
                  d3_next <= datat_reg(3)(to_integer(adress_reg));        
                  d4_next <= datat_reg(4)(to_integer(adress_reg));        
                  d5_next <= datat_reg(5)(to_integer(adress_reg));    
                  d6_next <= datat_reg(6)(to_integer(adress_reg));     
                  d7_next <= datat_reg(7)(to_integer(adress_reg));          
                  d8_next <= datat_reg(8)(to_integer(adress_reg));       
                  acc_next <= (shift_left(signed(tableout),to_integer(adress_reg))) + acc_reg;   
                  adress_next <= adress_reg + "0001";          
                   state_next <= count;        
             elsif adress_reg = "0111" then   
                 d0_next <= datat_reg(0)(to_integer(adress_reg));       
                 d1_next <= datat_reg(1)(to_integer(adress_reg));        
                 d2_next <= datat_reg(2)(to_integer(adress_reg));      
                 d3_next <= datat_reg(3)(to_integer(adress_reg));      
                 d4_next <= datat_reg(4)(to_integer(adress_reg));     
                 d5_next <= datat_reg(5)(to_integer(adress_reg));            
                 d6_next <= datat_reg(6)(to_integer(adress_reg));       
                 d7_next <= datat_reg(7)(to_integer(adress_reg));          
                 d8_next <= datat_reg(8)(to_integer(adress_reg));            
                 acc_next <=  -(shift_left(signed(tableout),to_integer(adress_reg))) + acc_reg;           
                 adress_next <= "0000";          
                 state_next <= result;         
            end if;        
        when result =>           
               data_out_next <= acc_reg;         
               state_next <= load;           
              acc_next <= (others => '0');   
 
       when others =>         
           state_next <= load;   
  end case;
 end process;  
            data_out    <= std_logic_vector(data_out_reg);
  end arch;

My scale coefficients are

[ 110,-69,-320,1093,2470,1093,-320,-69,110]

For example when input signal is

[1,0,0,0,0,0,0,0,0]

my system multiple the reuslt twice so the result is

[ 220,-138, -640, 2186, 4940, 2186, -640, -138, 220]

instead

[110, -69, -320, 1093, 2470, 1093, -320, -69, 110].

Anyone help ? I think there is something wrong with last cycle of count state, because the result is delayed 10 cycles of clock, so all system count the result badly but I don't know how I can repair it ;/

1 Reply