FPGA----IP核cordic使用

之前说过,使用IP核要先百度,然后看文档,然后再百度最后使用。本篇文章以cord IC核的sin、cos来进行实验(全网最详教程)。

1、定点数、浮点数、反码、补码

首先要明确这几个词的概念。废话不多说,直接上例子:采用32位的有符号定点数表示方法,第一位表示符号位(0是正数,1是负数),因此还剩31个位置来表示数据,具体整数部分与小数部分是几位,看自己设定。我们下面假设整数部分2位(因为-pi~pi=-3.14~3.14,2位可以表示3),29位表示小数。

Exp1:

1.5=1+0.5=>0(符号位)_01(整数位)_0.5*2^29(小数位)=0(符号位)_01(整数位)_1,0000,0000,0000,0000,0000,0000,0000(小数位)=00110000000000000000000000000000=30000000'h('h表示16进制)

②负数是正数的补码,即反码+1:补码=反码(二进制取反即可)+1

由于1.5=0_01_10000000000000000000000000000,所以其反码为1_10_0,1111,1111,1111,1111,1111,1111,1111,所以其补码为1_10_1,0000,0000,0000,0000,0000,0000,0000,所以

-1.5=11010000000000000000000000000000=D0000000'h

Exp2:

120°=120/180*pi=2.094395102393195=2+(0.094395102393195*2^29)=0_10_int(50677984.71016798224384)=0_10_50677985=0_10_0,0011,0000,0101,0100,1000,1110,0001=01000011000001010100100011100001=430548E1'h

-120°=-120/180*pi=-2.094395102393195=1_01_1,1100,1111,1010,1011,0111,0001,1110=10111100111110101011011100011110=BCFAB71E'h

2、了解了编码规则后就开始使用cordic IP核

实验任务:使用IP核cordic的sin/cos功能

实验软硬件:ZCU106、Vivado2019.1

实验过程:

step1:建立test_pl_cordic项目,建立top源文件,并添加Clocking Wizard
与cordic IP核(如果这一步不会请参考前面的文章)

FPGA----IP核cordic使用_第1张图片

step2:cordic IP核的配置

FPGA----IP核cordic使用_第2张图片

 FPGA----IP核cordic使用_第3张图片

step3:赋值代码,并仿真(因为testbench里设置了时延,因此下面的第三图里面的按钮必须点一下才能看到仿真结果)

`timescale 1ns / 1ps
//
// Company: 东北电力大学
// Engineer: Yang Zheng
// 
// Create Date: 2021/12/31 14:33:38
// Design Name: 
// Module Name: top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module top(
    input   clk_p,
    input   clk_n,
    input   rst,
    output [63:0] data_a,
    output [63:0] data_b,
    output [63:0] data_c
    );
    reg    [31:0]  c_E_PH       [2:0];//A相
    reg            compute_sign =   1'b0;
    clk_wiz_0 uut_clk_wiz_0(
        .clk_out1(clk),
  // Status and control signals
        .reset(~rst),//高电平复位
        .locked(locked),
 // Clock in ports
        .clk_in1_p(clk_p),
        .clk_in1_n(clk_n)
    );
    always @(posedge clk or negedge rst) begin
        if (!rst) begin
            //复位
        end
        else begin
            c_E_PH[0] <= 32'h00000000;      //A相
            c_E_PH[1] <= 32'hBCFAB71E;      //B相
            c_E_PH[2] <= 32'h430548E1;      //C相
            compute_sign    <= 1'b1;
        end
        
    end
    reg             s_axis_phase_tvalid_a = 1'b0;
    reg     [31:0]  s_axis_phase_tdata_a  = 32'b0; 
    reg             s_axis_phase_tvalid_b = 1'b0;
    reg     [31:0]  s_axis_phase_tdata_b  = 32'b0;
    reg             s_axis_phase_tvalid_c = 1'b0;
    reg     [31:0]  s_axis_phase_tdata_c  = 32'b0;   
    wire    [63:0]  m_axis_dout_tdata_a;
    wire    [63:0]  m_axis_dout_tdata_b;
    wire    [63:0]  m_axis_dout_tdata_c;
    cordic_0 uut_cordic_sin_cos_a(
        .aclk(clk),
        .s_axis_phase_tvalid(s_axis_phase_tvalid_a),
        .s_axis_phase_tdata(s_axis_phase_tdata_a),

        .m_axis_dout_tvalid(m_axis_dout_tvalid_a),
        .m_axis_dout_tdata(m_axis_dout_tdata_a)
    );
    cordic_0 uut_cordic_sin_cos_b(
        .aclk(clk),
        .s_axis_phase_tvalid(s_axis_phase_tvalid_b),
        .s_axis_phase_tdata(s_axis_phase_tdata_b),

        .m_axis_dout_tvalid(m_axis_dout_tvalid_b),
        .m_axis_dout_tdata(m_axis_dout_tdata_b)
    );
    cordic_0 uut_cordic_sin_cos_c(
        .aclk(clk),
        .s_axis_phase_tvalid(s_axis_phase_tvalid_c),
        .s_axis_phase_tdata(s_axis_phase_tdata_c),

        .m_axis_dout_tvalid(m_axis_dout_tvalid_c),
        .m_axis_dout_tdata(m_axis_dout_tdata_c)
    );
    assign  data_a  =   m_axis_dout_tdata_a;
    assign  data_b  =   m_axis_dout_tdata_b;
    assign  data_c  =   m_axis_dout_tdata_c;
    always @(posedge clk or negedge rst) begin
        if (!rst)begin
            //复位
            s_axis_phase_tvalid_a   <=  1'b0;
            s_axis_phase_tvalid_b   <=  1'b0;
            s_axis_phase_tvalid_c   <=  1'b0;
        end
        else if(compute_sign == 1'b1) begin
            //可以开始计算
            s_axis_phase_tvalid_a <= 1'b1;
            s_axis_phase_tdata_a  <= c_E_PH[0];
            s_axis_phase_tvalid_b <= 1'b1;
            s_axis_phase_tdata_b  <= c_E_PH[1];
            s_axis_phase_tvalid_c <= 1'b1;
            s_axis_phase_tdata_c  <= c_E_PH[2];
            compute_sign    <= 1'b0;
        end
        else if(m_axis_dout_tvalid_a  == 1'b1
                && m_axis_dout_tvalid_b  == 1'b1    &&  m_axis_dout_tvalid_c  == 1'b1) begin
            s_axis_phase_tvalid_a   <=  1'b0;
            s_axis_phase_tvalid_b   <=  1'b0;
            s_axis_phase_tvalid_c   <=  1'b0;
        end
    end
endmodule
`timescale 1ns / 1ps
//
// Company: 东北电力大学
// Engineer: Yang Zheng
// 
// Create Date: 2021/12/31 14:49:12
// Design Name: 
// Module Name: testbench
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module testbench(

    );
    reg clk;
    reg rst;
    wire [63:0] data_a;
    wire [63:0] data_b;
    wire [63:0] data_c;
    always #4 clk=~clk;
    initial begin
        clk = 1'b0;
        rst = 1'b0;
        #10;
        rst = 1'b1;
    end

    top uut_top(
        .clk_p(clk),
        .clk_n(~clk),
        .rst(rst),
        .data_a(data_a),
        .data_b(data_b),
        .data_c(data_c)
    );
endmodule

FPGA----IP核cordic使用_第4张图片

step4:结果分析

FPGA----IP核cordic使用_第5张图片

注意:输出是64位的,前32位是sin后32位是cos

 我们把B相与C相的前32位拿来进行验证:

B相:c8930a30=11001000100100110000101000110000=1(符号位)_1(整数位)_00,1000,1001,0011,0000,1010,0011,0000(小数位)=-(1-1).((2^30-001000100100110000101000110000)/2^30)=-0.((2^30-143854128)/2^30)=-0.866

C相:376CF5D0=110111011011001111010111010000=0(符号位)_0(整数位)_11,0111,0110,1100,1111,0101,1101,0000(小数位)=0.(110111011011001111010111010000/2^30)=0.866

----------------------------2023-1-10更新---------------------------------------------------------------------------------

附上所有结果的转换截图,不要再说我代码不对/计算步骤不对了,我文章3000+的阅读量,不可能出错的!!!评论不要误人子弟!!!

1、32位浮点数转fix32_29

reg [31:0] input_data = 32'h3FC00000;//1.5
reg [31:0] input_data = 32'hBFC00000;//-1.5

FPGA----IP核cordic使用_第6张图片

FPGA----IP核cordic使用_第7张图片 

2、32位浮点数转fix32_30

reg [31:0] input_data = 32'h3F5DB22D;//0.866
reg [31:0] input_data = 32'hBF5DB22D;//-0.866

FPGA----IP核cordic使用_第8张图片

FPGA----IP核cordic使用_第9张图片

 验证完毕!!!

你可能感兴趣的:(Verilog,fpga开发,verilog)