<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 汽車電子 > 設(shè)計(jì)應(yīng)用 > 基于CORDIC算法的32位浮點(diǎn)三角超越函數(shù)之正余弦函數(shù)的FPGA實(shí)現(xiàn)

          基于CORDIC算法的32位浮點(diǎn)三角超越函數(shù)之正余弦函數(shù)的FPGA實(shí)現(xiàn)

          ——
          作者:桂林電子科技大學(xué) 通信與信息工程系 李全 陳石平 付佃華 時(shí)間:2006-11-03 來源:電子產(chǎn)品世界 收藏

          摘要: 本文在傳統(tǒng)算法的基礎(chǔ)之上,通過增加迭代次數(shù),對(duì)參數(shù)進(jìn)行了優(yōu)化篩選,提高了運(yùn)算精度,使設(shè)計(jì)出的軟核能夠在精度要求較高的場(chǎng)合中運(yùn)行,如實(shí)時(shí)語音、圖像信號(hào)處理、濾波技術(shù)等。輸出數(shù)據(jù)經(jīng)過,能夠直接兼容大多數(shù)處理器,擴(kuò)展了其應(yīng)用范圍。最終在Altera公司NiosⅡ處理器中通過增加的方式完成了硬件實(shí)現(xiàn)。

          關(guān)鍵詞: ;;

          引言

          浮點(diǎn)超越函數(shù)的應(yīng)用領(lǐng)域十分廣泛,涉及航空航天、機(jī)器人技術(shù)、實(shí)時(shí)語音、圖像信號(hào)處理、濾波技術(shù)、FFT變換等領(lǐng)域。因此,設(shè)計(jì)并實(shí)現(xiàn)浮點(diǎn)三角超越函數(shù)是非常重要的。硬件實(shí)現(xiàn)的超越函數(shù)算法,按照數(shù)學(xué)公式和對(duì)應(yīng)的實(shí)現(xiàn)方式的不同,可以分為查表法、多項(xiàng)式近似法、基于查表的多項(xiàng)式結(jié)合方法、有理數(shù)近似和逐位法五類。經(jīng)過對(duì)這些算法進(jìn)行分析和比較,本文選擇 作為超越函數(shù)的算法,并用Altera公司的CycloneⅡ芯片完成硬件實(shí)現(xiàn)。

          CORDIC內(nèi)核及前后處理單元設(shè)計(jì)

          CORDIC內(nèi)部結(jié)構(gòu)


          在迭代式架構(gòu)下,內(nèi)部CORDIC結(jié)構(gòu)如圖1所示。

          圖1  經(jīng)典CORDIC硬件實(shí)現(xiàn)架構(gòu)

          圖1中架構(gòu)由控制單元,選擇器,移位寄存器,ROM,加法器組成。系統(tǒng)的控制單元采用有限狀態(tài)機(jī)的實(shí)現(xiàn)形式,進(jìn)行迭代和數(shù)據(jù)格式轉(zhuǎn)換的流程控制。ROM中存放的是預(yù)先計(jì)算好的反正切數(shù)據(jù)值,供迭代運(yùn)算中調(diào)用。從架構(gòu)中可以看出只有移位與加減運(yùn)算,因此特別適合于用硬件實(shí)現(xiàn)。每次迭代運(yùn)算后,再將數(shù)據(jù)返回,直到足夠的次數(shù)執(zhí)行完成后,才將結(jié)果輸出。每次迭代之前要對(duì)角度值Z進(jìn)行判斷,根據(jù)Z的符號(hào)來決定圖1中的符號(hào)。

          實(shí)現(xiàn)該部分的關(guān)鍵代碼如下:
          if(~z[31])
           begin
            x <= x - (y >>> counter);
            y <= y + (x >>> counter);
            z <= z - atan;
            end
          else
           begin
            x <= x + (y >>> counter);
            y <= y - (x >>> counter);
            z <= z + atan;
           end  

          前置處理單元

          由于迭代本身的限制,最大旋轉(zhuǎn)角度用公式表示為:

               (1)
          為了擴(kuò)展輸入角的范圍,需要對(duì)輸入角進(jìn)行預(yù)處理,使其落在第一象限范圍之內(nèi)。即對(duì)輸入角度進(jìn)行取模,根據(jù)所處的象限進(jìn)行符號(hào)判斷和正余弦交換。在CORDIC內(nèi)核設(shè)計(jì)中,對(duì)0_范圍內(nèi)的角度用一個(gè)32位的二進(jìn)制整數(shù)來表示,即101101100000101101100000(即十進(jìn)制數(shù)11930464)。

          后置處理單元

          后置處理將內(nèi)部CORDIC計(jì)算出來的結(jié)果在輸出前轉(zhuǎn)換成IEEE-754標(biāo)準(zhǔn)格式,即形式,其結(jié)構(gòu)如圖2所示。

          圖2  后置處理單元硬件結(jié)構(gòu)

          圖2中的LZDC(Leading zero detection circuit)為前導(dǎo)零檢測(cè)電路,其功能是用來統(tǒng)計(jì)數(shù)據(jù)從最高位開始連續(xù)“0”的個(gè)數(shù),再根據(jù)它把計(jì)算出來的數(shù)值轉(zhuǎn)換成IEEE-754標(biāo)準(zhǔn)格式。在轉(zhuǎn)換過程中需要對(duì)尾數(shù)進(jìn)行左移,才能表示為,此位移量再與前置處理器單元傳來的參考指數(shù)值相減,得到輸出指數(shù)值。符號(hào)位直接由前置處理過程得到。最后將符號(hào)位、指數(shù)數(shù)值、小數(shù)按位連接得到IEEE-754格式的數(shù)據(jù),并從硬件接口輸出端輸出。

          設(shè)計(jì)及軟件仿真波形

          用Quartus II對(duì)本設(shè)計(jì)進(jìn)行了軟件波形仿真,選取角度值分別為、、和(即-)。

          以為例,iAngle的十進(jìn)制數(shù)為(/360)*88.8= 1059425266(小數(shù)部分忽略),十六進(jìn)制表示為3F258BF2。oCos的內(nèi)部仿真結(jié)果十六進(jìn)制值為3FFD8131,對(duì)應(yīng)的IEEE-754標(biāo)準(zhǔn)格式值oCos_IEEE754為3F7FF804,即十進(jìn)制數(shù)0.020942,正弦的計(jì)算過程同理。

          仿真結(jié)果對(duì)照如表1所示。

          從表中可以看出,在(0_)輸入范圍內(nèi),用本設(shè)計(jì)計(jì)算仿真出的結(jié)果誤差小于10-6,在單精度表示范圍內(nèi)誤差為0,且輸出表示為標(biāo)準(zhǔn)IEEE754類型。一次計(jì)算所需時(shí)鐘周期數(shù)為34。



          Altera公司NiosⅡ處理器增加了多達(dá)256條用戶自定義指令,這是其它SOC系統(tǒng)無法比擬的。用戶自定義就是讓NiosⅡ軟核完成一個(gè)用HDL描述的電路模塊功能。用戶自定義指令可以在幾個(gè)時(shí)鐘周期之內(nèi)完成復(fù)雜算法的處理能力,訪問存儲(chǔ)器或系統(tǒng)外的邏輯單元,加快專項(xiàng)任務(wù)的執(zhí)行,以達(dá)到優(yōu)化目的。通過用戶自定義指令可以把系統(tǒng)中用軟件處理中的耗時(shí)多的關(guān)鍵算法用硬邏輯電路來實(shí)現(xiàn),大大提高處理器的效率。由于CORDIC內(nèi)核的特性,正余弦函數(shù)可以同時(shí)計(jì)算出來,因此適合于采用擴(kuò)展用戶自定義指令來實(shí)現(xiàn),即用一個(gè)硬件模塊來完成兩種函數(shù)的計(jì)算。通過一個(gè)附加的參數(shù)n來決定輸出是正弦或余弦,這樣可以節(jié)約一半的硬件資源。本文在NIOSⅡ中增加了正余弦自定義指令,其宏定義代碼如下:

          #define MYCORDIC_N 0x00000002
          #define MYCORDIC_N_MASK ((1<<1)-1)
          #define FLOAT_COS(A)  __builtin_custom_fni(MYCORDIC_N+( 1&MYCORDIC_N_MASK),(A))
          #define FLOAT_SIN(A)  __builtin_custom_fni(MYCORDIC_N+ (0&MYCORDIC_N_MASK),(A))

          加入指令后,在NiosⅡ的IDE中進(jìn)行軟硬件同時(shí)調(diào)試,相應(yīng)的C語言測(cè)試代碼在此省略,給出對(duì)比結(jié)果如圖3和圖4所示。

          圖3

          圖4

          本系統(tǒng)硬件驗(yàn)證平臺(tái)采用DE2開發(fā)板,其中NiosⅡ處理器配置為full功能,分別使用16K數(shù)據(jù)cache和16K指令cache,增加了硬件乘法器和硬件除法器,開啟了流水線功能,已達(dá)到了NiosⅡ軟核處理器的最高性能。

          從結(jié)果對(duì)比中看出,使用硬件指令后對(duì)完全相同的正余弦角度進(jìn)行計(jì)算時(shí),其運(yùn)算速度大大提高。需要說明的是,軟件運(yùn)算隨著輸入角度的不同所使用的計(jì)算時(shí)間有很大差別,而使用硬件指令運(yùn)算是,其計(jì)算時(shí)間基本不變。詳細(xì)對(duì)比如表2所示。

          誤差方面,軟硬件運(yùn)算在六位小數(shù)范圍內(nèi)其誤差值為0,可見本設(shè)計(jì)確實(shí)達(dá)到了高精度的要求。

          結(jié)語

          本設(shè)計(jì)以提高處理器精度和速度為目標(biāo),通過在NiosⅡ處理器中添加用戶自定義指令的方式以更多的硬件資源換取更快的計(jì)算速度,從而滿足現(xiàn)代實(shí)時(shí)通訊處理的要求。在傳統(tǒng)CORDIC算法的基礎(chǔ)之上,巧妙的改進(jìn)了算法,達(dá)到了更高精度和更快的速度,具有較廣泛的應(yīng)用價(jià)值。當(dāng)然,本設(shè)計(jì)只完成了正余弦函數(shù)的硬件IP部分,還有更多的工作等待我們?nèi)ネ瓿?,相信通過不斷的努力,我們會(huì)完成更多的函數(shù)硬件IP。

          參考文獻(xiàn)
          1.  Volder. The CORDIC trigonometric computing teclu}ique. IRE Trans. Electronic Computers, 1959, EC-8(3): 334-334.
          2.  Richard Herveille. Cordic Core Specification . 18, 2001
          3.  潘宏亮.浮點(diǎn)指數(shù)類超越函數(shù)的運(yùn)算算法研究與硬件實(shí)現(xiàn).西北工業(yè)大學(xué) 2006.3
          4.  IEEE organise.IEEE Standard for Binary Floating-Point Arithmetic Inc 345 East 47th Street, New York, NY 10017, USA
          5.  王博立.浮點(diǎn)運(yùn)算CORDIC之實(shí)現(xiàn)與其在3D圖形學(xué)之應(yīng)用.臺(tái)灣國立中山大學(xué) 2002.6
          6.  www.Altera.com
          7.  www.opencore.org
          8.  www.edacn.net



          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();