gownianzdupianv2
module complex_mul (
input wire RST,
input wire CLK,
input wire I_STB,
output wire I_ACK,
input wire [31:0] a_real,
input wire [31:0] a_imag,
input wire [31:0] b_real,
input wire [31:0] b_imag,
output reg O_STB,
input wire O_ACK,
output reg [63:0] result_real,
output reg [63:0] result_imag
);
// sygnały mnożenia
wire m1_ack, m2_ack, m3_ack, m4_ack;
wire m1_stb, m2_stb, m3_stb, m4_stb;
wire m1_out_stb, m2_out_stb, m3_out_stb, m4_out_stb;
wire [63:0] m1_res, m2_res, m3_res, m4_res;
assign m1_stb = I_STB;
assign m2_stb = I_STB;
assign m3_stb = I_STB;
assign m4_stb = I_STB;
assign I_ACK = m1_ack & m2_ack & m3_ack & m4_ack;
// mnożenia
multiplier m1 (
.RST(RST), .CLK(CLK),
.I_STB(m1_stb), .I_ACK(m1_ack),
.I_DAT_A(a_real), .I_DAT_B(b_real),
.O_STB(m1_out_stb), .O_ACK(O_ACK),
.O_DAT(m1_res)
);
multiplier m2 (
.RST(RST), .CLK(CLK),
.I_STB(m2_stb), .I_ACK(m2_ack),
.I_DAT_A(a_imag), .I_DAT_B(b_imag),
.O_STB(m2_out_stb), .O_ACK(O_ACK),
.O_DAT(m2_res)
);
multiplier m3 (
.RST(RST), .CLK(CLK),
.I_STB(m3_stb), .I_ACK(m3_ack),
.I_DAT_A(a_real), .I_DAT_B(b_imag),
.O_STB(m3_out_stb), .O_ACK(O_ACK),
.O_DAT(m3_res)
);
multiplier m4 (
.RST(RST), .CLK(CLK),
.I_STB(m4_stb), .I_ACK(m4_ack),
.I_DAT_A(a_imag), .I_DAT_B(b_real),
.O_STB(m4_out_stb), .O_ACK(O_ACK),
.O_DAT(m4_res)
);
// dodawanie ad + bc
wire add1_ack, add1_out_stb;
wire [63:0] add1_res;
adder add1 (
.RST(RST), .CLK(CLK),
.I_STB(m3_out_stb & m4_out_stb), .I_ACK(add1_ack),
.I_DAT_A(m3_res), .I_DAT_B(m4_res),
.O_STB(add1_out_stb), .O_ACK(O_ACK),
.O_DAT(add1_res)
);
// odejmowanie ac - bd = ac + (-bd)
wire sub_ack, sub_out_stb;
wire [63:0] sub_res;
adder sub (
.RST(RST), .CLK(CLK),
.I_STB(m1_out_stb & m2_out_stb), .I_ACK(sub_ack),
.I_DAT_A(m1_res), .I_DAT_B(~m2_res + 1), // negacja bd
.O_STB(sub_out_stb), .O_ACK(O_ACK),
.O_DAT(sub_res)
);
// końcowy zapis wyników
reg done;
always @(posedge CLK or posedge RST) begin
if (RST) begin
O_STB <= 0;
result_real <= 0;
result_imag <= 0;
done <= 0;
end else if (sub_out_stb & add1_out_stb & ~done) begin
result_real <= sub_res;
result_imag <= add1_res;
O_STB <= 1;
done <= 1;
end else if (O_ACK) begin
O_STB <= 0;
done <= 0;
end
end
endmodule