【FPGA】Xilinx Cordic IP 内核使用记录(输入输出数据格式介绍)及实验仿真

功能描述

1、Rotate

Rotate 实现的功能是坐标的旋转。
输入 X, Y, Phase
输出X’, Y’
具体实现的功能对应的数学表达形式如下:
在这里插入图片描述
在做FFT 复乘旋转因子时也可以用这个IP核的Rotate功能来实现。旋转因子-旋转!

2、Translation

Translation 实现的功能是求模,以及向量的夹角
输入 X, Y
输出X’ and Phase
具体实现的功能对应的数学表达形式如下:
在这里插入图片描述
在这里插入图片描述

3、Sin and Cos

功能:求取θ角对应的Sin 和Cos 函数值
输入:Phase
输出:X_OUT = Cos(PHASE_IN), Y_OUT = Sin(PHASE_IN)).

注:角度\相位Phase的数据格式是 2QN format,The output vector, (X_OUT, Y_OUT), is expressed as a pair of fixed-point twos complement numbers with an integer width of 2 bits (1QN format).
下面有关于数据格式的简略解释。

在数据输出时X,Y在同一个接口输出 sin的值在高位,cos的值在低位

在这里插入图片描述

4、Sinh and Cosh

功能:求解sinh 和cosh 在phase下的值
输入:Phase 角度
输出:坐标,注意高低位对应!
在这里插入图片描述

5、ArcTan

功能:求反正切函数值
输入:(X,Y) 坐标值
输出:Phase 角度
在这里插入图片描述

6 ArcTanh

功能:求Arctanh 函数值
输入:(Xin, Yin)
输出:Phase and (Xout,0)
在这里插入图片描述

数据格式

在这个IP内核里面
角度Phase的数据一般都是 1位符号位_2位整数位_N位小数位(2QN格式),
X, Y的输入是1位符号位_1位整数位_N位小数位(1QN格式)
输入,输出的数据都是二进制补码的形式(二补码),并且其他IP运算出来的数据可以直接输入到这个内核进行运算,大概可能都是补码的原因。

但是!!!在IP核运算中需要注意小数点对齐,数据截位的问题。
比如使用Xilinx 的 复数乘法器 CMPY IP 内核时,一个通道输入的仅仅存在符号位而不存在小数位,另外一个通道输入的却是1QN格式的数据,那么输出的结果也会存在着N位小数位。那么需要进行数据截位之后才会得到想要的结果。

详细可参考以下的一篇博文:
Xilinx Vivado复数乘法器Complex Multiplier IP核调用及其仿真

简单来说,就是如果输出选择最大位宽(无截位时),从非小数点的位置开始取,到输入数据位宽一致的位置即可。

例如,Cmpy 输入的一个复数是1位符号位+15位整数位无小数位;另一个输入的数据格式是1符号位+1整数位+14位小数位
那么在无截位输出的数据里[13:0]依旧是小数位,[14+:16](这种表述格式相当于[29:14], 14是开始截取的位置,16是截取的总位宽)位是我们想查看的。

使用教程

使用教程以Rotate 为例。
在 IP Catalog 搜索到我们的Cordic IP内核,点开后按下图所示经行内核设置。

在这里插入图片描述
第二页好像不用怎么配置(以后需要深入了解)
在这里插入图片描述

注意!!!每次数据输入需要延迟一段时间 ,这个延时具体在IP核配置的界面,那个Latency:22就是。

仿真激励文件代码:

`timescale 1ns / 1ps

 
module cordic_rotate_tb();
 
// cordic_rotate_test Inputs
reg   clk                                  = 0 ;
reg   start                                = 0 ;
reg   [15:0]  x_in                         = 0 ;
reg   [15:0]  y_in                         = 0 ;
reg   [15:0]  pha_in                       = 0 ;
// reg [15:0] X_in [7:0];
// cordic_rotate_test Outputs
wire  over                                 ;
wire  [15:0]  x_out                        ;
wire  [15:0]  y_out                        ;
 
 
initial
begin
    forever #5  clk=~clk;
end
 
cordic_rotate  u_cordic_rotate (
    .clk                     ( clk            ),
    .start                   ( start          ),
    .x_in                    ( x_in    [15:0] ),
    .y_in                    ( y_in    [15:0] ),
    .pha_in                  ( pha_in  [15:0] ),
                                        
    .over                    ( over           ),
    .x_out                   ( x_out   [15:0] ),
    .y_out                   ( y_out   [15:0] )
);
 
 
initial
begin
    #5  
    start<=1;
    pha_in<=16'b0000000000000000;//0
    x_in<=16'b0100000000000000;
    y_in<=16'b0000000000000000;
    
    #22 //第二次输入要在第一次输出之后,需要延时 
    pha_in<=16'b0011001000111101; //pi/2
    x_in<=16'b0100000000000000;
    y_in<=16'b0000000000000000;
end
 always @(posedge clk)begin
     #300
     $stop;
 end
 
endmodule

rotate代码:

`timescale 1ns / 1ps
//
// Company: SZU
// Engineer: LiangWF22
// 
// Create Date: 2023/03/19 09:42:43
// Design Name: 
// Module Name: cordic_rotate
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module cordic_rotate(
input clk,                    //输入时钟信号
input start,                  //输入开始计算信号
input [15:0] x_in,            //输入坐标x
input [15:0] y_in,            //输入坐标y
input [15:0] pha_in,          //输入相角
output wire over,             //输出计算完成标志
output wire [15:0] x_out,     //输出坐标x
output wire [15:0] y_out      //输出坐标y
    );

cordic_0 cordic_rotate0 (
  .aclk(clk),                                        // input wire aclk
  .s_axis_phase_tvalid(start),          // input wire s_axis_phase_tvalid
  .s_axis_phase_tdata(pha_in),            // input wire [15 : 0] s_axis_phase_tdata
  .s_axis_cartesian_tvalid(start),  // input wire s_axis_cartesian_tvalid
  .s_axis_cartesian_tdata({y_in,x_in}),    // input wire [31 : 0] s_axis_cartesian_tdata
  .m_axis_dout_tvalid(over),            // output wire m_axis_dout_tvalid
  .m_axis_dout_tdata({y_out,x_out})              // output wire [31 : 0] m_axis_dout_tdata
);

endmodule


工程链接

CSDN:https://download.csdn.net/download/LiangWF22/87591037
其他:https://leoeinstein.lanzoum.com/ixdrk0qiefnc

Forever young,always tearful.

  • 8
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Xilinx提供了CORDIC IP核,可以用于实现三角函数计算。CORDIC(Coordinate Rotation Digital Computer)是一种通过旋转坐标轴来计算三角函数的算法,它具有高精度、低功耗、低面积等优点,在数字信号处理、通信、图像处理等领域得到广泛应用。 以下是实现正弦函数计算的示例代码: ```verilog `timescale 1ns / 1ps module cordic_sin ( input signed [31:0] angle, output reg signed [31:0] sin_out ); wire signed [31:0] x, y, z; reg signed [31:0] x_buf, y_buf, z_buf; reg [31:0] i; CORDIC #( .DATA_WIDTH(32), .MODE(1), // Mode 1: Compute sin and cos .ITERATIONS(16), // Number of iterations .ANGLE_PRECISION(32), // Angle precision .PIPELINE_STAGE(0) // Pipeline stage ) cordic_inst ( .x(x), .y(y), .z(z) ); // Initial values assign x = angle; assign y = 0; assign z = 0; always @ (posedge cordic_inst.clk) begin if (cordic_inst.done) begin sin_out <= y_buf; x_buf <= x; y_buf <= y; z_buf <= z; i <= 0; end else begin // Shift x, y, z for next iteration x_buf <= x; y_buf <= y; z_buf <= z; x <= cordic_inst.x_out >> i; y <= cordic_inst.y_out >> i; z <= cordic_inst.z_out >> i; i <= i + 1; end end endmodule ``` 在上面的代码中,我们使用CORDIC IP核计算输入角度的正弦值。输入角度为一个有符号的32整数,输出正弦值也是一个有符号的32整数。我们使用MODE 1来计算正弦和余弦,ITERATIONS为16,ANGLE_PRECISION为32(表示输入角度的精度为32),PIPELINE_STAGE为0(表示不使用流水线)。 我们将输入角度直接赋值给x,y和z的初始值都为0。每次CORDIC IP核完成一次计算后,我们将得到下一次计算的x、y和z值,同时将当前计算得到的y值存储在sin_out寄存器中。 需要注意的是,CORDIC IP核是一个带有时钟的模块,因此我们需要在时钟上升沿时检查计算是否完成。如果计算完成,我们将存储下一次计算所需的x、y和z值,并将i重置为0,以便进行下一轮迭代。 值得注意的是,CORDIC IP核支持流水线操作,可以在可接受的延迟范围内提高性能。如果您需要更快的计算速度,可以尝试调整PIPELINE_STAGE参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值