打印
[FPGA]

一种VHDL写的反余弦查表方法

[复制链接]
938|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
李永宏|  楼主 | 2016-3-22 11:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
library ieee;
USE IEEE.std_logic_1164.all;  --
USE IEEE.numeric_std.ALL;
USE IEEE.math_complex.ALL;
USE IEEE.math_real.ALL;
USE IEEE.numeric_bit.ALL;
USE IEEE.std_logic_unsigned.all;
USE IEEE.std_logic_signed.all;
USE IEEE.std_logic_arith.ALL; ---- --

entity P_ACOShalfup is
PORT(   
      
        clock0                            :   IN    std_logic;
        clk                               :   IN    std_logic;
        reset                             :   IN    std_logic;
        clk_enable                        :   IN    std_logic;
        sqrtin1                           :   IN    std_logic_vector(13 downto 0);
        sqrtin2                           :   IN    std_logic_vector(13 downto 0);
        alfaout                           :   OUT   std_logic_vector(15 downto 0)
       
    );
end P_ACOShalfup; --

architecture rtl of P_ACOShalfup is

SIGNAL q50KHZ                                   : std_logic;
SIGNAL input409upKHZ                            : std_logic;
SIGNAL input409downKHZ                          : std_logic;

SIGNAL switch_up                                : std_logic;
SIGNAL switch_down                              : std_logic;
SIGNAL q409K                                    : std_logic;

SIGNAL  uptbl_flag                              : std_logic:='0';
SIGNAL  downtbl_flag                            : std_logic:='0';

SIGNAL  Clear_halfupflag                        : std_logic:='0';
SIGNAL  Clear_halfdownflag                      : std_logic:='0';

SIGNAL  uptbl_addr                               : unsigned(13 downto 0):="00000000000000";
SIGNAL  downtbl_addr                             : unsigned(13 downto 0):="00000000000000";

SIGNAL  input_register1                          : signed(13 DOWNTO 0)  :="00000000000000";--
SIGNAL  buff_data                                : unsigned(15 downto 0):="0000000000000000";  --16bit max65535


SIGNAL  output_register                          : UNSIGNED(15 DOWNTO 0):="0000000000000000";--
SIGNAL  count_halfupwaveClock                    : UNSIGNED(13 DOWNTO 0):="00000000000000";   --**在上半波10ms内有多少个409KH脉冲
SIGNAL  count_halfdownwaveClock                  : UNSIGNED(13 DOWNTO 0):="00000000000000";   --**在下半波10ms内有多少个409KH脉冲

SIGNAL  datain                                   : signed(13 downto 0):="00000000000000";
SIGNAL  indatauA                                 : signed(13 downto 0):="00000000000000";
SIGNAL  indatauB                                 : signed(13 downto 0):="00000000000000";


begin
   
   input409upKHZ     <= switch_up AND q409K;
   input409downKHZ   <= switch_down AND q409K;
   
   ----------------------------------------
   q409KHZ:PROCESS(clock0)
   VARIABLE cout:integer:=0;
   BEGIN
   IF clock0'EVENT AND clock0='1' THEN
   cout:=cout+1;
   IF cout<=122 THEN
      q409K <= '0';
   ELSIF cout<244 THEN
      q409K <= '1';
    ELSE cout:=0;
   END IF;  
   END IF;
   END PROCESS q409KHZ;
   ----------------------------------------
   q50KH:PROCESS(clock0)
   VARIABLE cout:INTEGER:=0;
   BEGIN
   IF clock0'EVENT AND clock0='1' THEN
   cout:=cout+1;
   IF cout<=1000 THEN q50KHZ<='0';
   ELSIF cout<2000 THEN q50KHZ<='1';   ---2000 x 50KHz=100MHz
    ELSE cout:=0;
   END IF;  
   END IF;
   END PROCESS q50KH;
  
   ---------上半波对409KHz脉冲记数---------

   Pulse_upEstablish_Phase:PROCESS(input409upKHZ ,reset)     --  引入409KHZ

   BEGIN
        
        IF reset = '0' THEN

          count_halfupwaveClock <= "00000000000000";
         
          ELSIF input409upKHZ'event AND input409upKHZ = '1' THEN
              IF clk_enable = '1' THEN
                 count_halfupwaveClock <= count_halfupwaveClock+"00000000000001";  ---上半波来一个脉冲累加一个
              END IF;
        END IF;
        
        IF Clear_halfupflag = '1' THEN
           count_halfupwaveClock <= "00000000000000";
        END IF;
         
   END PROCESS Pulse_upEstablish_Phase;
---------下半波对409KHz脉冲记数---------

   Pulse_downEstablish_Phase:PROCESS(input409downKHZ ,reset)     --  引入409KHZ

   BEGIN
        
        IF reset = '0' THEN

          count_halfdownwaveClock <= "00000000000000";         
          ELSIF input409downKHZ'event AND input409downKHZ= '1' THEN
              IF clk_enable = '1' THEN
              count_halfdownwaveClock <= count_halfdownwaveClock+"00000000000001"; ---下半波来一个脉冲累加一个
              END IF;
        END IF;

        IF Clear_halfdownflag = '1' THEN
           count_halfdownwaveClock <= "00000000000000";
        END IF;
   END PROCESS Pulse_downEstablish_Phase;
  -------------------------------------------------------

  input_reg_process : PROCESS (q50KHZ, reset)               --  引入50KHZ

  VARIABLE ahead_up:integer    :=0;
  VARIABLE ahead_down:integer  :=0;
  VARIABLE fellow_up:integer   :=0;
  VARIABLE fellow_down:integer :=0;
  
  BEGIN
   
    IF reset = '0' THEN
          input_register1 <= "00000000000000";
          
    ELSIF q50KHZ'event AND q50KHZ = '1' THEN
      IF clk_enable = '1' THEN
             
          input_register1 <= datain;  
          
      END IF;
    END IF;
    ---------------------------------------------------
    if(input_register1>0)then
         switch_up <= '1';
         switch_down <= '0';
        
         Clear_halfdownflag <= '1';
         Clear_halfupflag <= '0';
         fellow_down := 0;
         ahead_down  := 0;

         fellow_up := CONV_INTEGER(datain);
          if(fellow_up /= ahead_up)then

            uptbl_flag <= '1';                                             
            uptbl_addr <= count_halfupwaveClock;                   ---获得查表地址
            ahead_up:= fellow_up;
          else
            uptbl_flag <= '0';
          end if;
    end if;
    ---------------------------------------------------
    if(input_register1<0)then
         switch_up <= '0';
         switch_down <= '1';
      
         Clear_halfupflag <= '1';
         Clear_halfdownflag <= '0';
         fellow_up := 0;
         ahead_up  := 0;

         fellow_down := CONV_INTEGER(datain);
          if(fellow_down /= ahead_down)then
            downtbl_flag <= '1';                                  ---上半波数据发生变化,置上半表查表标志              
            downtbl_addr <= count_halfdownwaveClock;              ---获得查表地址
            ahead_down:= fellow_down;
          else
            downtbl_flag <= '0';
          end if;
    end if;
  END PROCESS input_reg_process;
  
main:process(clk ,reset)
   VARIABLE UPVALUE,DOWNVALUE,result: INTEGER:=0;
  begin
  
   --------------------该段程序用于测试及查表调速---------------------------------------------------
   IF reset = '0' THEN                  
          datain  <= "00000000000000";  
    ELSIF clk'event AND clk = '1' THEN
      IF clk_enable = '1' THEN

            indatauA <= sqrtin1;
          indatauB <= sqrtin2;
                  
                  UPVALUE:=CONV_INTEGER(indatauA);
                  DOWNVALUE:=CONV_INTEGER(indatauB);
                  result:=UPVALUE/DOWNVALUE;
          --datain <= CONV_SIGNED(-1,14)*sqrtin3/sqrtin4;        ----   -ACOS(U1/U2)
              datain <= CONV_SIGNED(result,14);

      END IF;
    END IF;
  ----------------------该段结束------------------------------------------------------------------
    --------------查上表,4096个值,其后是查下表4096个值,合计8092个值---------------------------------
    if(uptbl_flag ='1')then
    case uptbl_addr  is
when CONV_UNSIGNED(1,14)=>buff_data<=CONV_UNSIGNED(47128,16);
when CONV_UNSIGNED(2,14)=>buff_data<=CONV_UNSIGNED(47133,16);
when CONV_UNSIGNED(3,14)=>buff_data<=CONV_UNSIGNED(47138,16);
when CONV_UNSIGNED(4,14)=>buff_data<=CONV_UNSIGNED(47143,16);
when CONV_UNSIGNED(5,14)=>buff_data<=CONV_UNSIGNED(47148,16);
when CONV_UNSIGNED(6,14)=>buff_data<=CONV_UNSIGNED(47153,16);
when CONV_UNSIGNED(7,14)=>buff_data<=CONV_UNSIGNED(47158,16);
when CONV_UNSIGNED(8,14)=>buff_data<=CONV_UNSIGNED(47162,16);
when CONV_UNSIGNED(9,14)=>buff_data<=CONV_UNSIGNED(47167,16);
when CONV_UNSIGNED(10,14)=>buff_data<=CONV_UNSIGNED(47172,16);
when CONV_UNSIGNED(11,14)=>buff_data<=CONV_UNSIGNED(47177,16);
when CONV_UNSIGNED(12,14)=>buff_data<=CONV_UNSIGNED(47182,16);
when CONV_UNSIGNED(13,14)=>buff_data<=CONV_UNSIGNED(47187,16);
when CONV_UNSIGNED(14,14)=>buff_data<=CONV_UNSIGNED(47192,16);
when CONV_UNSIGNED(15,14)=>buff_data<=CONV_UNSIGNED(47197,16);
when CONV_UNSIGNED(16,14)=>buff_data<=CONV_UNSIGNED(47202,16);
when CONV_UNSIGNED(17,14)=>buff_data<=CONV_UNSIGNED(47206,16);
when CONV_UNSIGNED(18,14)=>buff_data<=CONV_UNSIGNED(47211,16);
when CONV_UNSIGNED(19,14)=>buff_data<=CONV_UNSIGNED(47216,16);
when CONV_UNSIGNED(20,14)=>buff_data<=CONV_UNSIGNED(47221,16);
when CONV_UNSIGNED(21,14)=>buff_data<=CONV_UNSIGNED(47226,16);
when CONV_UNSIGNED(22,14)=>buff_data<=CONV_UNSIGNED(47231,16);
when CONV_UNSIGNED(23,14)=>buff_data<=CONV_UNSIGNED(47236,16);
when CONV_UNSIGNED(24,14)=>buff_data<=CONV_UNSIGNED(47241,16);
when CONV_UNSIGNED(25,14)=>buff_data<=CONV_UNSIGNED(47245,16);
when CONV_UNSIGNED(26,14)=>buff_data<=CONV_UNSIGNED(47250,16);
when CONV_UNSIGNED(27,14)=>buff_data<=CONV_UNSIGNED(47255,16);
when CONV_UNSIGNED(28,14)=>buff_data<=CONV_UNSIGNED(47260,16);
when CONV_UNSIGNED(29,14)=>buff_data<=CONV_UNSIGNED(47265,16);
when CONV_UNSIGNED(30,14)=>buff_data<=CONV_UNSIGNED(47270,16);
when CONV_UNSIGNED(31,14)=>buff_data<=CONV_UNSIGNED(47275,16);
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
when CONV_UNSIGNED(4093,14)=>buff_data<=CONV_UNSIGNED(47109,16);
when CONV_UNSIGNED(4094,14)=>buff_data<=CONV_UNSIGNED(47114,16);
when CONV_UNSIGNED(4095,14)=>buff_data<=CONV_UNSIGNED(47119,16);
when CONV_UNSIGNED(4096,14)=>buff_data<=CONV_UNSIGNED(47123,16);


    when others =>buff_data<=CONV_UNSIGNED(47123,16);
    end case;
    output_register <= buff_data;
    end if;
    end process main;
  
    alfaout <= output_register;    --查表数据最终放大10000倍,适应0-65535范围正余弦查表,并与2/3pi*10000相加减

end rtl;

在板子上验证过,程序的数据表段用excell生成,拷贝到开发环境里,不然累死人滴

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

12

帖子

0

粉丝