1、好久没写文章了,有点手生,大家尽量看。本文章代码实现了32位浮点数(即一个复数为64位)的复数计算,且本人实现了32*32复数矩阵的求逆运算,需要的请查看作者资料邮箱。
2、Verilog复数运算
实验任务:实现A=1*4(虚数位32位、实数位32位),B=4*1(虚数位32位、实数位32位)全浮点数复数矩阵计算。本代码并行度高、代码复用性强。
实验软硬件:ZCU106、Vivado 2019.1
实验知识:(a+bi)*(c+di)=(ac-bd) + (bc+ad)i。因此需要4个乘法器,一个减法器,一个加法器。因此需要两步计算即可完成复数乘法计算。网上的变换可以变换为只需要3个乘法器,5个加法器,但是计算时间并没有降低,因此不采用此方法。
实验过程:
①建立工程,complex_multiply。
②添加乘法IP核与加法IP核
③复制代码
`timescale 1ns / 1ps
//
// Company: 东北电力大学
// Engineer: Yang Zheng
//
// Create Date: 2022/02/09 23:09:55
// Design Name:
// Module Name: complex_add_compute
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module complex_add_compute
#(
DW =32//位宽
)(
input clk,
input rst,
input [(DW * 2)-1:0] complex_add_compute_input_A,//高32位是实部,低32位是虚部
input [(DW * 2)-1:0] complex_add_compute_input_B,//高32位是实部,低32位是虚部
output [(DW * 2)-1:0] complex_add_compute_output,//高32位是实部,低32位是虚部
input complex_add_input_valid,//输入开始求解信号
output complex_add_output_valid,//输出求解完毕信号
output complex_add_valid_en//输出此模块可用信号
);
reg [(DW)-1:0] output_real = 'd0;
reg [(DW)-1:0] output_imag = 'd0;
assign complex_add_compute_output = {output_real,output_imag};
reg complex_add_output_valid_r = 1'b0;
reg complex_add_valid_en_r = 1'b1;
assign complex_add_output_valid = complex_add_output_valid_r;
assign complex_add_valid_en = complex_add_valid_en_r;
//初始化输入
reg compute_reshape = 1'b0;
reg [(DW)-1:0] complex_compute_a = 'd0;
reg [(DW)-1:0] complex_compute_b = 'd0;
reg [(DW)-1:0] complex_compute_c = 'd0;
reg [(DW)-1:0] complex_compute_d = 'd0;
always @(posedge clk or negedge rst) begin
if (!rst) begin
//复位
compute_reshape <= 1'b0;
complex_compute_a <= 'd0;
complex_compute_b <= 'd0;
complex_compute_c <= 'd0;
complex_compute_d <= 'd0;
output_real <= 'd0;
output_imag <= 'd0;
end
else if(complex_add_input_valid == 1'b1 && compute_reshape == 1'b0) begin
complex_compute_a <=complex_add_compute_input_A[(DW * 2)-1:DW];
complex_compute_b <=complex_add_compute_input_A[(DW)-1:0];
complex_compute_c <=complex_add_compute_input_B[(DW * 2)-1:DW];
complex_compute_d <=complex_add_compute_input_B[(DW)-1:0];
complex_add_valid_en_r <= 1'b0;
compute_reshape <= 1'b1;
end
end
//例化模块
/*例化2个加法器模块*/
reg aresetn_add = 1'b0;
always @(negedge rst) begin
if (!rst) begin
aresetn_add <= 1'b1;
end
end
reg add_a_tvalid_1 = 1'b0;
reg add_b_tvalid_1 = 1'b0;
reg [31:0] add_a_tdata_1 = 32'b0;
reg [31:0] add_b_tdata_1 = 32'b0;
wire [31:0] add_result_tdata_1;
complex_compute_add uut_complex_compute_add_1(
.aclk(clk),
.aresetn(aresetn_add),
.s_axis_a_tvalid(add_a_tvalid_1),
.s_axis_a_tdata(add_a_tdata_1),
.s_axis_b_tvalid(add_b_tvalid_1),
.s_axis_b_tdata(add_b_tdata_1),
.m_axis_result_tvalid(add_result_tvalid_1),
.m_axis_result_tdata(add_result_tdata_1)
);
reg add_a_tvalid_2 = 1'b0;
reg add_b_tvalid_2 = 1'b0;
reg [31:0] add_a_tdata_2 = 32'b0;
reg [31:0] add_b_tdata_2 = 32'b0;
wire [31:0] add_result_tdata_2;
complex_compute_add uut_complex_compute_add_2(
.aclk(clk),
.aresetn(aresetn_add),
.s_axis_a_tvalid(add_a_tvalid_2),
.s_axis_a_tdata(add_a_tdata_2),
.s_axis_b_tvalid(add_b_tvalid_2),
.s_axis_b_tdata(add_b_tdata_2),
.m_axis_result_tvalid(add_result_tvalid_2),
.m_axis_result_tdata(add_result_tdata_2)
);
//状态机
reg [1:0] st_cur = 'd0;
reg [1:0] st_next = 'd0;
parameter IDLE = 2'd0 ;
parameter ST1 = 2'd1 ;
always @(posedge clk or negedge rst) begin
if (!rst) begin
st_cur <= 'd0;
st_next <= 'd0;
end
else begin
st_cur <= st_next;
end
end
reg ST1_done = 1'b0;
reg ST1_do = 1'b0;
reg [2:0] aresetn_count = 3'b0;
//状态切换
always @(posedge clk) begin
case (st_cur)
IDLE:
if (complex_add_input_valid == 1'b1 && compute_reshape == 1'b1) begin
st_next <= ST1;
ST1_do <= 1'b0;
end
ST1:
if (ST1_done) begin
/*加法器复位*/
aresetn_add <= 1'b0;
aresetn_count <= aresetn_count + 1'b1;
complex_add_output_valid_r <= 1'b1;
if (aresetn_count == 'd3) begin
aresetn_count <= 1'b0;
st_next <= IDLE;
aresetn_add <= 1'b1;
ST1_done <= 1'b0;
complex_add_valid_en_r <= 1'b1;
compute_reshape <= 1'b0;
end
end
default: st_next <= IDLE;
endcase
end
//状态过程
always @(posedge clk or negedge rst) begin
if (!rst) begin
end
else begin
if (st_cur == ST1 && ST1_done == 1'b0 && ST1_do == 1'b0) begin
//计算a+c、b+d
add_a_tvalid_1 <= 1'b1;
add_b_tvalid_1 <= 1'b1;
add_a_tdata_1 <= complex_compute_a;
add_b_tdata_1 <= complex_compute_c;
add_a_tvalid_2 <= 1'b1;
add_b_tvalid_2 <= 1'b1;
add_a_tdata_2 <= complex_compute_b;
add_b_tdata_2 <= complex_compute_d;
ST1_do <= 1'b1;
end
end
end
//状态输出
//ST1 输出
always @(posedge clk or negedge rst) begin
if (!rst) begin
ST1_done <= 1'b0;
end
else begin
if (st_cur == ST1 && add_result_tvalid_1 == 1'b1 && add_result_tvalid_2 == 1'b1
&& ST1_done == 1'b0) begin
ST1_done <= 1'b1;
add_a_tvalid_1 <= 1'b0;
add_b_tvalid_1 <= 1'b0;
add_a_tvalid_2 <= 1'b0;
add_b_tvalid_2 <= 1'b0;
output_real <= add_result_tdata_1;
output_imag <= add_result_tdata_2;
end
end
end
//两个周期的高电平
reg [1:0] complex_add_output_valid_r_count = 2'b0;
always @(posedge clk or negedge rst) begin
if (!rst) begin
complex_add_output_valid_r_count <= 2'b0;
end
else begin
if (complex_add_output_valid_r) begin
complex_add_output_valid_r_count <= complex_add_output_valid_r_count + 1'b1;
if (complex_add_output_valid_r_count == 'd2) begin
complex_add_output_valid_r <= 1'b0;
complex_add_output_valid_r_count <= 2'b0;
end
end
end
end
endmodule
`timescale 1ns / 1ps
//
// Company: 东北电力大学
// Engineer: Yang Zheng
//
// Create Date: 2022/02/09 18:06:18
// Design Name:
// Module Name: complex_multiply_compute
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module complex_multiply_compute
#(
DW =32//位宽
)(
input clk,
input rst,
input [(DW * 2)-1:0] complex_multiply_compute_input_A,//高32位是实部,低32位是虚部
input [(DW * 2)-1:0] complex_multiply_compute_input_B,//高32位是实部,低32位是虚部
output [(DW * 2)-1:0] complex_multiply_compute_output,//高32位是实部,低32位是虚部
input complex_multiply_input_valid,//输入开始求解信号
output complex_multiply_output_valid,//输出求解完毕信号
output complex_multiply_valid_en//输出此模块可用信号
);
reg [(DW)-1:0] output_real = 'd0;
reg [(DW)-1:0] output_imag = 'd0;
assign complex_multiply_compute_output = {output_real,output_imag};
reg complex_multiply_output_valid_r = 1'b0;
reg complex_multiply_valid_en_r = 1'b1;
assign complex_multiply_output_valid = complex_multiply_output_valid_r;
assign complex_multiply_valid_en = complex_multiply_valid_en_r;
//初始化输入
reg compute_reshape = 1'b0;
reg [(DW)-1:0] complex_compute_a = 'd0;
reg [(DW)-1:0] complex_compute_b = 'd0;
reg [(DW)-1:0] complex_compute_c = 'd0;
reg [(DW)-1:0] complex_compute_d = 'd0;
always @(posedge clk or negedge rst) begin
if (!rst) begin
//复位
compute_reshape <= 1'b0;
complex_compute_a <= 'd0;
complex_compute_b <= 'd0;
complex_compute_c <= 'd0;
complex_compute_d <= 'd0;
output_real <= 'd0;
output_imag <= 'd0;
end
else if(complex_multiply_input_valid == 1'b1 && compute_reshape == 1'b0) begin
complex_compute_a <=complex_multiply_compute_input_A[(DW * 2)-1:DW];
complex_compute_b <=complex_multiply_compute_input_A[(DW)-1:0];
complex_compute_c <=complex_multiply_compute_input_B[(DW * 2)-1:DW];
complex_compute_d <=complex_multiply_compute_input_B[(DW)-1:0];
complex_multiply_valid_en_r <= 1'b0;
compute_reshape <= 1'b1;
end
end
//例化模块
/*例化4个乘法模块*/
reg aresetn_multiply = 1'b0;
always @(negedge rst) begin
if (!rst) begin
aresetn_multiply <= 1'b1;//2个低电平复位
end
end
reg multiply_a_tvalid_1 = 1'b0;
reg multiply_b_tvalid_1 = 1'b0;
reg [31:0] multiply_a_tdata_1 = 32'b0;
reg [31:0] multiply_b_tdata_1 = 32'b0;
wire [31:0] multiply_result_tdata_1;
complex_compute_multiply uut_complex_compute_multiply_1(
.aclk(clk),
.aresetn(aresetn_multiply),//低电平复位
.s_axis_a_tvalid(multiply_a_tvalid_1),
.s_axis_a_tdata(multiply_a_tdata_1),
.s_axis_b_tvalid(multiply_b_tvalid_1),
.s_axis_b_tdata(multiply_b_tdata_1),
.m_axis_result_tvalid(multiply_result_tvalid_1),
.m_axis_result_tdata(multiply_result_tdata_1)
);
reg multiply_a_tvalid_2 = 1'b0;
reg multiply_b_tvalid_2 = 1'b0;
reg [31:0] multiply_a_tdata_2 = 32'b0;
reg [31:0] multiply_b_tdata_2 = 32'b0;
wire [31:0] multiply_result_tdata_2;
complex_compute_multiply uut_complex_compute_multiply_2(
.aclk(clk),
.aresetn(aresetn_multiply),//低电平复位
.s_axis_a_tvalid(multiply_a_tvalid_2),
.s_axis_a_tdata(multiply_a_tdata_2),
.s_axis_b_tvalid(multiply_b_tvalid_2),
.s_axis_b_tdata(multiply_b_tdata_2),
.m_axis_result_tvalid(multiply_result_tvalid_2),
.m_axis_result_tdata(multiply_result_tdata_2)
);
reg multiply_a_tvalid_3 = 1'b0;
reg multiply_b_tvalid_3 = 1'b0;
reg [31:0] multiply_a_tdata_3 = 32'b0;
reg [31:0] multiply_b_tdata_3 = 32'b0;
wire [31:0] multiply_result_tdata_3;
complex_compute_multiply uut_complex_compute_multiply_3(
.aclk(clk),
.aresetn(aresetn_multiply),//低电平复位
.s_axis_a_tvalid(multiply_a_tvalid_3),
.s_axis_a_tdata(multiply_a_tdata_3),
.s_axis_b_tvalid(multiply_b_tvalid_3),
.s_axis_b_tdata(multiply_b_tdata_3),
.m_axis_result_tvalid(multiply_result_tvalid_3),
.m_axis_result_tdata(multiply_result_tdata_3)
);
reg multiply_a_tvalid_4 = 1'b0;
reg multiply_b_tvalid_4 = 1'b0;
reg [31:0] multiply_a_tdata_4 = 32'b0;
reg [31:0] multiply_b_tdata_4 = 32'b0;
wire [31:0] multiply_result_tdata_4;
complex_compute_multiply uut_complex_compute_multiply_4(
.aclk(clk),
.aresetn(aresetn_multiply),//低电平复位
.s_axis_a_tvalid(multiply_a_tvalid_4),
.s_axis_a_tdata(multiply_a_tdata_4),
.s_axis_b_tvalid(multiply_b_tvalid_4),
.s_axis_b_tdata(multiply_b_tdata_4),
.m_axis_result_tvalid(multiply_result_tvalid_4),
.m_axis_result_tdata(multiply_result_tdata_4)
);
/*例化1个减法模块*/
reg aresetn_subtract = 1'b0;
always @(negedge rst) begin
if (!rst) begin
aresetn_subtract <= 1'b1;//2个低电平复位
end
end
reg subtract_a_tvalid = 1'b0;
reg subtract_b_tvalid = 1'b0;
reg [31:0] subtract_a_tdata = 32'b0;
reg [31:0] subtract_b_tdata = 32'b0;
wire [31:0] subtract_result_tdata;
complex_compute_subtract uut_complex_compute_subtract(
.aclk(clk),
.aresetn(aresetn_subtract),
.s_axis_a_tvalid(subtract_a_tvalid),
.s_axis_a_tdata(subtract_a_tdata),
.s_axis_b_tvalid(subtract_b_tvalid),
.s_axis_b_tdata(subtract_b_tdata),
.m_axis_result_tvalid(subtract_result_tvalid),
.m_axis_result_tdata(subtract_result_tdata)
);
/*例化1个加法模块*/
reg aresetn_add = 1'b0;
always @(negedge rst) begin
if (!rst) begin
aresetn_add <= 1'b1;//2个低电平复位
end
end
reg add_a_tvalid = 1'b0;
reg add_b_tvalid = 1'b0;
reg [31:0] add_a_tdata = 32'b0;
reg [31:0] add_b_tdata = 32'b0;
wire [31:0] add_result_tdata;
complex_compute_add uut_complex_compute_add(
.aclk(clk),
.aresetn(aresetn_add),
.s_axis_a_tvalid(add_a_tvalid),
.s_axis_a_tdata(add_a_tdata),
.s_axis_b_tvalid(add_b_tvalid),
.s_axis_b_tdata(add_b_tdata),
.m_axis_result_tvalid(add_result_tvalid),
.m_axis_result_tdata(add_result_tdata)
);
//状态机
reg [1:0] st_cur = 'd0;
reg [1:0] st_next = 'd0;
parameter IDLE = 2'd0 ;
parameter ST1 = 2'd1 ;
parameter ST2 = 2'd2 ;
always @(posedge clk or negedge rst) begin
if (!rst) begin
st_cur <= 'd0;
st_next <= 'd0;
end
else begin
st_cur <= st_next;
end
end
reg ST1_done = 1'b0;
reg ST2_done = 1'b0;
reg [2:0] aresetn_count = 3'b0;
reg ST1_do = 1'b0;
reg ST2_do = 1'b0;
//状态切换
always @(posedge clk) begin
case (st_cur)
IDLE:
if (complex_multiply_input_valid == 1'b1 && compute_reshape == 1'b1) begin
st_next <= ST1;
ST1_do <= 1'b0;
ST2_do <= 1'b0;
end
ST1:
if (ST1_done) begin
/*乘法器复位*/
aresetn_multiply <= 1'b0;
aresetn_count <= aresetn_count + 1'b1;
if (aresetn_count == 'd3) begin
aresetn_count <= 1'b0;
st_next <= ST2;
aresetn_multiply <= 1'b1;
ST1_done <= 1'b0;
end
end
ST2:
if (ST2_done) begin
/*加法器与减法器复位*/
aresetn_add <= 1'b0;
aresetn_subtract <= 1'b0;
aresetn_count <= aresetn_count + 1'b1;
complex_multiply_output_valid_r <= 1'b1;
if (aresetn_count == 'd3) begin
aresetn_count <= 1'b0;
st_next <= IDLE;
aresetn_add <= 1'b1;
aresetn_subtract <= 1'b1;
ST2_done <= 1'b0;
complex_multiply_valid_en_r <= 1'b1;
compute_reshape <= 1'b0;
end
end
default: st_next <= IDLE;
endcase
end
reg [31:0] multiply_result [3:0];//记录乘法结果,防止乘法器复位结果被重置
//状态过程
always @(posedge clk or negedge rst) begin
if (!rst) begin
end
else begin
if (st_cur == ST1 && ST1_done == 1'b0 && ST1_do == 1'b0) begin
//计算a*c、b*d、b*c、a*d
multiply_a_tvalid_1 <= 1'b1;
multiply_b_tvalid_1 <= 1'b1;
multiply_a_tdata_1 <= complex_compute_a;
multiply_b_tdata_1 <= complex_compute_c;
multiply_a_tvalid_2 <= 1'b1;
multiply_b_tvalid_2 <= 1'b1;
multiply_a_tdata_2 <= complex_compute_b;
multiply_b_tdata_2 <= complex_compute_d;
multiply_a_tvalid_3 <= 1'b1;
multiply_b_tvalid_3 <= 1'b1;
multiply_a_tdata_3 <= complex_compute_b;
multiply_b_tdata_3 <= complex_compute_c;
multiply_a_tvalid_4 <= 1'b1;
multiply_b_tvalid_4 <= 1'b1;
multiply_a_tdata_4 <= complex_compute_a;
multiply_b_tdata_4 <= complex_compute_d;
ST1_do <= 1'b1;
end
else if(st_cur == ST2 && ST2_done == 1'b0 && ST2_do == 1'b0) begin
//计算a*c-b*d、b*c+a*d
subtract_a_tvalid <= 1'b1;
subtract_b_tvalid <= 1'b1;
subtract_a_tdata <= multiply_result[0];
subtract_b_tdata <= multiply_result[1];
add_a_tvalid <= 1'b1;
add_b_tvalid <= 1'b1;
add_a_tdata <= multiply_result[2];
add_b_tdata <= multiply_result[3];
ST2_do <= 1'b1;
end
end
end
//状态输出
//ST1 输出
always @(posedge clk or negedge rst) begin
if (!rst) begin
ST1_done <= 1'b0;
multiply_result[0] <= 32'b0;
multiply_result[1] <= 32'b0;
multiply_result[2] <= 32'b0;
multiply_result[3] <= 32'b0;
end
else begin
if (st_cur == ST1 && multiply_result_tvalid_1 == 1'b1 && multiply_result_tvalid_2 == 1'b1
&& multiply_result_tvalid_3 == 1'b1 && multiply_result_tvalid_4 == 1'b1 && ST1_done == 1'b0) begin
ST1_done <= 1'b1;
multiply_a_tvalid_1 <= 1'b0;
multiply_b_tvalid_1 <= 1'b0;
multiply_a_tvalid_2 <= 1'b0;
multiply_b_tvalid_2 <= 1'b0;
multiply_a_tvalid_3 <= 1'b0;
multiply_b_tvalid_3 <= 1'b0;
multiply_a_tvalid_4 <= 1'b0;
multiply_b_tvalid_4 <= 1'b0;
{multiply_result[0],multiply_result[1],multiply_result[2],multiply_result[3]} <=
{multiply_result_tdata_1,
multiply_result_tdata_2,
multiply_result_tdata_3,
multiply_result_tdata_4};
end
end
end
//ST2 输出
always @(posedge clk or negedge rst) begin
if (!rst) begin
ST2_done <= 1'b0;
end
else begin
if (st_cur == ST2 && add_result_tvalid == 1'b1 && subtract_result_tvalid == 1'b1
&& ST2_done == 1'b0) begin
ST2_done <= 1'b1;
add_a_tvalid <= 1'b0;
add_b_tvalid <= 1'b0;
subtract_a_tvalid <= 1'b0;
subtract_b_tvalid <= 1'b0;
output_real <= subtract_result_tdata;
output_imag <= add_result_tdata;
end
end
end
//两个周期的高电平
reg [1:0] complex_multiply_output_valid_r_count = 2'b0;
always @(posedge clk or negedge rst) begin
if (!rst) begin
complex_multiply_output_valid_r_count <= 2'b0;
end
else begin
if (complex_multiply_output_valid_r) begin
complex_multiply_output_valid_r_count <= complex_multiply_output_valid_r_count + 1'b1;
if (complex_multiply_output_valid_r_count == 'd2) begin
complex_multiply_output_valid_r <= 1'b0;
complex_multiply_output_valid_r_count <= 2'b0;
end
end
end
end
endmodule
`timescale 1ns / 1ps
//
// Company: 东北电力大学
// Engineer: Yang Zheng
//
// Create Date: 2022/02/09 16:40:48
// Design Name:
// Module Name: complex_multiply_14_41
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module complex_multiply_14_41
#(
M = 1,//矩阵变化就需要更改
N = 4,//矩阵变化就需要更改
DW =32//位宽
)(
input clk,
input rst,
input [(DW * M * N)*2-1:0] complex_matrix_compute_input_A,//高32位是实部,低32位是虚部 1行4列 4个复数
input [(DW * N * M)*2-1:0] complex_matrix_compute_input_B,//高32位是实部,低32位是虚部 4行1列 4个复数
output [(DW)*2-1:0] complex_matrix_compute_output,//高32位是实部,低32位是虚部
input complex_matrix_multiply_input_valid,//输入开始求解信号
output complex_matrix_multiply_output_valid,//输出求解完毕信号
output complex_matrix_multiply_valid_en//输出此模块可用信号
);
reg [(DW)*2-1:0] complex_matrix_compute_output_r = 'd0;
assign complex_matrix_compute_output = complex_matrix_compute_output_r;
reg complex_matrix_multiply_output_valid_r = 1'b0;
reg complex_matrix_multiply_valid_en_r = 1'b1;
assign complex_matrix_multiply_output_valid = complex_matrix_multiply_output_valid_r;
assign complex_matrix_multiply_valid_en = complex_matrix_multiply_valid_en_r;
//初始化输入
reg compute_reshape = 1'b0;
reg [(DW)*2-1:0] complex_compute_a1 = 'd0;
reg [(DW)*2-1:0] complex_compute_a2 = 'd0;
reg [(DW)*2-1:0] complex_compute_a3 = 'd0;
reg [(DW)*2-1:0] complex_compute_a4 = 'd0;
reg [(DW)*2-1:0] complex_compute_b1 = 'd0;
reg [(DW)*2-1:0] complex_compute_b2 = 'd0;
reg [(DW)*2-1:0] complex_compute_b3 = 'd0;
reg [(DW)*2-1:0] complex_compute_b4 = 'd0;
always @(posedge clk or negedge rst) begin
if (!rst) begin
//复位
compute_reshape <= 1'b0;
complex_compute_a1 <= 'd0;
complex_compute_a2 <= 'd0;
complex_compute_a3 <= 'd0;
complex_compute_a4 <= 'd0;
complex_compute_b1 <= 'd0;
complex_compute_b2 <= 'd0;
complex_compute_b3 <= 'd0;
complex_compute_b4 <= 'd0;
complex_matrix_compute_output_r <= 'd0;
end
else if(complex_matrix_multiply_input_valid == 1'b1 && compute_reshape == 1'b0) begin
complex_compute_a1 <= complex_matrix_compute_input_A[(DW * 8)-1:(DW * 6)];
complex_compute_a2 <= complex_matrix_compute_input_A[(DW * 6)-1:(DW * 4)];
complex_compute_a3 <= complex_matrix_compute_input_A[(DW * 4)-1:(DW * 2)];
complex_compute_a4 <= complex_matrix_compute_input_A[(DW * 2)-1:(DW * 0)];
complex_compute_b1 <= complex_matrix_compute_input_B[(DW * 8)-1:(DW * 6)];
complex_compute_b2 <= complex_matrix_compute_input_B[(DW * 6)-1:(DW * 4)];
complex_compute_b3 <= complex_matrix_compute_input_B[(DW * 4)-1:(DW * 2)];
complex_compute_b4 <= complex_matrix_compute_input_B[(DW * 2)-1:(DW * 0)];
complex_matrix_multiply_valid_en_r <= 1'b0;
compute_reshape <= 1'b1;
end
end
//例化模块
/*例化2个复数加法模块*/
reg [63:0] complex_add_compute_input_A_1;
reg [63:0] complex_add_compute_input_B_1;
reg complex_add_input_valid_1;
wire [63:0] complex_add_compute_output_1;
complex_add_compute uut_complex_add_compute_1(
.clk(clk),
.rst(rst),
.complex_add_compute_input_A(complex_add_compute_input_A_1),//高32位是实部,低32位是虚部
.complex_add_compute_input_B(complex_add_compute_input_B_1),//高32位是实部,低32位是虚部
.complex_add_compute_output(complex_add_compute_output_1),//高32位是实部,低32位是虚部
.complex_add_input_valid(complex_add_input_valid_1),//输入开始求解信号
.complex_add_output_valid(complex_add_output_valid_1),//输出求解完毕信号
.complex_add_valid_en(complex_add_valid_en_1)//输出此模块可用信号
);
reg [63:0] complex_add_compute_input_A_2;
reg [63:0] complex_add_compute_input_B_2;
reg complex_add_input_valid_2;
wire [63:0] complex_add_compute_output_2;
complex_add_compute uut_complex_add_compute_2(
.clk(clk),
.rst(rst),
.complex_add_compute_input_A(complex_add_compute_input_A_2),//高32位是实部,低32位是虚部
.complex_add_compute_input_B(complex_add_compute_input_B_2),//高32位是实部,低32位是虚部
.complex_add_compute_output(complex_add_compute_output_2),//高32位是实部,低32位是虚部
.complex_add_input_valid(complex_add_input_valid_2),//输入开始求解信号
.complex_add_output_valid(complex_add_output_valid_2),//输出求解完毕信号
.complex_add_valid_en(complex_add_valid_en_2)//输出此模块可用信号
);
/*例化4个复数乘法器*/
reg [63:0] complex_multiply_compute_input_A_1;
reg [63:0] complex_multiply_compute_input_B_1;
reg complex_multiply_input_valid_1;
wire [63:0] complex_multiply_compute_output_1;
complex_multiply_compute uut_complex_multiply_compute_1(
.clk(clk),
.rst(rst),
.complex_multiply_compute_input_A(complex_multiply_compute_input_A_1),//高32位是实部,低32位是虚部
.complex_multiply_compute_input_B(complex_multiply_compute_input_B_1),//高32位是实部,低32位是虚部
.complex_multiply_compute_output(complex_multiply_compute_output_1),//高32位是实部,低32位是虚部
.complex_multiply_input_valid(complex_multiply_input_valid_1),//输入开始求解信号
.complex_multiply_output_valid(complex_multiply_output_valid_1),//输出求解完毕信号
.complex_multiply_valid_en(complex_multiply_valid_en_1)//输出此模块可用信号
);
reg [63:0] complex_multiply_compute_input_A_2;
reg [63:0] complex_multiply_compute_input_B_2;
reg complex_multiply_input_valid_2;
wire [63:0] complex_multiply_compute_output_2;
complex_multiply_compute uut_complex_multiply_compute_2(
.clk(clk),
.rst(rst),
.complex_multiply_compute_input_A(complex_multiply_compute_input_A_2),//高32位是实部,低32位是虚部
.complex_multiply_compute_input_B(complex_multiply_compute_input_B_2),//高32位是实部,低32位是虚部
.complex_multiply_compute_output(complex_multiply_compute_output_2),//高32位是实部,低32位是虚部
.complex_multiply_input_valid(complex_multiply_input_valid_2),//输入开始求解信号
.complex_multiply_output_valid(complex_multiply_output_valid_2),//输出求解完毕信号
.complex_multiply_valid_en(complex_multiply_valid_en_2)//输出此模块可用信号
);
reg [63:0] complex_multiply_compute_input_A_3;
reg [63:0] complex_multiply_compute_input_B_3;
reg complex_multiply_input_valid_3;
wire [63:0] complex_multiply_compute_output_3;
complex_multiply_compute uut_complex_multiply_compute_3(
.clk(clk),
.rst(rst),
.complex_multiply_compute_input_A(complex_multiply_compute_input_A_3),//高32位是实部,低32位是虚部
.complex_multiply_compute_input_B(complex_multiply_compute_input_B_3),//高32位是实部,低32位是虚部
.complex_multiply_compute_output(complex_multiply_compute_output_3),//高32位是实部,低32位是虚部
.complex_multiply_input_valid(complex_multiply_input_valid_3),//输入开始求解信号
.complex_multiply_output_valid(complex_multiply_output_valid_3),//输出求解完毕信号
.complex_multiply_valid_en(complex_multiply_valid_en_3)//输出此模块可用信号
);
reg [63:0] complex_multiply_compute_input_A_4;
reg [63:0] complex_multiply_compute_input_B_4;
reg complex_multiply_input_valid_4;
wire [63:0] complex_multiply_compute_output_4;
complex_multiply_compute uut_complex_multiply_compute_4(
.clk(clk),
.rst(rst),
.complex_multiply_compute_input_A(complex_multiply_compute_input_A_4),//高32位是实部,低32位是虚部
.complex_multiply_compute_input_B(complex_multiply_compute_input_B_4),//高32位是实部,低32位是虚部
.complex_multiply_compute_output(complex_multiply_compute_output_4),//高32位是实部,低32位是虚部
.complex_multiply_input_valid(complex_multiply_input_valid_4),//输入开始求解信号
.complex_multiply_output_valid(complex_multiply_output_valid_4),//输出求解完毕信号
.complex_multiply_valid_en(complex_multiply_valid_en_4)//输出此模块可用信号
);
//状态机
reg [1:0] st_cur = 'd0;
reg [1:0] st_next = 'd0;
parameter IDLE = 2'd0 ;
parameter ST1 = 2'd1 ;
parameter ST2 = 2'd2 ;
parameter ST3 = 2'd3 ;
always @(posedge clk or negedge rst) begin
if (!rst) begin
st_cur <= 'd0;
st_next <= 'd0;
end
else begin
st_cur <= st_next;
end
end
reg ST1_done = 1'b0;
reg ST2_done = 1'b0;
reg ST3_done = 1'b0;
reg [2:0] aresetn_count = 3'b0;
reg ST1_do = 1'b0;
reg ST2_do = 1'b0;
reg ST3_do = 1'b0;
//状态切换
always @(posedge clk) begin
case (st_cur)
IDLE:
if (complex_matrix_multiply_input_valid == 1'b1 && compute_reshape == 1'b1) begin
st_next <= ST1;
ST1_do <= 1'b0;
ST2_do <= 1'b0;
ST3_do <= 1'b0;
ST1_done <= 1'b0;
ST2_done <= 1'b0;
ST3_done <= 1'b0;
end
ST1:
if (ST1_done) begin
/*乘法器复位*/
if (complex_multiply_valid_en_1 == 1'b1 && complex_multiply_valid_en_2 == 1'b1
&& complex_multiply_valid_en_3 == 1'b1 && complex_multiply_valid_en_4 == 1'b1) begin
st_next <= ST2;
end
end
ST2:
if (ST2_done) begin
/*加法器复位*/
if (complex_add_valid_en_1 == 1'b1 && complex_add_valid_en_2 == 1'b1) begin
st_next <= ST3;
end
end
ST3:
if (ST3_done) begin
/*加法器复位*/
complex_matrix_multiply_output_valid_r <= 1'b1;
if (complex_add_valid_en_1 == 1'b1) begin
st_next <= IDLE;
complex_matrix_multiply_valid_en_r <= 1'b1;
compute_reshape <= 1'b0;
end
end
default: st_next <= IDLE;
endcase
end
reg [63:0] multiply_result [3:0];//记录乘法结果,防止乘法器复位结果被重置
reg [63:0] add_result [1:0];//记录乘法结果,防止加法器复位结果被重置
//状态过程
always @(posedge clk or negedge rst) begin
if (!rst) begin
end
else begin
if (st_cur == ST1 && ST1_done == 1'b0 && ST1_do == 1'b0
&& complex_multiply_valid_en_1 == 1'b1 && complex_multiply_valid_en_2 == 1'b1
&& complex_multiply_valid_en_3 == 1'b1 && complex_multiply_valid_en_4 == 1'b1) begin
//计算a1*b1、a2*b2、a3*b3、a4*b4
complex_multiply_input_valid_1 <= 1'b1;
complex_multiply_compute_input_A_1 <= complex_compute_a1;
complex_multiply_compute_input_B_1 <= complex_compute_b1;
complex_multiply_input_valid_2 <= 1'b1;
complex_multiply_compute_input_A_2 <= complex_compute_a2;
complex_multiply_compute_input_B_2 <= complex_compute_b2;
complex_multiply_input_valid_3 <= 1'b1;
complex_multiply_compute_input_A_3 <= complex_compute_a3;
complex_multiply_compute_input_B_3 <= complex_compute_b3;
complex_multiply_input_valid_4 <= 1'b1;
complex_multiply_compute_input_A_4 <= complex_compute_a4;
complex_multiply_compute_input_B_4 <= complex_compute_b4;
ST1_do <= 1'b1;
end
else if(st_cur == ST2 && ST2_done == 1'b0 && ST2_do == 1'b0
&& complex_add_valid_en_1 == 1'b1 && complex_add_valid_en_2 == 1'b1) begin
//计算a1*b1+a2*b2、a3*b3+a4*b4
complex_add_input_valid_1 <= 1'b1;
complex_add_compute_input_A_1 <= multiply_result[0];
complex_add_compute_input_B_1 <= multiply_result[1];
complex_add_input_valid_2 <= 1'b1;
complex_add_compute_input_A_2 <= multiply_result[2];
complex_add_compute_input_B_2 <= multiply_result[3];
ST2_do <= 1'b1;
end
else if(st_cur == ST3 && ST3_done == 1'b0 && ST3_do == 1'b0
&& complex_add_valid_en_1 == 1'b1) begin
//计算a1*b1+a2*b2+a3*b3+a4*b4
complex_add_input_valid_1 <= 1'b1;
complex_add_compute_input_A_1 <= add_result[0];
complex_add_compute_input_B_1 <= add_result[1];
ST3_do <= 1'b1;
end
end
end
//状态输出
//ST1 输出
always @(posedge clk or negedge rst) begin
if (!rst) begin
ST1_done <= 1'b0;
multiply_result[0] <= 32'b0;
multiply_result[1] <= 32'b0;
multiply_result[2] <= 32'b0;
multiply_result[3] <= 32'b0;
end
else begin
if (st_cur == ST1 && complex_multiply_output_valid_1 == 1'b1 && complex_multiply_output_valid_2 == 1'b1
&& complex_multiply_output_valid_3 == 1'b1 && complex_multiply_output_valid_4 == 1'b1 && ST1_done == 1'b0) begin
ST1_done <= 1'b1;
complex_multiply_input_valid_1 <= 1'b0;
complex_multiply_input_valid_2 <= 1'b0;
complex_multiply_input_valid_3 <= 1'b0;
complex_multiply_input_valid_4 <= 1'b0;
{multiply_result[0],multiply_result[1],multiply_result[2],multiply_result[3]} <=
{complex_multiply_compute_output_1,
complex_multiply_compute_output_2,
complex_multiply_compute_output_3,
complex_multiply_compute_output_4};
end
end
end
//ST2 输出
always @(posedge clk or negedge rst) begin
if (!rst) begin
ST2_done <= 1'b0;
add_result[0] <= 32'b0;
add_result[1] <= 32'b0;
end
else begin
if (st_cur == ST2 && complex_add_output_valid_1 == 1'b1 && complex_add_output_valid_2 == 1'b1
&& ST2_done == 1'b0) begin
ST2_done <= 1'b1;
complex_add_input_valid_1 <= 1'b0;
complex_add_input_valid_2 <= 1'b0;
{add_result[0],add_result[1]} <=
{complex_add_compute_output_1,
complex_add_compute_output_2};
end
end
end
//ST3 输出
always @(posedge clk or negedge rst) begin
if (!rst) begin
ST3_done <= 1'b0;
end
else begin
if (st_cur == ST3 && complex_add_output_valid_1 == 1'b1
&& ST3_done == 1'b0) begin
ST3_done <= 1'b1;
complex_add_input_valid_1 <= 1'b0;
complex_matrix_compute_output_r <= complex_add_compute_output_1;
end
end
end
//两个周期的高电平
reg [1:0] complex_multiply_output_valid_r_count = 2'b0;
always @(posedge clk or negedge rst) begin
if (!rst) begin
complex_multiply_output_valid_r_count <= 2'b0;
end
else begin
if (complex_matrix_multiply_output_valid_r) begin
complex_multiply_output_valid_r_count <= complex_multiply_output_valid_r_count + 1'b1;
if (complex_multiply_output_valid_r_count == 'd2) begin
complex_matrix_multiply_output_valid_r <= 1'b0;
complex_multiply_output_valid_r_count <= 2'b0;
end
end
end
end
endmodule
④testbench
`timescale 1ns / 1ps
//
// Company: 东北电力大学
// Engineer: Yang Zheng
//
// Create Date: 2022/02/09 20:43:08
// 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;
reg rst;
always #5 clk =~ clk;
initial begin
clk = 1'b0;
rst = 1'b0;
#100;
rst = 1'b1;
end
reg [63:0] complex_multiply_compute_input_A;
reg [63:0] complex_multiply_compute_input_B;
reg complex_multiply_input_valid;
wire [63:0] complex_multiply_compute_output;
complex_multiply_compute uut_complex_multiply_compute(
.clk(clk),
.rst(rst),
.complex_multiply_compute_input_A(complex_multiply_compute_input_A),//高32位是实部,低32位是虚部
.complex_multiply_compute_input_B(complex_multiply_compute_input_B),//高32位是实部,低32位是虚部
.complex_multiply_compute_output(complex_multiply_compute_output),//高32位是实部,低32位是虚部
.complex_multiply_input_valid(complex_multiply_input_valid),//输入开始求解信号
.complex_multiply_output_valid(complex_multiply_output_valid),//输出求解完毕信号
.complex_multiply_valid_en(complex_multiply_valid_en)//输出此模块可用信号
);
always @(posedge clk or negedge rst) begin
if (!rst) begin
//复位
end
else begin
/*
>> (2.6+7.5i)*(6.4-3.8i)
ans =
1.8056e+02 + 1.5248e+02i (42348f5c+42187ae2i)
>>
*/
if (complex_multiply_valid_en) begin
complex_multiply_compute_input_A <= {32'h40266666,32'h40f00000};
complex_multiply_compute_input_B <= {32'h40cccccd,32'hc0733333};
complex_multiply_input_valid <= 1'b1;
end
end
end
reg [63:0] complex_add_compute_input_A;
reg [63:0] complex_add_compute_input_B;
reg complex_add_input_valid;
wire [63:0] complex_add_compute_output;
complex_add_compute uut_complex_add_compute(
.clk(clk),
.rst(rst),
.complex_add_compute_input_A(complex_add_compute_input_A),//高32位是实部,低32位是虚部
.complex_add_compute_input_B(complex_add_compute_input_B),//高32位是实部,低32位是虚部
.complex_add_compute_output(complex_add_compute_output),//高32位是实部,低32位是虚部
.complex_add_input_valid(complex_add_input_valid),//输入开始求解信号
.complex_add_output_valid(complex_add_output_valid),//输出求解完毕信号
.complex_add_valid_en(complex_add_valid_en)//输出此模块可用信号
);
always @(posedge clk or negedge rst) begin
if (!rst) begin
//复位
end
else begin
/*>> (2.6+7.5i)+(6.4-3.8i)
ans =
9.0000 + 3.7000i (41100000+406ccccdi)
*/
if (complex_add_valid_en) begin
complex_add_compute_input_A <= {32'h40266666,32'h40f00000};
complex_add_compute_input_B <= {32'h40cccccd,32'hc0733333};
complex_add_input_valid <= 1'b1;
end
end
end
reg [32*4*2-1:0] complex_matrix_compute_input_A;
reg [32*4*2-1:0] complex_matrix_compute_input_B;
reg complex_matrix_multiply_input_valid;
wire [63:0] complex_matrix_compute_output;
complex_multiply_14_41 uut_complex_multiply_14_41(
.clk(clk),
.rst(rst),
.complex_matrix_compute_input_A(complex_matrix_compute_input_A),//高32位是实部,低32位是虚部
.complex_matrix_compute_input_B(complex_matrix_compute_input_B),//高32位是实部,低32位是虚部
.complex_matrix_compute_output(complex_matrix_compute_output),//高32位是实部,低32位是虚部
.complex_matrix_multiply_input_valid(complex_matrix_multiply_input_valid),//输入开始求解信号
.complex_matrix_multiply_output_valid(complex_matrix_multiply_output_valid),//输出求解完毕信号
.complex_matrix_multiply_valid_en(complex_matrix_multiply_valid_en)//输出此模块可用信号
);
always @(posedge clk or negedge rst) begin
if (!rst) begin
//复位
end
else begin
/*
>> (2.6+7.5i)*(6.4-3.8i)*4
ans =
1.8056e+02 + 1.5248e+02i (43348f5c+43187ae2i)
>>
*/
if (complex_matrix_multiply_valid_en) begin
complex_matrix_compute_input_A <= {32'h40266666,32'h40f00000,32'h40266666,32'h40f00000,32'h40266666,32'h40f00000,32'h40266666,32'h40f00000};
complex_matrix_compute_input_B <= {32'h40cccccd,32'hc0733333,32'h40cccccd,32'hc0733333,32'h40cccccd,32'hc0733333,32'h40cccccd,32'hc0733333};
complex_matrix_multiply_input_valid <= 1'b1;
end
end
end
endmodule
⑤结果
3、声明
代码全部由东北电力大学Yang Zheng亲自开发验证,开源也用于大家学习用途,版权归本人所有,转载时请注明出处,请不要用于任何商业用途!