增添Vivado IP 核
选择浮点类型 floating-point 浮点类型
界面提供加法、减法、乘法的IP核
修改配置信息
选择non-blocking非阻塞模式,非阻塞控制流指的是部件不需要准备好就可以接受数据,缺少一个ready的端口信号
第二个配置参数延迟:
延迟指从输入数据有效到数据全部计算完成的时间,以时钟周期为单位
封装乘法模块与加法模块的设计文件
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2024/04/24
// Design Name: Floating Point Adder
// Module Name: floating_point_add
// Project Name:
// Target Devices:
// Tool Versions:
// Description: This module interfaces with a floating point adder IP to perform
// IEEE-754 single precision floating point addition.
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module floating_point_add_design(
input aclk,
input s_axis_a_tvalid,
input [31:0] s_axis_a_tdata,
input s_axis_b_tvalid,
input [31:0] s_axis_b_tdata,
output m_axis_result_tvalid,
output [31:0] m_axis_result_tdata
);
// Instantiate the floating point adder core
floating_point_add adder_core (
.aclk(aclk),
.s_axis_a_tvalid(s_axis_a_tvalid),
.s_axis_a_tdata(s_axis_a_tdata),
.s_axis_b_tvalid(s_axis_b_tvalid),
.s_axis_b_tdata(s_axis_b_tdata),
.m_axis_result_tvalid(m_axis_result_tvalid),
.m_axis_result_tdata(m_axis_result_tdata)
);
endmodule
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2024/04/24 01:43:15
// Design Name:
// Module Name: floating_point_multiply
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module floating_point_multiply(
input clk,
input a_tvalid,
input [31:0] a_tdata,
input b_tvalid,
input [31:0] b_tdata,
output mul_result_tvalid,
output [31:0] mul_result_tdata
);
multiply_unit uut(
.aclk(clk),
.s_axis_a_tvalid(a_tvalid),
.s_axis_a_tdata(a_tdata),
.s_axis_b_tvalid(b_tvalid),
.s_axis_b_tdata(b_tdata),
.m_axis_result_tvalid(mul_result_tvalid),
.m_axis_result_tdata(mul_result_tdata)
);
endmodule
测试乘法模块与加法模块的文件
`timescale 1ns / 1ps
module floating_point_multiply_tb;
reg clk = 0;
reg a_tvalid = 0;
reg [31:0] a_tdata = 0;
reg b_tvalid = 0;
reg [31:0] b_tdata = 0;
wire mul_result_tvalid;
wire [31:0] mul_result_tdata;
floating_point_multiply uut (
.clk(clk),
.a_tvalid(a_tvalid),
.a_tdata(a_tdata),
.b_tvalid(b_tvalid),
.b_tdata(b_tdata),
.mul_result_tvalid(mul_result_tvalid),
.mul_result_tdata(mul_result_tdata)
);
always #5 clk = ~clk; // Generate a clock with 50MHz frequency
initial begin
// Test case 1: Normal multiplication
a_tvalid = 1;
a_tdata = 32'h40400000; // 3.0 in IEEE-754
b_tvalid = 1;
b_tdata = 32'h40000000; // 2.0 in IEEE-754
#10
a_tvalid = 0; b_tvalid = 0;
#10
#200;
// More test cases should be added here
$finish;
end
endmodule
加法模块增加了一段显示结果的代码片段用于验证实际加法模块的运算周期,测试文件格式需要更换为systemverilog,因为$bitstoshortreal
是一个 SystemVerilog 的内置函数,它将一个32位IEEE 754编码的二进制值转换为一个浮点类型的值。
`timescale 1ns / 1ps
module floating_point_add_tb;
reg aclk;
reg s_axis_a_tvalid;
reg [31:0] s_axis_a_tdata;
reg s_axis_b_tvalid;
reg [31:0] s_axis_b_tdata;
wire m_axis_result_tvalid;
wire [31:0] m_axis_result_tdata;
// Instantiate the Unit Under Test (UUT)
floating_point_add_design uut (
.aclk(aclk),
.s_axis_a_tvalid(s_axis_a_tvalid),
.s_axis_a_tdata(s_axis_a_tdata),
.s_axis_b_tvalid(s_axis_b_tvalid),
.s_axis_b_tdata(s_axis_b_tdata),
.m_axis_result_tvalid(m_axis_result_tvalid),
.m_axis_result_tdata(m_axis_result_tdata)
);
// Clock generation
initial begin
aclk = 0;
forever #5 aclk = ~aclk; // Clock with a period of 10ns (100MHz)
end
// Stimulus here
initial begin
// Initialize Inputs
s_axis_a_tvalid = 0;
s_axis_b_tvalid = 0;
s_axis_a_tdata = 0;
s_axis_b_tdata = 0;
// Wait for the global reset
#10;
// First test: Add 1.5 + 2.5 = 4.0
s_axis_a_tvalid = 1;
s_axis_a_tdata = 32'h3fc00000; // 1.5 in IEEE-754 format
s_axis_b_tvalid = 1;
s_axis_b_tdata = 32'h40200000; // 2.5 in IEEE-754 format
#10; // Hold inputs for a short time
// Deassert valid signals
s_axis_a_tdata = 32'h40600000; //3.5 in IEEE-754 format
s_axis_b_tdata = 32'h3fc00000; // 1.5 in IEEE-754 format
#20; // Wait for the result
s_axis_a_tvalid = 0;
s_axis_b_tvalid = 0;
// Add additional test cases here
// Finish the simulation
#200;
$finish;
end
// Monitor results
always @(posedge aclk) begin
if(s_axis_a_tvalid)
begin
$display("Time:%0t ns input data is valid", $time / 1000.0);
end
if(m_axis_result_tvalid)
begin
// 假定m_axis_result_tdata是32位二进制浮点数,需要先转换成实际的浮点值
$display("Time: %0t ns add module come out data Result: %f", $time / 1000.0, $bitstoshortreal(m_axis_result_tdata));
end
end
endmodule