IP 核配置
按照上图所示进行配置,下文对配置内容进行详述。
- Configuration Parameters
- Functional Selection:可选择 Rotate(坐标旋转)、Translate(坐标变换)、Sin and Cos(正余弦计算)、ArcTan(反正切计算)、Sinh and Cosh(双曲函数)、ArcTanh(反双曲函数)、and Square Root(平方根计算)
- Architectural Configuration:
- Word Serial(串行):计算慢但资源消耗少
- Parallel(并行):计算快但资源消耗多
- Pipelining Mode:可选择 None(无流水线)、Optimal(最优流水线)、Maximum(最大流水线)。选用流水线会在子迭代后插入寄存器,增加计算延迟
- Phase Format:
- Radians(弧度):输入范围是 [ − π , π ] [-\pi,\pi] [−π,π] ,一个符号位 + 两个整数位 + (N-3)个小数位
- Scaled Radians(归一化弧度):输入范围是 [ − 1 , 1 ] [-1,1] [−1,1] ,一个符号位 + 两个整数位 + (N-3)个小数位
- Input/Output Options
- 输入输出位宽建议保持一致
- Round Mode:可选择 Truncate(截断)、Positive Infinity(向上取整)、Pos Neg Infinity(四舍五入)、Nearest Even(取最接近的偶数)
- Advanced Configuration Parameters
- Iterations(迭代次数):当设置为零时,迭代次数由输出所需的精度决定。在这种情况下,对于除平方根以外的所有运算,设置的基本迭代次数是输出宽度
- Precision(精度):当设置为零时,内部精度将根据输出所需的精度和内部迭代次数自动确定
- Coarse Rotation:当禁用时,输入/输出范围仅限于第一象限
IP 核输出
输出的数据格式为:高位为实部(正弦结果),低位为虚部(余弦结果)
HDL 代码
module CORDIC(
input wire sys_clk_p,
input wire sys_clk_n,
input wire rst_n,
input wire [15:0] phase_in, // 输入相位,16位宽度
input wire phase_valid, // 输入相位有效信号
output wire [15:0] sin_out, // 输出正弦值,16位宽度
output wire [15:0] cos_out, // 输出余弦值,16位宽度
output wire out_valid // 输出数据有效信号
);
/**********************************************
*********** IBUFDS 原语
**********************************************/
IBUFDS IBUFDS_inst(
.O(sys_clk),
.I(sys_clk_p),
.IB(sys_clk_n)
);
/**********************************************
*********** 例化 CORDIC IP核
**********************************************/
cordic_0 sin_cos (
.aclk (sys_clk ), // input wire aclk
.s_axis_phase_tvalid (phase_valid ), // input wire s_axis_phase_tvalid
.s_axis_phase_tdata (phase_in ), // input wire [15 : 0] s_axis_phase_tdata
.m_axis_dout_tvalid (out_valid ), // output wire m_axis_dout_tvalid
.m_axis_dout_tdata ({sin_out, cos_out} ) // output wire [31 : 0] m_axis_dout_tdata
);
endmodule
testbench 代码
`timescale 1ns / 1ps
module CORDIC_tb(
);
// 时钟周期定义
parameter CLK_PERIOD = 10;
reg sys_clk_p;
wire sys_clk_n;
reg rst_n;
reg [15:0] phase_in;
reg phase_valid;
wire [15:0] sin_out;
wire [15:0] cos_out;
wire out_valid;
// 实例化待测模块
CORDIC CORDIC_tb (
.sys_clk_p(sys_clk_p),
.sys_clk_n(sys_clk_n),
.rst_n(rst_n),
.phase_in(phase_in),
.phase_valid(phase_valid),
.sin_out(sin_out),
.cos_out(cos_out),
.out_valid(out_valid)
);
// 初始化 phase_valid 信号
initial begin
phase_valid = 0;
#(CLK_PERIOD * 30);
phase_valid = 1;
end
// 初始化 phase_in 信号
initial begin
phase_in = 0;
#(CLK_PERIOD * 30);
#(CLK_PERIOD*0) phase_in = 16'b1110_0000_0000_0000 ; // -1
#CLK_PERIOD phase_in = 16'b1110_1000_0000_0000 ; // -0.75
#CLK_PERIOD phase_in = 16'b1111_0000_0000_0000 ; // -0.5
#CLK_PERIOD phase_in = 16'b1111_1000_0000_0000 ; // -0.25
#CLK_PERIOD phase_in = 16'b0000_0000_0000_0000 ; // 0
#CLK_PERIOD phase_in = 16'b0000_1000_0000_0000 ; // 0.25
#CLK_PERIOD phase_in = 16'b0001_0000_0000_0000 ; // 0.5
#CLK_PERIOD phase_in = 16'b0001_1000_0000_0000 ; // 0.75
#CLK_PERIOD phase_in = 16'b0010_0000_0000_0000 ; // 1
end
// 初始化clk信号
assign sys_clk_n = ~sys_clk_p;
initial begin
sys_clk_p = 1;
forever #(CLK_PERIOD/2) sys_clk_p = ~sys_clk_p;
end
// 初始化rst信号
initial begin
rst_n = 0;
#(CLK_PERIOD * 20);
rst_n = 1;
end
endmodule
仿真结果
数据格式设置
输入参数设置为 Radix -> Real Settings -> Fixed Point -> Signed -> Binary Point:13
输出参数设置为 Radix -> Real Settings -> Fixed Point -> Signed -> Binary Point:14
仿真结果分析
- 时延:从输入数据有效到输出结果有效经历了19个时钟周期(190ns)
- 精度:输出结果存在一定误差,误差在 1e-5 量级