Vivado IP core complex multiplication en virgule flottante Virgule flottante
Table des matières
1. Exemple de multiplication de nombres complexes à virgule flottante
2. Étapes de configuration du noyau IP à virgule flottante
5. Analyse des résultats de la simulation
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 , 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.
Résumer
Cette fois, nous allons introduire la multiplication de nombres complexes à virgule flottante.