87 lines
3.1 KiB
Verilog
87 lines
3.1 KiB
Verilog
module mult_C #(
|
|
parameter integer A_width = 8
|
|
,parameter integer B_width = 8
|
|
,parameter integer C_width = 8
|
|
,parameter integer D_width = 8
|
|
,parameter integer o_width = 31//division
|
|
|
|
)
|
|
|
|
(
|
|
clk,
|
|
rstn,
|
|
en,
|
|
a,
|
|
b,
|
|
c,
|
|
d,
|
|
Re,
|
|
Im
|
|
);
|
|
|
|
input rstn;
|
|
input clk;
|
|
input en;
|
|
input signed [A_width-1 :0] a;
|
|
input signed [B_width-1 :0] b;
|
|
input signed [C_width-1 :0] c;
|
|
input signed [D_width-1 :0] d;
|
|
|
|
output signed [o_width-1 :0] Re;
|
|
output signed [o_width-1 :0] Im;
|
|
|
|
wire signed [A_width+C_width-1:0] ac;
|
|
wire signed [B_width+D_width-1:0] bd;
|
|
wire signed [A_width+D_width-1:0] ad;
|
|
wire signed [B_width+C_width-1:0] bc;
|
|
wire signed [A_width+C_width :0] Re_tmp;
|
|
wire signed [A_width+D_width :0] Im_tmp;
|
|
wire signed [o_width-1 :0] Re_trunc;
|
|
wire signed [o_width-1 :0] Im_trunc;
|
|
|
|
wire signed [A_width:0] sum_ab;
|
|
wire signed [C_width:0] sum_cd;
|
|
wire signed [A_width+C_width+1:0] product_of_sums;
|
|
|
|
assign sum_ab = a + b;
|
|
assign sum_cd = c + d;
|
|
|
|
|
|
DW02_mult #(A_width,C_width) inst_c1( .A (a ),
|
|
.B (c ),
|
|
.TC (1'b1 ),
|
|
.PRODUCT (ac )
|
|
);
|
|
|
|
DW02_mult #(B_width,D_width) inst_c2( .A (b ),
|
|
.B (d ),
|
|
.TC (1'b1 ),
|
|
.PRODUCT (bd )
|
|
);
|
|
|
|
DW02_mult #(A_width+1,D_width+1) inst_c3( .A (sum_ab ),
|
|
.B (sum_cd ),
|
|
.TC (1'b1 ),
|
|
.PRODUCT (product_of_sums)
|
|
);
|
|
|
|
assign Re_tmp = ac - bd;
|
|
assign Im_tmp = product_of_sums - ac - bd;
|
|
|
|
trunc #(
|
|
.diw (A_width+C_width+1 )
|
|
,.msb (A_width+C_width-2 )
|
|
,.lsb (A_width+C_width-o_width-1 )
|
|
) u_round1 (clk, rstn, en, Re_tmp, Re_trunc);
|
|
trunc #(
|
|
.diw (A_width+D_width+1 )
|
|
,.msb (A_width+D_width-2 )
|
|
,.lsb (A_width+C_width-o_width-1 )
|
|
) u_round2 (clk, rstn, en, Im_tmp, Im_trunc);
|
|
|
|
// Since this is complex multiplication, the output bit width needs to be increased by one compared to the input.
|
|
assign Re = Re_trunc;
|
|
assign Im = Im_trunc;
|
|
|
|
endmodule
|