一、背景介绍
Cordic(Coordinate Rotation Digital Computer) ,坐标旋转数字计算机算法。由Volder于1959年在设计美国航空控制系统的过程中首先提出,主要用于解决导航系统中三角函数、反三角函数和开方等运算的实时计算问题。1971年,Walther将圆周系统、线性系统和双曲系统统一到一个Cordic迭代方程,从而提出了一种统一的算法形式。
因为CORDIC算法本身是一种逐位逼近的算法,所以一般不论旋转级数 n 是多少,都直接应用其极限的二进制码作为模校正因子。
现代数字信号处理的一个主要发展趋势是,算法结构日趋复杂,计算量大,实时性要求高,且包含大量三角函数、开方等复杂函数计算。但是MAC单元并不适合此类函数的计算,而CORDIC算法可以将多种难以用硬件电路直接实现的复杂算法分解为简单的加减、移位运算,故非常适合硬件电路的实现。CORDIC算法应用广泛,如离散傅里叶变换、离散余弦变换、离散Hartley变换、Chirp-Z变换、各种滤波以及矩阵的奇异值分解中都可应用CORDIC算法。从广义上讲,CORDIC算法提供了一种数学计算的逼近方法。例如,在工程领域可以用它实现直接数字频率合成器。
二、FPGA实现
(1)vivado CORDIC IP 核的调用
用它求平方根,输入位宽32bit,输出位宽16bit。在IP Catalog 下的Math Funtion中找到CORDIC,双击弹出IP的配置界面。
从此处可以看到输出有16个时钟的延迟
(2)编写IP例化代码
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2017/09/02 14:31:20
// Design Name:
// Module Name: sqrt_test
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module sqrt_test(
input [31:0] d_in,
input clk,
input ce,
output [15:0] d_out
);
cordic_0 cordic_inst (
.aclk(clk), // input wire aclk
.s_axis_cartesian_tvalid(ce), // input wire s_axis_cartesian_tvalid
.s_axis_cartesian_tdata(d_in), // input wire [31 : 0] s_axis_cartesian_tdata
.m_axis_dout_tvalid(m_axis_dout_tvalid), // output wire m_axis_dout_tvalid
.m_axis_dout_tdata(d_out) // output wire [15 : 0] m_axis_dout_tdata
);
endmodule
(3)编写测试文件
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2017/09/02 14:36:17
// Design Name:
// Module Name: simu
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module simu(
);
reg [31:0]d_in;
reg clk;
reg ce;
wire [15:0]d_out;
sqrt_test U1
(
.clk(clk),
.d_in(d_in),
.ce(ce),
.d_out(d_out)
);
initial begin
d_in = 0;
clk = 0;
ce = 0;
#20;
ce = 1;
end
always #5 clk = ~clk;
always #10 d_in = d_in + 1000;
endmodule
(4)仿真波形
文章评论(0条评论)
登录后参与讨论