乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      CORDIC算法理論與代碼實(shí)現(xiàn)(VHDL)

       goandlove 2019-08-01

      為什么會(huì)出現(xiàn)CORDIC算法呢?

      對(duì)于三角函數(shù)計(jì)算,理論接觸較多的應(yīng)該就是級(jí)數(shù)展開的方法 ,通過逼近的方式進(jìn)行計(jì)算,比如泰勒級(jí)數(shù)。但是因?yàn)檫@種多項(xiàng)式函數(shù)在計(jì)算的過程中需要大量使用到浮點(diǎn)數(shù)計(jì)算,而對(duì)于缺乏硬件乘法器的器件而言這種計(jì)算方式的實(shí)現(xiàn)是很困難的。有了問題,自然就會(huì)有人出來解決,1959年J. Volder就首次提出了CORDIC算法,只需要進(jìn)行移位和加減運(yùn)算的快速算法。

      CORDIC算法能干什么?

      這里只介紹關(guān)于三角函數(shù)方面CORDIC的作用:

      1、得到坐標(biāo)軸上一點(diǎn)的角度(相位信息);

      2、得到坐標(biāo)軸上一點(diǎn)對(duì)應(yīng)的(幅值信息)。

      ps:使用cordic計(jì)算幅值的方法不好,可以選擇更好的,比如查找表的方法,因此這里不再過多介紹計(jì)算幅值的方法。

      CORDIC算法的原理是什么?

      對(duì)于坐標(biāo)軸上點(diǎn)的相位,就是和x軸正半軸(后面統(tǒng)稱x軸)的夾角。求一個(gè)點(diǎn)的相位也就是將要求的點(diǎn)進(jìn)行旋轉(zhuǎn),當(dāng)點(diǎn)旋轉(zhuǎn)到與x軸第一次重合時(shí),旋轉(zhuǎn)過的相位大小就是這個(gè)點(diǎn)的相位。CORDIC算法通俗來講就是把這個(gè)旋轉(zhuǎn)過程變成了“離散”旋轉(zhuǎn),每次旋轉(zhuǎn)特定的角度,旋轉(zhuǎn)N次。在旋轉(zhuǎn)過程中不停的判斷,如果落在x軸就停止,如果發(fā)現(xiàn)在x軸上方就逆時(shí)針旋轉(zhuǎn)(相位增加),如果發(fā)現(xiàn)在x軸下方就順時(shí)針旋轉(zhuǎn)(相位減小),將旋轉(zhuǎn)過程中的相位變化進(jìn)行累加,最終就可以得到一個(gè)點(diǎn)的相位。這里可以總結(jié)這個(gè)旋轉(zhuǎn)過程有兩點(diǎn)要求:

      1、旋轉(zhuǎn)過程中能夠?qū)崟r(shí)得到y(tǒng)的值,因?yàn)槲覀冃枰獃的值來判斷我們旋轉(zhuǎn)的點(diǎn)是否到達(dá)了x軸(點(diǎn)在第一象限的話,y=0則表明點(diǎn)落在了x軸上);

      2、每次旋轉(zhuǎn)需要知道旋轉(zhuǎn)的角度,以便于計(jì)算相位。

      有了上面的原理,現(xiàn)在需要做的就是得到一個(gè)點(diǎn)在坐標(biāo)軸上旋轉(zhuǎn)和相位的關(guān)系式。

      首先假設(shè)坐標(biāo)軸上有任意一點(diǎn)經(jīng)過旋轉(zhuǎn)后得到,如下圖所示:

      因?yàn)槭切D(zhuǎn),幅值相等,則可以推導(dǎo)公式:

      ps:這里介紹一種方便的方法推導(dǎo),使用復(fù)變函數(shù)推導(dǎo)相位旋轉(zhuǎn),有興趣化簡一下即可對(duì)應(yīng)上面的公式:

      這里可以把()看作是輸入點(diǎn),上面的公式的確滿足了旋轉(zhuǎn)的第一個(gè)要求,也就是可以實(shí)時(shí)計(jì)算出旋轉(zhuǎn)后的y值,但是這個(gè)公式中包含了,它們計(jì)算起來已經(jīng)很復(fù)雜了,怎么辦呢?接下來就是取巧的過程:

      1、對(duì)于而言,只是影響y值的大小,但是并不影響判斷點(diǎn)是否落在x軸上,因此這里直接將省略;

      2、對(duì)于任意的的確不好求其結(jié)果,但是我們可以限制每次旋轉(zhuǎn)的角度,使的值是特殊值,這里選擇的值是(1,1/2,1/4,...,1/(2^n))。這里值的選擇是方便硬件進(jìn)行計(jì)算,可以直接進(jìn)行算術(shù)右移,最大限度簡化操作。

      3、既然的值有了,那么對(duì)于每次旋轉(zhuǎn)的角度值而言也就是確定的了(45,26.565051177078,14.0362434679265等等)。對(duì)于實(shí)際工程而言,旋轉(zhuǎn)次數(shù)(迭代)肯定是有限的,這個(gè)次數(shù)是和浮點(diǎn)數(shù)轉(zhuǎn)化為定點(diǎn)數(shù)精度有關(guān)的。比如轉(zhuǎn)化精度是浮點(diǎn)數(shù)1轉(zhuǎn)化為定點(diǎn)數(shù)256,則45°對(duì)應(yīng)的定點(diǎn)數(shù)是45*256=11520,且能分辨的最小值是1/256=0.00390625°。因?yàn)橛凶钚》直媛氏拗?,如果角度再小也就沒有意義了,因此如果轉(zhuǎn)化倍數(shù)是256,則最大迭代次數(shù)是15次。

      ps:CORDIC算法只是一個(gè)近似計(jì)算,也就是說15次迭代后點(diǎn)不一定是落在x軸上的。轉(zhuǎn)化精度也高,迭代次數(shù)越多,結(jié)果越準(zhǔn)確。

      有了上面的推論,相位旋轉(zhuǎn)公式可以寫成:

      對(duì)于旋轉(zhuǎn)過程中相位累加的公式可以寫成:

      這里的z是有初始值的,初始值和象限有關(guān),第一象限和第四就是z=0(x>0),第二象限就是z=90(y>0),第三象限就是z=-90(y<>在下面給出的示例代碼中,是默認(rèn)輸入值x>0的。如果想將程序擴(kuò)展到四個(gè)象限,判斷輸入點(diǎn)的象限,然后取z的不同初始值和對(duì)輸入點(diǎn)進(jìn)行象限變換(比如輸入點(diǎn)在第二象限(x0,y0),則將點(diǎn)逆時(shí)針旋轉(zhuǎn)90°得到新點(diǎn)(y0,-x0))即可,有興趣的可以進(jìn)行添加。

      以下是示例代碼:

      library ieee;
      use ieee.std_logic_1164.all;
      use ieee.std_logic_signed.all;
      use ieee.std_logic_arith.all;
      entity cordic is
      generic(
      w1 : integer := 16; --幅值位寬
      w2 : integer := 16; --角度位寬
      w3 : integer := 18 --中間變量
      );
      port(
      clk : in std_logic;
      rstn : in std_logic;
      data_En : in std_logic;
      x_In : in std_logic_vector(w1-1 downto 0);
      y_In : in std_logic_vector(w1-1 downto 0);
      zn : out std_logic_vector(w2-1 downto 0)
      );
      end cordic;

      architecture beha of cordic is
      type array15x8 is array(0 to 14) of std_logic_vector(w2-1 downto 0);
      constant z : array15x8 := (x'2D00',x'1A91',x'0E09',x'0720',x'0394',x'01CA',x'00E5',
      x'0073',x'0039',x'001D',x'000E',x'0007',x'0004',x'0002',x'0001');
      signal phi : std_logic_vector(w2-1 downto 0) := (others => '0');
      signal x0,y0 : std_logic_vector(w3-1 downto 0);
      signal im,re : std_logic_vector(w3-1 downto 0);
      signal n : integer range 0 to 14;
      type state is (s0,s1);
      signal Cstate : state := s0;
      begin
      process(n,y0,x0)
      begin
      im <> to_stdlogicvector(to_bitvector(y0) sra n);
      re <> to_stdlogicvector(to_bitvector(x0) sra n);
      end process;

      process(clk,rstn)
      begin
      if rstn='0' then
      phi <> (others => '0');
      elsif rising_edge(clk) then
      case Cstate is
      when s0 =>
      if data_En='1' then
      Cstate <> s1;
      n <> 0;
      x0 <> sxt(x_In,w3);
      y0 <> sxt(y_In,w3);
      else
      n <> n;
      end if;
      when s1 =>
      if signed(y0)=0 then
      x0 <> x0;
      y0 <> y0;
      elsif (y0(7))='1' then
      x0 <> x0 - im;
      y0 <> y0 + re;
      phi <> phi - z(n);
      else
      x0 <> x0 + im;
      y0 <> y0 - re;
      phi <> phi + z(n);
      end if;
      if n14 then
      n <> n + 1;
      else
      Cstate <> s0;
      end if;
      when others =>
      Cstate <> s0;
      end case;
      zn <> phi;
      end if;
      end process;
      end beha;

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多