首页>>论坛 >>技术社区 >>OpenHW社区论坛 >>XUP板卡及板级硬件
|
我要发帖  | 我要投票  | 我要回复  | 收藏
1

帮我看看这个FIR滤波器的程序

版主: KiKi  玄剑  XUPteam  Pollux 
帮我看看这个FIR滤波器的程序
 

--24阶滤波器设?

LIBRARY ieee;
USE ieee.std_logic_1164.all;
Use ieee.std_logic_arith.all;
Use ieee.std_logic_unsigned.all;

library lpm;
USE lpm.lpm_components.ALL;

ENTITY wyhzy IS
 PORT( 
      clk   :IN  STD_LOGIC;                       --主时钟
      clk_en:IN  STD_LOGIC;                       --使能时钟   
         RST   :In  STD_LOGIC;                       --复位信号
      h_Temp:out  STD_LOGIC_vector(15 DOWNTO 0);   --输入信号
      x_Temp:out  STD_LOGIC_vector(15 DOWNTO 0);   --输入信号
      xiTemp:out  integer range 0 to 31;
      yTemp :out  STD_LOGIC_vector(31 DOWNTO 0);   --输入信号
         MTemp :out  STD_LOGIC_VECTOR(31 downto 0);

         y_out :OUT STD_LOGIC_vector(15 DOWNTO 0)    --滤波后的输出     
      );
end wyhzy;

ARCHITECTURE a of wyhzy IS
    
     component lpm_mult
  GENERIC (LPM_WIDTHA: POSITIVE;
     LPM_WIDTHB: POSITIVE;
     LPM_WIDTHP: POSITIVE;
               LPM_REPRESENTATION: STRING := "SIGNED" 
                 );
     PORT (
            dataa: IN STD_LOGIC_VECTOR(LPM_WIDTHA-1 DOWNTO 0);
               datab: IN STD_LOGIC_VECTOR(LPM_WIDTHB-1 DOWNTO 0);
               result: OUT STD_LOGIC_VECTOR(LPM_WIDTHP-1 DOWNTO 0)
           );
     END COMPONENT;


    component firram24 IS
 PORT
 (
  address  : IN STD_LOGIC_VECTOR (4 DOWNTO 0); 
  clock  : IN STD_LOGIC ;
  data  : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
  wren  : IN STD_LOGIC ;
  q      : OUT STD_LOGIC_VECTOR (15 DOWNTO 0)
 );
 end  component;

 component firrom24 IS
 PORT
 (
  address  : IN STD_LOGIC_VECTOR (4 DOWNTO 0); 
  clock  : IN STD_LOGIC ;
  q      : OUT STD_LOGIC_VECTOR (15 DOWNTO 0)
 );
 end  component;

  
  signal x1_in: STD_LOGIC_vector(15 DOWNTO 0);  
  signal xaddr: std_logic_vector(4 downto 0);          
  signal xout : std_logic_vector(15 DOWNTO 0);          
  signal datain: std_logic_vector(15 DOWNTO 0);
  signal xdata,x: STD_LOGIC_VECTOR(15 DOWNTO 0);
  signal h      : STD_LOGIC_VECTOR(15 downto 0);

  signal hdata: STD_LOGIC_VECTOR(15 downto 0);
  signal haddr  : STD_LOGIC_VECTOR(4  downto 0);

  signal Dataout: STD_LOGIC_VECTOR(31 downto 0);
  signal MulData: STD_LOGIC_VECTOR(31 downto 0);

  signal y      : STD_LOGIC_VECTOR(31 downto 0);
  shared variable yy      : STD_LOGIC_VECTOR(31 downto 0);
  signal hout   : STD_LOGIC_VECTOR(15 downto 0);
 
  signal countclk : integer range 0 to 31;
  signal xidx,xidxtemp: integer range 0 to 31;
  signal weable  : STD_LOGIC;

  type   xsinvec is array(15 downto 0) of STD_LOGIC_VECTOR(15 downto 0);
  signal xsin    : xsinvec;
  signal xsinidx : integer range 0 to 15;

begin


    Ramzz :firram24
    Port MAP(
                address  => xaddr,
                clock    => clk,
                data     => datain,
                wren     => weable, 
                q        => xout              
            ); 

    
    multiper : lpm_mult  
        GENERIC MAP(
                     LPM_WIDTHA => 16,
                     LPM_WIDTHB => 16,
                     LPM_WIDTHP => 32
                    )
        PORT MAP(  
                    dataa  => xdata,    --数据
                    datab  => hdata,    --系数
                    result => DataOut
                );

   --系数表
 coeef :firrom24
 PORT MAP ( clock => clk,
               address => haddr,
          q => hout);
-----------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------

 read:process(clk)                    --在下降沿把数据读进来      
 begin
     if clk='0' and clk'Event then      
     if clk_en='1' then
 
       if countclk=10 then
          x1_in   <= xsin(xsinidx);
          xsinidx <= xsinidx + 1;
       end if;
      
    end if;
 end if;
 end process read;
 
   
   Process(RST,clk)                       --滤波器的计算过程            
   begin
      if RST='0' then
         y_out<="0000000000000000";
  
         xsin(0) <= "0000000000000000";
         xsin(1) <= "0011000011111011";
         xsin(2) <= "0101101010000001";
         xsin(3) <= "0111011001000000";
         xsin(4) <= "0111111111111111"; 
         xsin(5) <= "0111011001000000";
         xsin(6) <= "0101101010000001";
         xsin(7) <= "0011000011111011";
         xsin(8) <= "0000000000000000";
         xsin(9) <= "1100111100000101";--CF05H;
         xsin(10)<= "1010010101111111";--A57FH; 
         xsin(11)<= "1000100111000000";--89C0H; 
         xsin(12)<= "1000000000000001";--8001H;
         xsin(13)<= "1000100111000000";--89C0H;
         xsin(14)<= "1010010101111111";--A57FH;
         xsin(15)<= "1100111100000101";--CF05H;
         --xsin(16)<= "0000000000000000";
         --xsinidx <= 0;
         xidx    <= 0;

      elsif clk='1' and clk'event then
      if clk_en='1' then
        
         x<=xout;                        
         h<=hout;   
   
         countclk<=countclk+1;
 
         if countclk=0 then

              y_out<=y(31 downto 16);   
              y<="00000000000000000000000000000000";
                          
           --数据存储
            xaddr <= conv_std_logic_vector(xidx,5); --先把预置好 即使改写了也没有关系
     datain<= x1_in;            
            weable<='1';                            --允许写!     

         elsif countclk=1 then
            xaddr <= conv_std_logic_vector(xidx,5);
              weable<='1';                           

         elsif countclk=2 then               
              weable<='0';                            --允许数据读
              xidxtemp <=xidx;
              if(xidx<23) then                      
                 xidx<=xidx + 1;
              else
                 xidx<=0;                             --地址索引改变            
              end if;
-----------------------------------------------------------------------------------------------------------
--开始计算
         elsif countclk=3 then                       
              xaddr<= conv_std_logic_vector(xidxtemp,5);--地址随着时钟发生变化 3bits
     haddr<= conv_std_logic_vector(0,5);                              
              if(xidxtemp=0) then
                 xidxtemp<=23;             
              else
                 xidxtemp<=xidxtemp - 1;             
              end if;
           
         elsif countclk=4 then                --等待一个时钟 再开始计算
              xaddr<= conv_std_logic_vector(xidxtemp,5);--地址随着时钟发生变化 3bits
     haddr<= conv_std_logic_vector(1,5);                              
              if(xidxtemp=0) then
                 xidxtemp<=23;             
              else
                 xidxtemp<=xidxtemp - 1;                                
        end if;
        weable<='0';
  
         elsif countclk=5 then                --等待一个时钟 再开始计算
              xaddr<= conv_std_logic_vector(xidxtemp,5);--地址随着时钟发生变化 3bits
     haddr<= conv_std_logic_vector(2,5);                              
              if(xidxtemp=0) then
                 xidxtemp<=23;             
              else
                 xidxtemp<=xidxtemp - 1;             
              end if;
              
              xdata<=x;   
              hdata<=h;
              y<=y+MulData;                  

         elsif countclk=6 then                --等待一个时钟 再开始计算
              xaddr<= conv_std_logic_vector(xidxtemp,5);--地址随着时钟发生变化 3bits
     haddr<= conv_std_logic_vector(3,5);                              
              if(xidxtemp=0) then
                 xidxtemp<=23;             
              else
                 xidxtemp<=xidxtemp - 1;             
              end if;

              xdata<=x;   
              hdata<=h;
              y<=y+MulData;                  

         elsif countclk<27 then             

              xaddr<= conv_std_logic_vector(xidxtemp,  5);--地址随着时钟发生变化 3bits
     haddr<= conv_std_logic_vector(countclk-3,5);                              
              if(xidxtemp=0) then
                 xidxtemp<=23;             
              else
                 xidxtemp<=xidxtemp - 1;             
              end if;

              xdata<=x;   
              hdata<=h;
              y<=y+MulData;            

         elsif countclk<30 then                --等待一个时钟 再开始计算    
              xdata<=x;   
              hdata<=h;
              xaddr<="00000";
              haddr<="00000";
              y<=y+MulData; 

         else
              xaddr<="00000";
              haddr<="00000";
              xdata<="0000000000000000";   
              hdata<="0000000000000000";
         end if;    

      end if;  --clk_en
    end if;    --clk

  end process ;

  MulData  <= Dataout;
  x_Temp   <= x;
  h_Temp   <= h;
  xiTemp   <= xidx;
  yTemp    <= y;
  MTemp    <= MulData;
end a;

 

 

这个程序我在工程中编译通过了,但是其中一直要判断countclk这个是什么作用呢,能帮我注释一下吗?

 

 
相关主题
回复 链接 收藏
 
RE:帮我看看这个FIR滤波器的程序
 
countclk主要用于时序控制,其实和状态机中的状态转换差不多。因为在你的这个设计中,时序是顺序执行的,因此可以用一个计数器来控制,同样你在明白其执行过程的基础上,也可以将它改写为状态机来进行控制。
 
努力而已!
回复 链接 收藏
 
RE:帮我看看这个FIR滤波器的程序
 
恩,标记状态用的。
推荐使用状态机:)
 
Walkie
回复 链接 收藏
 
我要发帖  | 我要投票  | 我要回复  | 收藏
1