赞
踩
基于cordic算法的小数开方及其FPGA实现
目录
现实中很多算法本身就包含开方运算,硬件实现中很多时候也会涉及到开方运算,本次较为详细的介绍用cordic算法实现开方运算的基本原理以及如何使用xilinx公司提供的cordic IP核来完成无符号小数开方运算。
提示:以下是本篇文章正文内容,写文章实属不易,希望能帮助到各位,转载请附上链接。
欲明白cordic算法中如何实现开方运算,首先需要知道坐标旋转公式。
如图1所示,在二维坐标系中,有一点A(x,y),其与原点之间连线的长度为r,连线和x轴正向夹角为,将其绕原点逆时针旋转可得到点。
由图知:
x’=rcos(α+θ)=rcosαcosθ−rsinαsinθ (1.1)
y’=rsin(α+θ)=rsinαcosθ+rcosαsinθ (1.2)
x=rcosα (1.3)
y=rsinα (1.4)
将(1.3)和(1.4)代入(1.1)和(1.2)可知:
x’=xcosθ−ysinθ (1.5)
y’=xsinθ+ycosθ (1.6)
(1.5)和(1.6)组成的即为坐标旋转公式,写成矩阵形式即为:
注:在word公式编辑器中编辑后复制过来居然有乱码,不兼容,所以以图片形式给出了。
那么如果是顺时针旋转我们由式(1.7)可知只需要将θ用-θ代替即可得到:
第 i+1 迭代旋转的角度为:
是每次迭代中的旋转角度。当 m=1 时,,此时为正弦方程;当 m=0 时,,此时为线性方程;当 m=-1 时, ,此时为双曲线方程。
- `timescale 1ns / 1ps
- //
- // Company: cq university
- // Engineer: clg
- // Create Date: 2022/09/01 20:52:25
- // Design Name:
- // Module Name: square_root
- // Project Name:
- // Target Devices:
- // Tool Versions: 2017.4
- // Description:
- // Dependencies:
- // Revision:1.0
- // Revision 0.01 - File Created
- // Additional Comments:
- //
-
- module square_root(
- input clk,
- input rst_n,
- input data_in_valid,
- input [31:0] data_in,
- output data_out_valid,
- output [31:0] data_out
- );
-
- cordic_square u1_cordic_square( //ip核例化
- .aclk(clk),
- .aresetn(rst_n),
- .s_axis_cartesian_tvalid(data_in_valid),
- .s_axis_cartesian_tdata(data_in),
- .m_axis_dout_tvalid(data_out_valid),
- .m_axis_dout_tdata(data_out)
- );
-
- endmodule
2.仿真代码
- `timescale 1ns / 1ps
- //
- // Company: cq university
- // Engineer: clg
- // Create Date: 2022/09/01 21:07:29
- // Design Name:
- // Module Name: square_root_tb
- // Project Name:
- // Target Devices: 2017.4
- // Tool Versions:
- // Description:
- // Dependencies:
- // Revision:1.0
- // Revision 0.01 - File Created
- // Additional Comments:
- //
-
- module square_root_tb();
- reg clk;
- reg rst_n;
- reg data_in_valid;
- reg [31:0] data_in;
- wire data_out_valid;
- wire [31:0] data_out;
-
- square_root u1_square_root(
- .clk(clk),
- .rst_n(rst_n),
- .data_in_valid(data_in_valid),
- .data_in(data_in),
- .data_out_valid(data_out_valid),
- .data_out(data_out)
- );
-
- initial begin
- clk=1'b1;rst_n=1'b1;data_in_valid=1'b0;data_in=32'b0;
- #10 rst_n=1'b0;
- #10 rst_n=1'b1;
- #10 data_in_valid=1'b1;data_in=32'b0_001_0000_0000_0000_0000_0000_0000_0000;
- #10 data_in_valid=1'b1;data_in=32'b0_111_0000_0000_0000_0000_0000_0000_0000;
-
- end
- always #5 clk=!clk;
- endmodule
如上图所示,从数据输入到数据输出会有32个时钟周期延时(与数据位数长短有关),注意实际的data_in和data_out是图中显示的2倍,因为我是把二进制的结果用定点数显示了,它显示的其实是真实值的一半,(这个运算是正确的,这里的误差完全是为了显示方便带来的一个倍数误差)因为实际上这个IP核开方运算时数据并不是真真正正的定点数,它的第一位算作的是小数点前面的0,其格式如下图所示:
所以图中仿真的输入为0.4375*2=0.875,输出为0.467707173200324*2=0.93541434346400648,我用计算器对0.875开方得到的结果是0.93541434346693485346,对比可知32位的精度挺高了,到小数点后第11位了,实际使用时完全可以自己根据需要的精度设置运算数据的位数。
以上就是此次介绍的cordic算法开方。
利用 CORDIC 算法计算平方根及其 FPGA 实现
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。