verilog实现基于Cordic算法的双曲函数计算
来源:互联网 发布:南瑞信通 知乎 编辑:程序博客网 时间:2024/05/16 17:09
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,//inputen,//inputcosh_out,sinh_out,e_out,//outputbusy_end//output );input clk,rst_n;input [31:0] z0;//16input en;output [31:0] sinh_out,cosh_out;//16output [31:0] e_out;//16output 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 endreg[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 endendreg[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 endendassign sinh_out = reg_y[11];//<<4assign 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;initialbegin 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)
阅读全文
0 0
- verilog实现基于Cordic算法的双曲函数计算
- 基于FPGA的CORDIC算法实现——Verilog版
- cordic算法verilog实现(简单版)
- cordic算法verilog实现(复杂版)
- cordic算法原理及verilog实现
- cordic算法原理及verilog实现
- Cordic算法——verilog实现
- FPGA基于CORDIC算法的求平方实现
- CORDIC算法的FPGA实现
- 三角函数计算,Cordic 算法C实现
- cordic算法的总结和verilog代码的编写
- FPGA实现cordic算法
- 三角函数计算,Cordic 算法入门
- 三角函数计算,Cordic 算法入门
- 三角函数计算,Cordic 算法入门
- 三角函数计算,Cordic 算法入门
- 三角函数计算,Cordic 算法入门
- 三角函数计算,Cordic 算法入门
- LeetCode-206. Reverse Linked List
- JavaWeb学习总结(五)——Servlet开发(一)
- JAVAWEB开发之——Linux命令总结
- 关于Spring中aop用aspect配置
- 石子归并 CSU
- verilog实现基于Cordic算法的双曲函数计算
- Linux系统编程——特殊进程之守护进程
- python练习
- 验证控件的使用
- MySQL两种安装方式02(绿色安装)_day02
- 【mysql】触发器
- 给出进程启动区间计算任意时间点并行进程数量
- Web架构:varnish缓存代理服务器超详细剖析
- Java Socket 简单编程实例