FPGA调用浮点数IP核实现浮点运算、以及CORDIC核计算三角函数,连续进行多次运算的时序

单片机的硬件串口,发送和接收完毕都有相应的标志位,例如TC(发送完成)和RXNE(接收完成)位。
FPGA则不同,FPGA采用的是AXI4-Stream协议,数据送入IP核后,经过固定数量的时钟周期后,就得到运算结果,没有任何标志位表明运算完成

利用浮点数IP核(Floating-point),将32位有符号定点数(Int32)转换为单精度浮点数(float),只需要6个时钟周期,就能得到结果。如下图所示:

将两个单精度浮点数相加,需要11个时钟周期后,才能得到结果,如下图所示:

利用CORDIC库计算sin和cos三角函数的值,需要20个时钟周期才能得到结果,如图所示:

那么,连续进行多次运算,需要多少时钟周期呢?让我们来编写程序测试一下:

【测试程序】

测试工程下载地址:https://pan.baidu.com/s/1qGiy64RmYWvopXLUUDa3HQ(提取码:9red)

test.v:

module test();
    reg clock = 0;
    
    main main(clock);
    
    always begin
        #10 clock = ~clock;
    end
endmodule

 main.v:

module main(
    input clock,
    output reg [3:0] leds = 0
    );
    
    reg [31:0] fixed_in = 0;
    wire [31:0] float_out;
    wire float_out_valid;
    floating_point_0 fixed_to_float(
        .aclk(clock),
        .s_axis_a_tdata(fixed_in),
        .s_axis_a_tvalid(1),
        .m_axis_result_tdata(float_out),
        .m_axis_result_tvalid(float_out_valid)
    );
    
    wire [31:0] addition_out;
    wire addition_out_valid;
    floating_point_1 float_addition(
        .aclk(clock),
        .s_axis_a_tdata(float_out),
        .s_axis_a_tvalid(float_out_valid),
        .s_axis_b_tdata(32'h3f800000),
        .s_axis_b_tvalid(1),
        .m_axis_result_tdata(addition_out),
        .m_axis_result_tvalid(addition_out_valid)
    );
    
    // 请注意: Phase Format选择Scaled Radians后
    // 还要把Coarse Rotation勾上,才能计算-Pi至Pi(即-180至180°)的范围
    // 否则只能计算-Pi/4至Pi/4 (即-45至45°)
    reg signed [15:0] phase_in = 16'b111_0000000000000; // -1
    wire [32:0] degree_in = (phase_in >>> 10) * 180; // 转换成角度, -1对应-180°
    wire [15:0] cos_out;
    wire [15:0] sin_out;
    wire sincos_valid;
    cordic_0 sincos(
        .aclk(clock),
        .s_axis_phase_tdata(phase_in),
        .s_axis_phase_tvalid(1),
        .m_axis_dout_tdata({sin_out, cos_out}), // Y_OUT, X_OUT
        .m_axis_dout_tvalid(sincos_valid)
    );
    
    always @(posedge clock) begin
        fixed_in <= fixed_in + 1;
        
        if (phase_in == 16'b001_0000000000000) begin // +1
            phase_in <= 16'b111_0000000000000; // -1
            leds <= leds + 1;
        end
        else
            phase_in <= phase_in + 16'b000_0010000000000; // +0.125
    end
    
endmodule

添加IP核的方法是,在vivado软件中点击左边的IP catalog

然后在右边搜索出要添加的IP核的名称,双击即可开始配置:

两者都选择non-blocking(非阻塞)模式。
注意配置CORDIC的时候,Phase Format要选择Scaled Radians(不带π的弧度单位),还必须要把Coarse Rotation勾上。
把Coarse Rotation勾上才能计算-180°~180°,否则只能计算-45°~45°。

配置完成后,点击Generate,就可以在代码中引用了。

来看下程序运行结果:(可以在右键菜单中将数字配置为浮点或定点方式显示)

可以看到,IP核的输入端每个时钟周期都在送入数据,IP核的输出端从valid信号变为高电平后,也是每个时钟周期都输出一次计算结果。

定点数转浮点数的模块,第一个时钟周期送入第一个数据后(注意输入的valid信号一直为1),第六个周期得到第一个数据的转换结果。第二个周期送入第二个数据后,在第七个周期得到转换结果。输出的valid信号是在第六个周期变成高电平的,说明到第六个周期才把第一个数据转换出来。

两个浮点数相加的模块,从第六个时钟周期开始送入数据(因为输入的valid信号连的是上一个模块输出的valid信号),同样也是每个时钟周期都送入一个数据。到第6+11=17个时钟周期,就开始得到计算结果了,每个周期都出一个新结果。

sin、cos三角函数计算模块,花了20个时钟周期才得到第一个结果,之后是每一个时钟周期都出一个新结果。

 

这表明,AXI4-Stream协议是按时钟周期来运行的,并没有任何表明运算完成的标志位。

每个时钟周期都可以送入数据,第一个数据运算出来需要花一定的时间,之后每个时钟都算出来新数据。

可以放大了看三角函数的运算结果,完全正确:

误差还是有一点:sin(0)算出来是-6.1×10^-5,其实就是0

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

巨大八爪鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值