aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/common
diff options
context:
space:
mode:
authorEddie Hung <eddie@fpgeh.com>2019-07-19 11:39:24 -0700
committerEddie Hung <eddie@fpgeh.com>2019-07-19 11:39:24 -0700
commit1d14cec7fd41710aba0bb910a82fa5ca81c4adb0 (patch)
tree32d7bf7782ec60cb4a61acba291ab3d4238df76f /techlibs/common
parent9ad11ea2cc25f764bcd4e27dfc12c0f8041cb48a (diff)
downloadyosys-1d14cec7fd41710aba0bb910a82fa5ca81c4adb0.tar.gz
yosys-1d14cec7fd41710aba0bb910a82fa5ca81c4adb0.tar.bz2
yosys-1d14cec7fd41710aba0bb910a82fa5ca81c4adb0.zip
Add a DSP_MINWIDTH macro, and soft-logic for {A_WIDTH,B_WIDTH} <= 1 too
Diffstat (limited to 'techlibs/common')
-rw-r--r--techlibs/common/mul2dsp.v96
1 files changed, 68 insertions, 28 deletions
diff --git a/techlibs/common/mul2dsp.v b/techlibs/common/mul2dsp.v
index b6aa02834..aab568c9f 100644
--- a/techlibs/common/mul2dsp.v
+++ b/techlibs/common/mul2dsp.v
@@ -28,27 +28,11 @@ module \$mul (A, B, Y);
output [Y_WIDTH-1:0] Y;
generate
- if (A_SIGNED != B_SIGNED)
+ if (A_SIGNED != B_SIGNED || A_WIDTH <= 1 || B_WIDTH <= 1)
wire _TECHMAP_FAIL_ = 1;
-`ifdef DSP_SIGNEDONLY
- else if (!A_SIGNED) begin
- wire [1:0] dummy;
- \$mul #(
- .A_SIGNED(1),
- .B_SIGNED(1),
- .A_WIDTH(A_WIDTH + 1),
- .B_WIDTH(B_WIDTH + 1),
- .Y_WIDTH(Y_WIDTH + 2)
- ) _TECHMAP_REPLACE_ (
- .A({1'b0, A}),
- .B({1'b0, B}),
- .Y({dummy, Y})
- );
- end
-`endif
// NB: A_SIGNED == B_SIGNED == 0 from here
else if (A_WIDTH >= B_WIDTH)
- \$__mul_gen #(
+ \$__mul #(
.A_SIGNED(A_SIGNED),
.B_SIGNED(B_SIGNED),
.A_WIDTH(A_WIDTH),
@@ -60,7 +44,7 @@ module \$mul (A, B, Y);
.Y(Y)
);
else
- \$__mul_gen #(
+ \$__mul #(
.A_SIGNED(B_SIGNED),
.B_SIGNED(A_SIGNED),
.A_WIDTH(B_WIDTH),
@@ -74,7 +58,7 @@ module \$mul (A, B, Y);
endgenerate
endmodule
-module \$__mul_gen (A, B, Y);
+module \$__mul (A, B, Y);
parameter A_SIGNED = 0;
parameter B_SIGNED = 0;
parameter A_WIDTH = 1;
@@ -95,7 +79,13 @@ module \$__mul_gen (A, B, Y);
genvar i;
generate
- if (A_WIDTH > `DSP_A_MAXWIDTH) begin
+ if (A_WIDTH <= 1 || B_WIDTH <= 1)
+ wire _TECHMAP_FAIL_ = 1;
+`ifdef DSP_MINWIDTH
+ else if (A_WIDTH+B_WIDTH < `DSP_MINWIDTH || Y_WIDTH < `DSP_MINWIDTH)
+ wire _TECHMAP_FAIL_ = 1;
+`endif
+ else if (A_WIDTH > `DSP_A_MAXWIDTH) begin
localparam n = (A_WIDTH+`DSP_A_MAXWIDTH-sign_headroom-1) / (`DSP_A_MAXWIDTH-sign_headroom);
localparam partial_Y_WIDTH = `MIN(Y_WIDTH, B_WIDTH+`DSP_A_MAXWIDTH);
if (A_SIGNED && B_SIGNED) begin
@@ -107,7 +97,7 @@ module \$__mul_gen (A, B, Y);
wire [Y_WIDTH-1:0] partial_sum [n-1:0];
end
- \$__mul_gen #(
+ \$__mul #(
.A_SIGNED(sign_headroom),
.B_SIGNED(B_SIGNED),
.A_WIDTH(`DSP_A_MAXWIDTH),
@@ -121,7 +111,7 @@ module \$__mul_gen (A, B, Y);
assign partial_sum[0] = partial[0];
for (i = 1; i < n-1; i=i+1) begin:slice
- \$__mul_gen #(
+ \$__mul #(
.A_SIGNED(sign_headroom),
.B_SIGNED(B_SIGNED),
.A_WIDTH(`DSP_A_MAXWIDTH),
@@ -135,7 +125,7 @@ module \$__mul_gen (A, B, Y);
assign partial_sum[i] = (partial[i] << i*(`DSP_A_MAXWIDTH-sign_headroom)) + partial_sum[i-1];
end
- \$__mul_gen #(
+ \$__mul #(
.A_SIGNED(A_SIGNED),
.B_SIGNED(B_SIGNED),
.A_WIDTH(A_WIDTH-(n-1)*(`DSP_A_MAXWIDTH-sign_headroom)),
@@ -161,7 +151,7 @@ module \$__mul_gen (A, B, Y);
wire [Y_WIDTH-1:0] partial_sum [n-1:0];
end
- \$__mul_gen #(
+ \$__mul #(
.A_SIGNED(A_SIGNED),
.B_SIGNED(sign_headroom),
.A_WIDTH(A_WIDTH),
@@ -175,7 +165,7 @@ module \$__mul_gen (A, B, Y);
assign partial_sum[0] = partial[0];
for (i = 1; i < n-1; i=i+1) begin:slice
- \$__mul_gen #(
+ \$__mul #(
.A_SIGNED(A_SIGNED),
.B_SIGNED(sign_headroom),
.A_WIDTH(A_WIDTH),
@@ -189,7 +179,7 @@ module \$__mul_gen (A, B, Y);
assign partial_sum[i] = (partial[i] << i*(`DSP_B_MAXWIDTH-sign_headroom)) + partial_sum[i-1];
end
- \$__mul_gen #(
+ \$__mul #(
.A_SIGNED(A_SIGNED),
.B_SIGNED(B_SIGNED),
.A_WIDTH(A_WIDTH),
@@ -218,7 +208,7 @@ module \$__mul_gen (A, B, Y);
.B_SIGNED(B_SIGNED),
.A_WIDTH(`DSP_A_MAXWIDTH),
.B_WIDTH(`DSP_B_MAXWIDTH),
- .Y_WIDTH(`DSP_A_MAXWIDTH+`DSP_B_MAXWIDTH),
+ .Y_WIDTH(`MIN(Y_WIDTH,`DSP_A_MAXWIDTH+`DSP_B_MAXWIDTH)),
) _TECHMAP_REPLACE_ (
.A(Aext),
.B(Bext),
@@ -228,4 +218,54 @@ module \$__mul_gen (A, B, Y);
endgenerate
endmodule
+(* techmap_celltype = "$__mul" *)
+module _90_internal_mul_to_external (A, B, Y);
+ parameter A_SIGNED = 0;
+ parameter B_SIGNED = 0;
+ parameter A_WIDTH = 1;
+ parameter B_WIDTH = 1;
+ parameter Y_WIDTH = 1;
+ input [A_WIDTH-1:0] A;
+ input [B_WIDTH-1:0] B;
+ output [Y_WIDTH-1:0] Y;
+
+ generate
+ if (A_SIGNED && !B_SIGNED)
+ \$mul #(
+ .A_SIGNED(A_SIGNED),
+ .B_SIGNED(1),
+ .A_WIDTH(A_WIDTH),
+ .B_WIDTH(B_WIDTH+1),
+ .Y_WIDTH(Y_WIDTH)
+ ) _TECHMAP_REPLACE_ (
+ .A(A),
+ .B({1'b0, B}),
+ .Y(Y)
+ );
+ else if (!A_SIGNED && B_SIGNED)
+ \$mul #(
+ .A_SIGNED(1),
+ .B_SIGNED(B_SIGNED),
+ .A_WIDTH(A_WIDTH+1),
+ .B_WIDTH(B_WIDTH),
+ .Y_WIDTH(Y_WIDTH)
+ ) _TECHMAP_REPLACE_ (
+ .A({1'b0, A}),
+ .B(B),
+ .Y(Y)
+ );
+ else
+ \$mul #(
+ .A_SIGNED(A_SIGNED),
+ .B_SIGNED(B_SIGNED),
+ .A_WIDTH(A_WIDTH),
+ .B_WIDTH(B_WIDTH),
+ .Y_WIDTH(Y_WIDTH)
+ ) _TECHMAP_REPLACE_ (
+ .A(A),
+ .B(B),
+ .Y(Y)
+ );
+ endgenerate
+endmodule