verilog實現基於Cordic演算法的雙曲函式計算
Cordic演算法可以用FPGA硬體來實現三角函式,向量旋轉,指數函式以及三角函式等數值計算,它是一種從一般的向量旋轉方程中推導得出。採用用不斷的旋轉求出對應的正弦餘弦值,是一種近似求解法。旋轉的角度很講求,比如求取正餘弦函式值時每次旋轉的角度必須使得 正切值近似等於 1/(2^N)。旋轉的目的是讓Y軸趨近與0。把每次旋轉的角度累加,即得到旋轉的角度和即為正切值。如圖1所示為Cordic基本原理示意圖,圖2位求解三角函式示意圖。
圖1 Cordic基本原理
圖2 Cordic求解三角函式
顯然Cordic演算法只需要簡單的硬體電路就可以實現。根據旋轉方向判定,可以選擇模式或向量模式進行工作,並通過設定不同的初始條件可以實現特殊函式的數學計算,從而為該演算法開創更廣泛的應用空間。
在雙曲座標下,Cordic演算法的迭代方程為:
- 與其他Cordic計算不同,由於tanh(-1)(2^0)為無窮大,所以迭代序列須從(i=1)開始,可以將各i處的值計算好並儲存在ROM中實現一個小的查詢表(LUT)。並從收斂考慮序列i的取值從第4項開始每隔3i+1項須重複一次。n次迭代輸出方程為:
- 可以通過選擇適當的初始值及多種操作模式組合完成tanh,exp的計算。下面是初步簡單實現的Verilog程式碼,程式碼中同時有用到ISE自帶的Cordic演算法的IP核作了模擬對比:
- module tanh_test(
- clk,
- rst_n,
- z0,//input
- en,//input
- cosh_out,
- sinh_out,
- e_out,//output
- busy_end//output
- );
- input clk,rst_n;
- input [31:0] z0;//16
- input en;
- output [31:0] sinh_out,cosh_out;//16
- output [31:0] e_out;//16
- output busy_end;
- reg en_buff;
- wire sub_busy;
- reg [31:0] cnt,h_cnt;
- wire [31:0] sub_result;
- reg busy_e;//
- always @(posedge clk or negedge rst_n)
- begin
- if(!rst_n)
- begin
- en_buff <= 0;
- busy_e <= 1'b1;//
- cnt <= 0;
- h_cnt <= 32'b0;
- end
- else begin
- en_buff <= en;
- cnt <= cnt + 1;
- end
- end
- reg[31:0] angel [0:12];
- always @(posedge clk or negedge rst_n)
- begin
- if(!rst_n)
- begin
- angel[0]<=32'b00000000000000001000110010011111;// 0.549306,1/2,tanh
- angel[1]<=32'b00000000000000000100000101100010;//0.255413,1/4
- angel[2]<=32'b00000000000000000010000000101011;//0.125657,1/8
- angel[3]<=32'b00000000000000000001000000000101;//0.062582,1/16
- angel[4]<=32'b00000000000000000001000000000101;//重複迭代一次
- angel[5]<=32'b00000000000000000000100000000000;//0.031260,1/32
- angel[6]<=32'b00000000000000000000010000000000;//0.015626,1/64
- angel[7]<=32'b00000000000000000000001000000000;//0.007813,1/128
- angel[8]<=32'b00000000000000000000000100000000;//0.003906250,1/256
- angel[9]<=32'b00000000000000000000000010000000;//0.001953125,1/128
- angel[10]<=32'b00000000000000000000000001000000;//0.0009765625,1/128
- angel[11]<=32'b00000000000000000000000000100000;//0.00048828125,1/128
- angel[12]<=32'b00000000000000000000000000010000;//0.000244140625,1/128
- //angel[8]<=17'b00000000000110011;//0.2,1/256,17'b00000000000110011
- //angel[9]<=17'b00000000000011001;//0.1,1/512,angel[9]<=17'b00000000000011001
- end
- end
- reg[31:0] reg_z[0:13];//1符號,15整數,16小數
- reg[31:0] reg_x[0:13];
- reg[31:0] reg_y[0:13];
- reg[4:0] i;
- always @(posedge clk or negedge rst_n)
- begin
- if(!rst_n)
- begin
- h_cnt <= 0;
- end
- else if(en && !en_buff)//&& (busy_e == 1'b1)
- begin
- reg_x[0] <= 32'b00000000000000010011010100011000;//(1/0.8282=1.2074)
- reg_y[0] <= 0;
- reg_z[0] <= z0;//初始值為v=1
- end
- else begin
- h_cnt <= h_cnt+1'b1;/////////////////////////
- for(i = 1;i <= 13;i = i+1'b1)
- begin
- if(reg_z[i-1][31])
- begin
- reg_x[i] <= reg_x[i-1]-(reg_y[i-1]>>i);//z<0,d=-1,否則d=1
- reg_y[i] <= reg_y[i-1]-(reg_x[i-1]>>i);
- reg_z[i] <= reg_z[i-1]+angel[i-1];
- end
- else begin
- reg_x[i] <= reg_x[i-1]+(reg_y[i-1]>>i);
- reg_y[i] <= reg_y[i-1]+(reg_x[i-1]>>i);
- reg_z[i] <= reg_z[i-1]-angel[i-1];
- end
- end
- if(h_cnt >= 20)
- begin
- busy_e <= 1'b0;
- end
- end
- end
- assign sinh_out = reg_y[11];//<<4
- assign cosh_out = reg_x[11];
- assign e_out = sub_result;
- assign busy_end =(sub_busy | busy_e);
- reg [15:0] in_phase;
- wire [15:0] out_cosh;
- wire [15:0] out_sinh;
- initial
- begin
- in_phase <= 16'b0010000000000000;//(1,第16位符號位,第15,14位整數位,13位小數位)
- end
- cordic_e your_instance_name (
- .phase_in(in_phase), // input [15 : 0] phase_in
- .x_out(out_cosh), // output [15 : 0] x_out
- .y_out(out_sinh), // output [15 : 0] y_out
- .clk(clk) // input clk
- );
- e_sub cosh_sub_sinh(
- .clk(clk),
- .rst_n(rst_n),
- .sub_a(cosh_out),
- .sub_b(sinh_out),
- .sub_result(sub_result),
- .busy_e(busy_e),
- .sub_busy(sub_busy)
- );
- endmodule
模擬結果圖,計算角度為1時的值:
(32'h00018aae=1.5417,sinh(1)真實值1.5431;32'h00012bfd=1.1718,cosh(1)=1.1752;32'h00005eb1=0.3699,e^(-1)=0.3679。使用IP核計算結果:16'h62d1=1.5440,16'h4b4b=1.1765)
相關文章
- 利用CORDIC演算法計算三角函式演算法函式
- 基於阿里雲函式計算實現AI推理阿里函式AI
- CORDIC演算法解釋及verilog HDL實現(圓座標系)演算法
- 基於函式計算的 BFF 架構函式架構
- 基於函式計算快速實現《為你寫詩》(阿里雲ECS)函式阿里
- 用RMI實現基於Java的分散式計算(轉)Java分散式
- 部署基於pythonwsgiweb框架的工程到函式計算PythonWeb框架函式
- “粘土風格”輕鬆拿捏,基於函式計算部署 ComfyUI實現AI生圖函式UIAI
- 基於函式計算部署GPT-Sovits語音生成模型實現AI克隆聲音函式GPT模型AI
- 基於函式計算一鍵部署簡易論壇函式
- 基於函式計算快速搭建Django Blog部落格函式Django
- 場景實踐:基於函式計算快速搭建Wordpress部落格系統函式
- 基於函式計算快速搭建Zblog部落格系統函式
- c++虛擬函式實現計算表示式子C++函式
- 【機器學習演算法實現】logistic迴歸__基於Python和Numpy函式庫機器學習演算法Python函式
- 手寫實現java棧結構,並實現簡易的計算器(基於字尾演算法)Java演算法
- 基於函式計算快速搭建Hexo部落格(體驗有禮)函式Hexo
- Verilog實現加減乘除運算
- 計算日期的函式函式
- 滿滿乾貨!手把手教你實現基於eTS的分散式計算器分散式
- 【iCore2雙核心板】SRAM 讀寫實驗(基於Verilog語言)
- 基於函式的索引函式索引
- Serverless 實戰 —— 函式計算 + Typescript 實踐Server函式TypeScript
- NodeJS 基於redis的分散式鎖的實現(Redlock演算法)NodeJSRedis分散式演算法
- 一元建站-基於函式計算 + wordpress 構建 serverless 網站函式Server網站
- 【iCore、iCore2 雙核心板】EPCS 實驗(SPI Flash)(基於Verilog語言)
- verilog實現矩陣卷積運算矩陣卷積
- 基於 Zookeeper 的分散式鎖實現分散式
- 基於redis的分散式鎖實現Redis分散式
- 基於vue實現的雙向資料繫結Vue
- 基於Verilog的陣列乘法器設計陣列
- 雲原生最佳實踐系列 5:基於函式計算 FC 實現阿里雲 Kafka 訊息內容控制 MongoDB DML 操作函式阿里KafkaMongoDB
- Oracle基於函式的索引Oracle函式索引
- [計算機視覺]基於內容的影像搜尋實現計算機視覺
- 一招識狗!基於函式計算打造柴犬秋田鑑定器函式
- 基於BKDRhash實現Hash演算法演算法
- VIVADO vhdl verilog 實現矩陣運算矩陣
- (函式)實現strstr函式函式