Vivado IP core complex multiplication en virgule flottante Virgule flottante

Vivado IP core complex multiplication en virgule flottante Virgule flottante

Table des matières

avant-propos

1. Exemple de multiplication de nombres complexes à virgule flottante

2. Étapes de configuration du noyau IP à virgule flottante

3. Réflexion globale

4. Simuler

1. Code de niveau supérieur

2. Code de simulation

5. Analyse des résultats de la simulation

Résumer


avant-propos

         Avec le développement continu du processus de fabrication, le réseau de portes logiques programmables sur le terrain (FPGA) devient de plus en plus intégré et son application devient de plus en plus étendue.Parmi eux, certains IP de traitement mathématique doivent être utilisés lors du traitement des signaux numériques. nucléaire. Récemment, j'étudie l'implémentation matérielle FPGA de la recherche sur la technologie anti-brouillage adaptative de l'espace aérien, qui utilise inévitablement certains cœurs IP.Aujourd'hui, je vais vous présenter comment utiliser le cœur IP à virgule flottante dans vivado pour réaliser une multiplication complexe à virgule flottante.à certains mesure utile.


Astuce : Ce qui suit est le texte de cet article, qui sont tous originaux par l'auteur lui-même. Il n'est pas facile d'écrire un article. J'espère que vous joindrez un lien vers cet article lors de la publication.

1. Exemple de multiplication de nombres complexes à virgule flottante

        Afin de faciliter l'analyse des résultats de la simulation ultérieure, nous énumérons ici les exemples de multiplication et de division de nombres complexes à virgule flottante. Au cours de la simulation, les exemples suivants sont directement utilisés pour la simulation afin de vérifier si les résultats de la simulation sont corrects. .

        exemple : Soit le nombre flottant a=32'h4057AE14+j32'h400F5C29, soit a=3.37+j2.24, le nombre flottant b=32'h3FE51EB8+j32'hC039999A, soit b=1.79-j2.9, alors a*b= 32'h414873EB+32'hC0B86DC6, soit a*b=12.5283-j5.7634, le résultat est calculé par matlab.

2. Étapes de configuration du noyau IP à virgule flottante

        Comment configurer l'addition, la soustraction, la multiplication et la division du noyau IP à virgule flottante a été expliqué dans l'article précédent. Les étudiants qui ne le savent pas peuvent lire mon article précédent, donc je ne le répéterai pas ici.

3. Réflexion globale

        Selon la formule (a+bi)(c+di)=ac-bd+(ad+bc)i, nous utilisons d'abord quatre multiplicateurs parallèles pour calculer les résultats de ac, bd, ad et bc, puis utilisons un soustracteur et un additionneur pour calculer ac-bd et ad+bc en parallèle . Dans ma configuration de cœur IP, le retard du cœur IP multiplicateur est de 8 horloges, et le retard du cœur IP additionneur et soustracteur est de 11 horloges. Une horloge ou deux se sont écoulées. Dans l'ensemble du code de niveau supérieur, le comptage de cnt est particulièrement important, et les changements de nombreuses variables intermédiaires dépendent de la valeur de cnt. J'ai aussi beaucoup commenté dans le code, et l'idée cette fois n'est pas difficile, je crois que tout le monde peut la comprendre.

4. Simuler

1. Code de niveau supérieur

Créez un module de niveau supérieur nommé float_complex_mul .

code afficher comme ci-dessous:

`timescale 1ns / 1ps
//
// Company: cq university
// Engineer: clg
// Create Date: 2022/07/24 15:15:43
// Design Name: 
// Module Name: float_complex_mul
// Project Name: 
// Target Devices: 
// Tool Versions: 2017.4
// Description: 
// Dependencies: 
// Revision:1.0
// Revision 0.01 - File Created
// Additional Comments:
//
//    计算公式   (a+bi)(c+di)=ac-bd+(ad+bc)i

module float_complex_mul(
    input clk,               // 输入时钟信号        
    input rst_n,             //输入复位信号
    input start,             //输入开始信号
    input [31:0] re_a,       //输入因数a的实部
    input [31:0] im_a,       //输入因数a的虚部
    input [31:0] re_b,       //输入因数b的实部
    input [31:0] im_b,       //输入因数b的虚部
    output reg over,           //输出计算完成信号
    output reg [31:0] re_res,  //输出计算结果的实部
    output reg [31:0] im_res   //输出计算结果的虚部
    );
    //reg define
    reg [4:0] cnt;               //过程计数标志
    reg valid1;                  //乘有效信号 
    reg valid2;                  //加减有效信号 
    
    //wire define
    wire [31:0] result1;      //结果1
    wire [31:0] result2;      //结果2
    wire [31:0] result3;      //结果3
    wire [31:0] result4;      //结果4
    wire [31:0] result5;      //结果5
    wire [31:0] result6;      //结果6
    always @(posedge clk or negedge rst_n)
        if(!rst_n)
            cnt<=0;
        else if(start==1)
            begin
                if(cnt<5'd27)    
                    cnt<=cnt+1;
                else
                    cnt<=0;
            end
        else if(start==0)
            cnt<=0;

    always @(posedge clk or negedge rst_n) 
        if(!rst_n)  
            valid1<=0;
        else if(5'd0<cnt<=5'd9)
            valid1<=1;
        else
            valid1<=0;
    
    always @(posedge clk or negedge rst_n)
        if(!rst_n)  
               valid2<=0;
           else if(5'd12<cnt<=5'd24)
               valid2<=1;
           else
               valid2<=0; 
    always @(posedge clk or negedge rst_n)
         if(!rst_n)  
            begin over<=0;re_res<=0;im_res<=0; end
         else if(cnt==5'd26)
            begin  over<=1;re_res<=result5;im_res<=result6;  end
         else
            begin over<=0;re_res<=0;im_res<=0; end
        
    float_mul_ip u1_float_mul_ip(                       //乘法器1    计算ac
                   .aclk(clk),
                   .s_axis_a_tvalid(valid1),
                   .s_axis_a_tdata(re_a),
                   .s_axis_b_tvalid(valid1),
                   .s_axis_b_tdata(re_b),
                   .m_axis_result_tvalid(),
                   .m_axis_result_tdata(result1)
               );
    float_mul_ip u2_float_mul_ip(                       //乘法器2    计算bd
                   .aclk(clk),
                   .s_axis_a_tvalid(valid1),
                   .s_axis_a_tdata(im_a),
                   .s_axis_b_tvalid(valid1),
                   .s_axis_b_tdata(im_b),
                   .m_axis_result_tvalid(),
                   .m_axis_result_tdata(result2)
               );
    float_mul_ip u3_float_mul_ip(                       //乘法器3    计算ad
                   .aclk(clk),
                   .s_axis_a_tvalid(valid1),
                   .s_axis_a_tdata(re_a),
                   .s_axis_b_tvalid(valid1),
                   .s_axis_b_tdata(im_b),
                   .m_axis_result_tvalid(),
                   .m_axis_result_tdata(result3)
               );  
    float_mul_ip u4_float_mul_ip(                       //乘法器4    计算bc
                  .aclk(clk),
                  .s_axis_a_tvalid(valid1),
                  .s_axis_a_tdata(im_a),
                  .s_axis_b_tvalid(valid1),
                  .s_axis_b_tdata(re_b),
                  .m_axis_result_tvalid(),
                  .m_axis_result_tdata(result4)
              );   
    float_sub_ip u1_float_sub_ip(                    //减法器   计算ac-bd
                .aclk(clk),
                .s_axis_a_tvalid(valid2),
                .s_axis_a_tdata(result1),
                .s_axis_b_tvalid(valid2),
                .s_axis_b_tdata(result2),
                .m_axis_result_tvalid(),
                .m_axis_result_tdata(result5)
              );     
    float_add_ip u1_float_add_ip(                  //加法器   计算ad+bc
                .aclk(clk),
                .s_axis_a_tvalid(valid2),
                .s_axis_a_tdata(result3),
                .s_axis_b_tvalid(valid2),
                .s_axis_b_tdata(result4),
                .m_axis_result_tvalid(),
                .m_axis_result_tdata(result6)
              );
              
endmodule

2. Code de simulation

Créez un module de simulation nommé float_complex_mul_tb pour simuler le module de niveau supérieur.

code afficher comme ci-dessous:

`timescale 1ns / 1ps
//
// Company: cq university
// Engineer: clg
// Create Date: 2022/07/26 10:26:05
// Design Name: 
// Module Name: float_complex_mul_tb
// Project Name: 
// Target Devices: 
// Tool Versions: 2017.4
// Description: 
// Dependencies: 
// Revision:1.0
// Revision 0.01 - File Created
// Additional Comments:
//

module float_complex_mul_tb();
    reg clk;               //时钟信号        
    reg rst_n;             //复位信号
    reg start;             //开始信号
    reg [31:0] re_a;       //因数a的实部
    reg [31:0] im_a;       //因数a的虚部
    reg [31:0] re_b;       //因数b的实部
    reg [31:0] im_b;       //因数b的虚部
    wire over;             //计算完成信号
    wire [31:0] re_res;    //计算结果的实部
    wire [31:0] im_res;    //计算结果的虚部

float_complex_mul u1_float_complex_mul(  //例化顶层模块
    .clk(clk),
    .rst_n(rst_n),
    .start(start),
    .re_a(re_a),
    .im_a(im_a),
    .re_b(re_b),
    .im_b(im_b),
    .over(over),
    .re_res(re_res),
    .im_res(im_res)
);
always #5 clk=~clk;
initial begin
    clk=1'b0;rst_n=1'b1;start=1'b0;
#5;     rst_n=1'b0;
#10;     rst_n=1'b1;
            start=1'b1;
            re_a=32'h4057ae14;
            im_a=32'h400f5c29;   
            re_b=32'h3fe51eb8;
            im_b=32'hc039999a; 
#270   start=1'b0;
      
end

endmodule

5. Analyse des résultats de la simulation

Les résultats de la simulation sont présentés dans la figure 1. Par rapport aux exemples de multiplication complexe à virgule flottante énumérés ci-dessus, on peut voir que le module a réalisé avec succès la multiplication de nombres complexes à virgule flottante. En conséquence, la différence entre le dernier nombre hexadécimal et le calcul précédent avec matlab est de 1, ce qui est dans la plage acceptable.On peut voir que l'erreur de calcul avec FPGA peut également être très faible.

Figure 1 Résultats de simulation


Résumer

Cette fois, nous allons introduire la multiplication de nombres complexes à virgule flottante.

Guess you like

Origin blog.csdn.net/m0_66360845/article/details/125990848