Line 34... |
Line 34... |
//
|
//
|
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
//
|
//
|
//
|
//
|
module bigsmpy(i_clk, i_sync, i_sgn, i_a, i_b, o_r, o_sync);
|
module bigsmpy(i_clk, i_sync, i_sgn, i_a, i_b, o_r, o_sync);
|
|
parameter CLOCKS = 1;
|
input i_clk, i_sync, i_sgn;
|
input i_clk, i_sync, i_sgn;
|
input [31:0] i_a, i_b;
|
input [31:0] i_a, i_b;
|
output reg [63:0] o_r;
|
output reg [63:0] o_r;
|
output reg o_sync;
|
output reg o_sync;
|
|
|
|
generate
|
|
if (CLOCKS == 1)
|
|
begin
|
|
wire signed [31:0] w_sa, w_sb;
|
|
wire [31:0] w_ua, w_ub;
|
|
|
|
assign w_sa = i_a;
|
|
assign w_sb = i_b;
|
|
assign w_ua = i_a;
|
|
assign w_ub = i_b;
|
|
|
|
always @(posedge i_clk)
|
|
begin
|
|
o_sync <= i_sync;
|
|
if (i_sgn)
|
|
o_r <= w_sa * w_sb;
|
|
else
|
|
o_r <= w_ua * w_ub;
|
|
end
|
|
|
|
end else if (CLOCKS == 2)
|
|
begin
|
|
reg signed [31:0] r_sa, r_sb;
|
|
wire [31:0] w_ua, w_ub;
|
|
|
|
always @(posedge i_clk)
|
|
begin
|
|
r_sa = i_a;
|
|
r_sb = i_b;
|
|
end
|
|
|
|
assign w_ua = r_sa;
|
|
assign w_ub = r_sb;
|
|
|
|
always @(posedge i_clk)
|
|
begin
|
|
o_sync <= i_sync;
|
|
if (i_sgn)
|
|
o_r <= r_sa * r_sb;
|
|
else
|
|
o_r <= w_ua * w_ub;
|
|
end
|
|
|
|
|
|
end else if (CLOCKS == 5)
|
|
begin
|
|
//
|
|
// A pipeline, shift register, to track our
|
|
// synchronization pulse as it transits our pipeline
|
//
|
//
|
// A pipeline, shift register, to track our synchronization pulse
|
|
reg [3:0] r_s;
|
reg [3:0] r_s;
|
|
|
//
|
//
|
|
// Clock #1: Register our inputs, copy the value of the sign
|
|
// bit.
|
reg r_mpy_signed;
|
reg r_mpy_signed;
|
reg [31:0] r_mpy_a_input, r_mpy_b_input;
|
reg [31:0] r_mpy_a_input, r_mpy_b_input;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
begin
|
begin
|
if (i_sgn)
|
if (i_sgn)
|
begin
|
begin
|
|
// This is about more than making the inputs
|
|
// unsigned, as you'll notice it makes positive
|
|
// inputs otherwise negative. Instead,
|
|
// this is about making the inputs have offset
|
|
// mode. Hence
|
|
// i_a = r_mpy_a_input - 2^31
|
|
// and so forth
|
r_mpy_a_input <= {(~i_a[31]), i_a[30:0] };
|
r_mpy_a_input <= {(~i_a[31]), i_a[30:0] };
|
r_mpy_b_input <= {(~i_b[31]), i_b[30:0] };
|
r_mpy_b_input <= {(~i_b[31]), i_b[30:0] };
|
end else begin
|
end else begin
|
r_mpy_a_input <= i_a[31:0];
|
r_mpy_a_input <= i_a[31:0];
|
r_mpy_b_input <= i_b[31:0];
|
r_mpy_b_input <= i_b[31:0];
|
Line 95... |
Line 153... |
reg [31:0] partial_mpy_2lo, partial_mpy_2hi;
|
reg [31:0] partial_mpy_2lo, partial_mpy_2hi;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
begin
|
begin
|
partial_mpy_2lo[15:0] <= partial_mpy_lo[15:0];
|
partial_mpy_2lo[15:0] <= partial_mpy_lo[15:0];
|
{ partial_mpy_2cl, partial_mpy_2lo[31:16] }
|
{ partial_mpy_2cl, partial_mpy_2lo[31:16] }
|
<= { 1'b0, partial_mpy_oi[15:0]}+ partial_mpy_lo[32:16];
|
<= { 1'b0, partial_mpy_oi[15:0]}
|
|
+ partial_mpy_lo[32:16];
|
{ partial_mpy_2ch, partial_mpy_2hi[16:0] }
|
{ partial_mpy_2ch, partial_mpy_2hi[16:0] }
|
<= partial_mpy_oi[32:16] + partial_mpy_hi[16:0];
|
<= partial_mpy_oi[32:16] + partial_mpy_hi[16:0];
|
partial_mpy_2hi[31:16] <= { partial_mpy_2hi[31:17], 1'b0 };
|
partial_mpy_2hi[31:16] <= { partial_mpy_2hi[31:17],
|
|
1'b0 };
|
r_s[3] <= r_s[2];
|
r_s[3] <= r_s[2];
|
end
|
end
|
|
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
begin
|
begin
|
o_r[31: 0] <= partial_mpy_2lo[31:0];
|
o_r[31: 0] <= partial_mpy_2lo[31:0];
|
o_r[63:32] <= partial_mpy_2hi
|
o_r[63:32] <= partial_mpy_2hi
|
+ { 13'h0, partial_mpy_2ch, 1'b0,
|
+ { 14'h0, partial_mpy_2ch, 1'b0,
|
15'h0, partial_mpy_2cl };
|
15'h0, partial_mpy_2cl };
|
o_sync <= r_s[3];
|
o_sync <= r_s[3];
|
end
|
end
|
|
end endgenerate
|
|
|
|
|
endmodule
|
endmodule
|
|
|
No newline at end of file
|
No newline at end of file
|