Vivado IP核之定点数转为浮点数Floating-point
前言
随着制造工艺的不断发展,现场可编程逻辑门阵列(FPGA)的集成度越来越高,应用也越来越广,其中在对数字信号进行处理时必然要用到一些数学处理类的IP核。最近正在研究空域自适应抗干扰技术研究的FPGA硬件实现,其中不免要用到一些IP核,今天就从定点数转浮点数详细介绍一下vivado当中的Floating-point这个IP核吧,希望对各位的学习能起到一定的帮助作用。
提示:以下是本篇文章正文内容,均为作者本人原创,写文章实属不易,希望各位在转载时附上本文链接。
一、什么是定点数?
定点数:小数位置固定不变的数叫做定点数,也就是小数点是定在某个位置不变的数。定点数分为定点整数与定点小数,其中定点整数又分为有符号定点整数与无符号定点整数,定点小数又分为有符号定点小数与无符号定点小数。本文着重介绍32位(1+1+30)有符号定点小数,位数的大小自己可以根据不同的使用场景设定,其他三类都比较简单,这里就不予以介绍。
小数点的位置固定在最高有效数位之前、符号位之后,如图1所示。定点小数的小数点位置是隐含约定的,小数点并不需要真正地占据一个bit位。
![](https://i-blog.csdnimg.cn/blog_migrate/e6d919c62e8a080ab8b6b638f9d0018a.png)
在图1中,为符号位,当
=0时,为正小数;当
=1时,小数为负小数。n为小数的位宽,小数的位宽会直接影响小数的精度,位宽n越大精度越高。
在xilinx vivado中的IP核,有符号定点数均以补码表示,所以我们务必要明白原码、反码、补码三者之间的关系。正数的原码、反码、补码均相同;负数的原码即为其取绝对值后正数的原码,将负数原码逐位取反,即得到负数反码,将负数反码加一即得到负数补码。
好了,话不多说,直接上例子。
example1: 假设一个有符号32位(1位符号位+1位整数位+30位小数位)定点小数用二进制表示为32'b0011_0111_0110_1100_1111_0101_1101_0000,那么它表示的小数换成十进制是多少呢?首先,其符号位为0,可知其为正数,那么原码、反码、补码相同;其次,整数位为0,实际对应的整数位也为0;然后,其30位小数部分为30'b11_0111_0110_1100_1111_0101_1101_0000,化为十进制数即为929887696;最后,我们知道当30位小数全为1时表示的十进制数为1073741823,那么由929887696/1073741823≈0.8660254即可得出该定点小数化为实数也就近似为0.8660254。
example2: 假设一个有符号32位(1位符号位+1位整数位+30位小数位)定点小数用二进制表示为32'b1100_1000_1001_0011_0000_1010_0011_0000,那么它表示的小数换成十进制是多少呢?首先,其符号位为1,可知其为负数,那么32'b1100_1000_1001_0011_0000_1010_0011_0000表示的为其补码,负数原码与补码不同,我们应该先求出其原码,其原码为32'b0011_0111_0110_1100_1111_0101_1101_0000;其次,整数位为0,实际对应的整数位也为0;由前面分析可知该码表示的正小数近似为0.8660254,至此即可得出该定点小数化为实数也就近似为-0.8660254。
二、什么是浮点数?
浮点数是一种标准化的表达方式,常用标准为IEEE754 标准,用来近似表示实数,并且可以在表达范围和表示精度之间进行权衡,因此被称为浮点数。(关于IEEE754 标准不懂的自行百度,这里不在赘述)。
example3: 假设一个有符号32位浮点数(单精度为32位,双精度为64位)用二进制32'b0011_1111_0101_1101_1011_0011_1101_0111,那么根据IEEE754 标准可知其符号位为0,表示正小数,其指数部分为8'b0111_1110,小数部分为23'b101_1101_1011_0011_1101_0111,根据IEEE754 标准可知其表示的小数为0.8660254。
example4: 假设一个有符号32位浮点数(单精度为32位,双精度为64位)用二进制32'b1011_1111_0101_1101_1011_0011_1101_0111,那么根据IEEE754 标准可知其符号位为1,表示负小数,其指数部分为8'b0111_1110,小数部分为23'b101_1101_1011_0011_1101_0111,根据IEEE754 标准可知其表示的小数为-0.8660254。
三、Floating-point IP核配置步骤
在vivado中搜索Floating-point,找到该IP核后即可按照以下操作完成相应的配置。
1.首先配置Operation Selection界面,如图2所示。
![](https://i-blog.csdnimg.cn/blog_migrate/130e156508fc35bb14b2414115e0ee4e.png)
2.其次配置Precision of Inputs界面,如图3所示。
![](https://i-blog.csdnimg.cn/blog_migrate/590d85859e73dfe0419109155960fbc2.png)
3.然后配置Precision of Result界面,如图4所示。
![](https://i-blog.csdnimg.cn/blog_migrate/fe79f7a5c46aacb89a44effbdab86262.png)
4.再然后配置Optimizations界面,如图5所示。
![](https://i-blog.csdnimg.cn/blog_migrate/f625180c34209b973b27a0a811da10a9.png)
5.最后配置Interface Options界面,如图6所示。
![](https://i-blog.csdnimg.cn/blog_migrate/bceda0ae5c8759916d910a495b84d2cb.png)
以上5个界面都配置完成后即可点击右下角OK按钮生成IP核。
四、仿真
1.顶层代码
建立一个顶层模块,命名为fix_to_float_top,用来例化刚才生成的IP核。
代码如下:
`timescale 1ns / 1ps
//
// Company: 重庆大学
// Engineer: CLG
// Create Date: 2022/07/22 09:37:43
// Design Name:
// Module Name: fix_to_float_top
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
// Dependencies:
// Revision:1.0
// Revision 0.01 - File Created
// Additional Comments:
//
module fix_to_float_top(
input clk,
input s_axis_a_tvalid, //输入数据有效标志信号
input [31:0] s_axis_a_tdata, //输入的 定点数 数据
output m_axis_result_tvalid, //输出数据有效标志信号
output [31:0] m_axis_result_tdata //输出的 float 数据
);
floating_point_ip u1_floating_point_ip(
.aclk(clk),
.s_axis_a_tvalid(s_axis_a_tvalid),
.s_axis_a_tdata(s_axis_a_tdata),
.m_axis_result_tvalid(m_axis_result_tvalid),
.m_axis_result_tdata(m_axis_result_tdata)
);
endmodule
2.仿真代码
建立一个仿真模块,命名为fix_to_float_tb,用来仿真刚才顶层模块例化的IP核。
代码如下:
`timescale 1ns / 1ps
//
// Company: 重庆大学
// Engineer: CLG
// Create Date: 2022/07/22 10:02:05
// Design Name:
// Module Name: fix_to_float_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
// Dependencies:
// Revision:1.0
// Revision 0.01 - File Created
// Additional Comments:
//
module fix_to_float_tb( );
reg clk;
reg a_valid_a = 1'b0;
reg [31:0] a_a = 32'b0;
wire [31:0] result_a;
fix_to_float_top u1_fix_to_float_top(
.clk(clk),
.s_axis_a_tdata(a_a),
.s_axis_a_tvalid(a_valid_a),
.m_axis_result_tdata(result_a),
.m_axis_result_tvalid(m_axis_result_tvalid)
);
always #5 clk=~clk;
initial begin
clk = 1'b0;
#100;
a_valid_a <= 1'b1;
a_a <= 32'h376CF5D0;
#500;
a_valid_a <= 1'b1;
a_a <= 32'hc8930a30;
end
always @(posedge clk) begin
if (m_axis_result_tvalid == 1'b1) begin
a_valid_a <= 1'b0;
end
end
endmodule
五、仿真分析
仿真结果如图7所示,对比前面所列举定点数、浮点数的例子,可知该模块成功实现了将定点数转化为浮点数。
![](https://i-blog.csdnimg.cn/blog_migrate/8eca46090deba295547cb40433c6c882.png)
六、两种将十进制小数转化为任意位数的二进制有符号定点数的方法
总结
本次介绍了定点数、浮点数以及怎么使用vivado中的Floating-point IP核将定点数转化32位浮点数。