之前说过,使用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核(如果这一步不会请参考前面的文章)
step2:cordic IP核的配置
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
step4:结果分析
注意:输出是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
2、32位浮点数转fix32_30
reg [31:0] input_data = 32'h3F5DB22D;//0.866
reg [31:0] input_data = 32'hBF5DB22D;//-0.866
验证完毕!!!