FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)

1、本人目前亲自开发了,复数矩阵求逆(包括复数矩阵的四则运算,设C=A+Bi,可以求解A是非奇异矩阵时的任何复数矩阵,由于代码并行程度过高,在个人电脑64g内存条件下32维矩阵已经不能仿真),需要的看本人资料。下面是8*8复数矩阵求逆仿真截图

FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第1张图片

FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第2张图片

2、本文建立在前两篇文章的基础之上,需要有定点数的知识积累,看不懂的点击下面传送门补课:FPGA----IP核cordic使用_发光的沙子的博客-CSDN博客之前说过,使用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(符号位)_https://blog.csdn.net/qq_37912811/article/details/122246197

FPGA----IP核float(定点数转浮点数)使用_发光的沙子的博客-CSDN博客_定点数ip核1、本文紧接上一篇文章,因为我们计算设定的32位的单精度浮点数,但是cordic IP核输出的是32位定点数x(符号位)_x(整数位)_xx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx(小数位),为了方便使用float IP核的计算,因此我们需要将定点数转为浮点数。本片文章为全网第一篇带小数的定点数转浮点数的例程。2、Floating-point IP核使用实验任务:实现sin(±120°)32位定点数转浮点数操作,具体值怎么算的请参考上一篇文章实验软硬件:ZCU106https://blog.csdn.net/qq_37912811/article/details/122271643

3、废话不多说,直接打开pg105-cordic文档第22页结果如下:

FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第3张图片

 什么意思呢?就是假设要求解一个z=a+jb转化为z=A\angle \theta =\sqrt{a^2+b^2}\angle arctan\frac{b}{a}这种相量形式,就需要用到cord IC下的translate功能。但是从上图来看,输入只支持[-1,1]之间的数。那么我们假设要求z=238.7-j165.4(下图为matlab计算值)应该如何呢?这就涉及到了归一化问题。

FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第4张图片

4、数据格式的归一化(格式化)

先看文档:

FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第5张图片

 什么意思呢?就是1Q15表示17位的2进制数据,其中15位是小数,1位是整数位,最高位是符号位

即z=x(符号位)_x(整数位)_xxx_xxxx_xxxx_xxxx(小数位),这个数据标示方法又叫做Fix17_15(17位的二进制定点数,其中15位是小数部分),那么对于一个例子1Q8(Fix10_8)就是10位二进制数据,其中包括1位符号位、1位整数位、8位小数位。下面是文档中的图:

FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第6张图片

注:Table3-11文档写错了,Bit6才是1。 

因此,我们可以根据计算的方法,将数据归一化。从上图可以看出,90.5可以表示为0.707,32表示为0.25。但这也出现了一个问题,当数据超过1时,计算会存在一定的误差。由于本人所做算法均为32位单精度浮点数,因此我们的数据格式时1Q30(Fix32_30),当数据小于1时,我们的计算的幅值与相角是相当精准的。

下图为238.5归一化后的Fix32_32对应的定点数二进制代码:

0(符号位)_0(整数位)_00_0000_0000_0000_0000_0000_1110_1110=4.442408680915833e-07

FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第7张图片

 上面介绍了如何使用translate核,因为我们可以采用Float的浮点数转定点数IP核,因此本文的实现思路就是:将实部与虚部先与1比较,如果大于1,则实部与虚部都除以2^{29},然后用Float将32位浮点数转为(32位含1位小数的定点数),然后再用translate,最后将输出的幅值乘以2^{29},角度不变即可完成对于复数转为向量的操作。下面是代码:

5、IP核的设置

①float_to_fix32_30

FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第8张图片

FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第9张图片

 FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第10张图片

 FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第11张图片

 ②polar_axis_translate

 FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第12张图片

 FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第13张图片

 ③fix32_30_to_float

FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第14张图片

 FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第15张图片

 FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第16张图片

 FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第17张图片

 ④fix32_29_to_float:与③除了下图都一样

FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第18张图片

 ⑤float_compare

FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第19张图片

 FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第20张图片

 ⑥float_multiply

FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第21张图片

FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第22张图片

 ⑦float_divide

FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第23张图片

FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第24张图片

6、代码考虑了,当数据大于1时 的情况,大家可以放心调用,复数数据格式采用32位的单精度浮点数。 

算了,大家还是联系我要代码吧,代码不贴出了。

FPGA----IP核cordic-translate使用(关于定点数的映射问题,全网最详)_第25张图片

 下面是testbench的代码

`timescale 1ns / 1ps
//
// Company: 东北电力大学
// Engineer: Yang Zheng
// 
// Create Date: 2022/03/17 15:39:27
// 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 = 1'b0;
    always #5 clk =~ clk;
    reg rst;
    reg complex_to_polar_input_valid = 1'b0;
    reg [63:0] complex_number;
    wire [63:0] polar_number;
    complex_to_polar uut_complex_to_polar(
        .clk(clk),
        .rst(rst),
        .complex_number(complex_number),
        .polar_number(polar_number),
        .complex_to_polar_input_valid(complex_to_polar_input_valid),
        .complex_to_polar_output_valid(complex_to_polar_output_valid),
        .complex_to_polar_valid_en(complex_to_polar_valid_en)
    );
    initial begin
        rst = 1'b0;
        #200;
        rst = 1'b1;
        complex_to_polar_input_valid = 1'b1;
        
    end
    always @(posedge clk or negedge rst) begin
        if (!rst) begin
            
        end
        else begin
            if (complex_to_polar_input_valid) begin
                if (complex_to_polar_valid_en) begin
                    complex_number = {32'h436EB333,32'hC3253C28};// 238.5-165.235i
                    //complex_number = {32'h3F34FDF3,32'h3E800000};// 0.707+0.25i
                end
            end
        end
    end

endmodule

7、仿真截图

验证: \sqrt{238.5^2+165.235^2}=290.1462652-atan(\frac{165.235}{238.5})=-0.6054912805557251

这就是为什么上述说到,大于1的数字会产生误差,就是因为Fix32_30所对应的Fix32_1,只有1个小数,因此算出的结果应该是\sqrt{238.5^2+165.5^2}= 290.2972614\approx 290.3106689453125

你可能感兴趣的:(Verilog,fpga开发,verilog)