作者:OpenSLee
1、float IP的创建
搜索float双击Floating-point
1 > Operation Selection 我们这里选择浮点数的加减法验证。
2 > Precision of Inputs 我们选择单晶浮点数(Single),指数位宽Exponent Width 8bit 尾数位宽24 bit
3 > Optimizations默认值
4 > Interface Options Latency选择1
2、浮点IP加减法的仿真验证
我们用python 自动生成100000个随机浮点数a和b以及a和b的相加或相减的结果。
python代码(float32(a)+float32(b)=float32(c)):
import bitstring, random span = 10000000 iteration = 100000 def ieee754(flt): b = bitstring.BitArray(float=flt, length=32) return b with open("TestAdd.txt", "w") as f: for i in range(iteration): a = ieee754(random.uniform(-span, span)) b = ieee754(random.uniform(-span, span)) ab = ieee754(a.float + b.float) f.write(a.hex +"_" + b.hex + "_" + ab.hex + "\n")
浮点数加法验证python结果(部分):
4a953fc4_ca39838f_49e1f7f2 4b14900e_492290ab_4b1eb919 4aedbfc3_4b146c7e_4b85a630 ca4bb7f6_cb162f1d_cb491d1a ca1ca77e_4ad19cc6_4a834907 c96e52c3_c9c7778d_ca1f5077 4ab9c1cc_cb187d76_ca6e7240 4b18508e_4a8e5556_4b5f7b39 cb103fa5_ca1765cf_cb361919 4a09db98_ca2feb0d_c9183dd4 ca626910_4a991e54_499fa730 c983aaa6_4b0534fd_4ae97f50 49e9e5f2_cad6005d_ca9b86e0 491b3266_4a3e2d28_4a64f9c2 ca935d66_caae8cbc_cb20f511 4a150544_4a645ebe_4abcb201
3、xilinx float IP的加法验证
s_axis_a_tdata,s_axis_b_tdata和m_axis_result_tdata分别代表浮点操作的a,b和结果c。
s_axis_operation_tdata的最低位为0时为加法,为1时为减法运算。
m_axis_result_tvalid当次信号为1时,结果有效。
浮点数加减法仿真顶层Float_AddSub_tb:
`timescale 1ns / 1ps `define N_TESTS 100000 module Float_AddSub_tb(); reg aclk; reg s_axis_a_tvalid; wire s_axis_a_tready; reg [31 : 0] s_axis_a_tdata; reg s_axis_b_tvalid; wire s_axis_b_tready; reg [31 : 0] s_axis_b_tdata; reg s_axis_operation_tvalid; wire s_axis_operation_tready; reg [7 : 0] s_axis_operation_tdata; wire m_axis_result_tvalid; reg m_axis_result_tready; wire [31 : 0] m_axis_result_tdata; reg [95:0] testVector [`N_TESTS-1:0]; reg test_stop; reg [31:0] Expected_result; reg [31:0] Expected_result_r; integer mcd; integer test_n; integer pass; integer error; initial begin aclk = 0; test_n = 0; pass =0; error = 0; test_stop =0; s_axis_a_tvalid = 0; s_axis_b_tvalid = 0; Expected_result = 0; Expected_result_r = 0; s_axis_a_tdata = 0; s_axis_b_tdata = 0; s_axis_operation_tvalid = 1; s_axis_operation_tdata =8'b0000_0000;//Add //s_axis_operation_tdata =8'b0000_0001;//Sub m_axis_result_tready = 1; $readmemh("TestAdd.txt", testVector);//Add mcd = $fopen("ResultsAdd.txt");//Add //$readmemh("TestSub.txt", testVector);//Sub //mcd = $fopen("ResultsSub.txt");//Sub repeat(100000) begin #10 test_n = test_n + 1'b1; end wait(test_stop==1'b1)begin $fclose(mcd); $finish; end end always #(5) aclk = ~aclk; always @(posedge aclk) begin Expected_result_r <= Expected_result; end always @(posedge aclk) begin #5 {s_axis_a_tdata,s_axis_b_tdata,Expected_result} = testVector[test_n]; s_axis_a_tvalid = 1; s_axis_b_tvalid = 1; //test_n <= test_n + 1'b1; #2; if ((m_axis_result_tvalid == 1) && (m_axis_result_tdata[31:11] == Expected_result_r[31:11])) begin $display ("TestPassed Test Number -> %d",test_n); pass = pass + 1'b1; end if ((m_axis_result_tvalid == 1) && (m_axis_result_tdata[31:11] != Expected_result_r[31:11])) begin $fdisplay (mcd,"Test Failed Expected Result = %h, Obtained s_axis_b_tdata = %h, Test Number -> %d",Expected_result,s_axis_b_tdata,test_n); error = error + 1'b1; end if (test_n >= `N_TESTS) begin $fdisplay(mcd,"Completed %d tests, %d passed and %d fails.", test_n, pass, error); test_stop = 1'b1; end end //----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG floating_AddSUB your_instance_name ( .aclk(aclk), // input wire aclk .s_axis_a_tvalid(s_axis_a_tvalid), // input wire s_axis_a_tvalid .s_axis_a_tready(s_axis_a_tready), // output wire s_axis_a_tready .s_axis_a_tdata(s_axis_a_tdata), // input wire [31 : 0] s_axis_a_tdata .s_axis_b_tvalid(s_axis_b_tvalid), // input wire s_axis_b_tvalid .s_axis_b_tready(s_axis_b_tready), // output wire s_axis_b_tready .s_axis_b_tdata(s_axis_b_tdata), // input wire [31 : 0] s_axis_b_tdata .s_axis_operation_tvalid(s_axis_operation_tvalid), // input wire s_axis_operation_tvalid .s_axis_operation_tready(s_axis_operation_tready), // output wire s_axis_operation_tready .s_axis_operation_tdata(s_axis_operation_tdata), // input wire [7 : 0] s_axis_operation_tdata .m_axis_result_tvalid(m_axis_result_tvalid), // output wire m_axis_result_tvalid .m_axis_result_tready(m_axis_result_tready), // input wire m_axis_result_tready .m_axis_result_tdata(m_axis_result_tdata) // output wire [31 : 0] m_axis_result_tdata ); endmodule
仿真结果:
Completed 100000 tests, 99999 passed and 0 fails.
通过仿真xilinx浮点ip的计算结果与python代码的输出结果一致,仿真成功。大家可以按照此方法仿真其他的算法中的计算公式或过程。首先利用C、matlab或者python等高级语言将算法的输入和输出一起打印出来,然后再读入到verilog的算法模型里面,通过打印出计算结果或误差来分析我们自己的算法的错误或者误差出现在哪里。
文章转载自: FPGA开源工作室(leezym0317)
*本文由作者授权转发,如需转载请联系作者本人