Add a DSP_MINWIDTH macro, and soft-logic for {A_WIDTH,B_WIDTH} <= 1 too
authorEddie Hung <eddie@fpgeh.com>
Fri, 19 Jul 2019 18:39:24 +0000 (11:39 -0700)
committerEddie Hung <eddie@fpgeh.com>
Fri, 19 Jul 2019 18:39:24 +0000 (11:39 -0700)
techlibs/common/mul2dsp.v

index b6aa02834fdccaabc5fde69415de76da9b471723..aab568c9fe5e68e61252d0c8aa1e54960579ee40 100644 (file)
@@ -28,27 +28,11 @@ module \$mul (A, B, Y);
        output [Y_WIDTH-1:0] Y;\r
 \r
        generate\r
-       if (A_SIGNED != B_SIGNED)\r
+       if (A_SIGNED != B_SIGNED || A_WIDTH <= 1 || B_WIDTH <= 1)\r
                wire _TECHMAP_FAIL_ = 1;\r
-`ifdef DSP_SIGNEDONLY\r
-        else if (!A_SIGNED) begin\r
-               wire [1:0] dummy;\r
-               \$mul #(\r
-                       .A_SIGNED(1),\r
-                       .B_SIGNED(1),\r
-                       .A_WIDTH(A_WIDTH + 1),\r
-                       .B_WIDTH(B_WIDTH + 1),\r
-                       .Y_WIDTH(Y_WIDTH + 2)\r
-               ) _TECHMAP_REPLACE_ (\r
-                       .A({1'b0, A}),\r
-                       .B({1'b0, B}),\r
-                       .Y({dummy, Y})\r
-               );\r
-        end\r
-`endif\r
        // NB: A_SIGNED == B_SIGNED == 0 from here\r
        else if (A_WIDTH >= B_WIDTH)\r
-               \$__mul_gen #(\r
+               \$__mul #(\r
                        .A_SIGNED(A_SIGNED),\r
                        .B_SIGNED(B_SIGNED),\r
                        .A_WIDTH(A_WIDTH),\r
@@ -60,7 +44,7 @@ module \$mul (A, B, Y);
                        .Y(Y)\r
                );\r
        else\r
-               \$__mul_gen #(\r
+               \$__mul #(\r
                        .A_SIGNED(B_SIGNED),\r
                        .B_SIGNED(A_SIGNED),\r
                        .A_WIDTH(B_WIDTH),\r
@@ -74,7 +58,7 @@ module \$mul (A, B, Y);
        endgenerate\r
 endmodule\r
 \r
-module \$__mul_gen (A, B, Y);\r
+module \$__mul (A, B, Y);\r
        parameter A_SIGNED = 0;\r
        parameter B_SIGNED = 0;\r
        parameter A_WIDTH = 1;\r
@@ -95,7 +79,13 @@ module \$__mul_gen (A, B, Y);
 \r
        genvar i;\r
        generate\r
-               if (A_WIDTH > `DSP_A_MAXWIDTH) begin\r
+               if (A_WIDTH <= 1 || B_WIDTH <= 1)\r
+                       wire _TECHMAP_FAIL_ = 1;\r
+`ifdef DSP_MINWIDTH\r
+               else if (A_WIDTH+B_WIDTH < `DSP_MINWIDTH || Y_WIDTH < `DSP_MINWIDTH)\r
+                       wire _TECHMAP_FAIL_ = 1;\r
+`endif\r
+               else if (A_WIDTH > `DSP_A_MAXWIDTH) begin\r
                        localparam n = (A_WIDTH+`DSP_A_MAXWIDTH-sign_headroom-1) / (`DSP_A_MAXWIDTH-sign_headroom);\r
                        localparam partial_Y_WIDTH = `MIN(Y_WIDTH, B_WIDTH+`DSP_A_MAXWIDTH);\r
                        if (A_SIGNED && B_SIGNED) begin\r
@@ -107,7 +97,7 @@ module \$__mul_gen (A, B, Y);
                                wire [Y_WIDTH-1:0] partial_sum [n-1:0];\r
                        end\r
 \r
-                       \$__mul_gen #(\r
+                       \$__mul #(\r
                                .A_SIGNED(sign_headroom),\r
                                .B_SIGNED(B_SIGNED),\r
                                .A_WIDTH(`DSP_A_MAXWIDTH),\r
@@ -121,7 +111,7 @@ module \$__mul_gen (A, B, Y);
                        assign partial_sum[0] = partial[0];\r
 \r
                        for (i = 1; i < n-1; i=i+1) begin:slice\r
-                               \$__mul_gen #(\r
+                               \$__mul #(\r
                                        .A_SIGNED(sign_headroom),\r
                                        .B_SIGNED(B_SIGNED),\r
                                        .A_WIDTH(`DSP_A_MAXWIDTH),\r
@@ -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];\r
                        end\r
 \r
-                       \$__mul_gen #(\r
+                       \$__mul #(\r
                                .A_SIGNED(A_SIGNED),\r
                                .B_SIGNED(B_SIGNED),\r
                                .A_WIDTH(A_WIDTH-(n-1)*(`DSP_A_MAXWIDTH-sign_headroom)),\r
@@ -161,7 +151,7 @@ module \$__mul_gen (A, B, Y);
                                wire [Y_WIDTH-1:0] partial_sum [n-1:0];\r
                        end\r
 \r
-                       \$__mul_gen #(\r
+                       \$__mul #(\r
                                .A_SIGNED(A_SIGNED),\r
                                .B_SIGNED(sign_headroom),\r
                                .A_WIDTH(A_WIDTH),\r
@@ -175,7 +165,7 @@ module \$__mul_gen (A, B, Y);
                        assign partial_sum[0] = partial[0];\r
 \r
                        for (i = 1; i < n-1; i=i+1) begin:slice\r
-                               \$__mul_gen #(\r
+                               \$__mul #(\r
                                        .A_SIGNED(A_SIGNED),\r
                                        .B_SIGNED(sign_headroom),\r
                                        .A_WIDTH(A_WIDTH),\r
@@ -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];\r
                        end\r
 \r
-                       \$__mul_gen #(\r
+                       \$__mul #(\r
                                .A_SIGNED(A_SIGNED),\r
                                .B_SIGNED(B_SIGNED),\r
                                .A_WIDTH(A_WIDTH),\r
@@ -218,7 +208,7 @@ module \$__mul_gen (A, B, Y);
                                .B_SIGNED(B_SIGNED),\r
                                .A_WIDTH(`DSP_A_MAXWIDTH),\r
                                .B_WIDTH(`DSP_B_MAXWIDTH),\r
-                               .Y_WIDTH(`DSP_A_MAXWIDTH+`DSP_B_MAXWIDTH),\r
+                               .Y_WIDTH(`MIN(Y_WIDTH,`DSP_A_MAXWIDTH+`DSP_B_MAXWIDTH)),\r
                        ) _TECHMAP_REPLACE_ (\r
                                .A(Aext),\r
                                .B(Bext),\r
@@ -228,4 +218,54 @@ module \$__mul_gen (A, B, Y);
        endgenerate\r
 endmodule\r
 \r
+(* techmap_celltype = "$__mul" *)\r
+module _90_internal_mul_to_external (A, B, Y); \r
+       parameter A_SIGNED = 0;\r
+       parameter B_SIGNED = 0;\r
+       parameter A_WIDTH = 1;\r
+       parameter B_WIDTH = 1;\r
+       parameter Y_WIDTH = 1;\r
 \r
+       input [A_WIDTH-1:0] A;\r
+       input [B_WIDTH-1:0] B;\r
+       output [Y_WIDTH-1:0] Y;\r
+\r
+       generate\r
+               if (A_SIGNED && !B_SIGNED)\r
+                       \$mul #(\r
+                               .A_SIGNED(A_SIGNED),\r
+                               .B_SIGNED(1),\r
+                               .A_WIDTH(A_WIDTH),\r
+                               .B_WIDTH(B_WIDTH+1),\r
+                               .Y_WIDTH(Y_WIDTH)\r
+                       ) _TECHMAP_REPLACE_ (\r
+                               .A(A),\r
+                               .B({1'b0, B}),\r
+                               .Y(Y)\r
+                       );\r
+               else if (!A_SIGNED && B_SIGNED)\r
+                       \$mul #(\r
+                               .A_SIGNED(1),\r
+                               .B_SIGNED(B_SIGNED),\r
+                               .A_WIDTH(A_WIDTH+1),\r
+                               .B_WIDTH(B_WIDTH),\r
+                               .Y_WIDTH(Y_WIDTH)\r
+                       ) _TECHMAP_REPLACE_ (\r
+                               .A({1'b0, A}),\r
+                               .B(B),\r
+                               .Y(Y)\r
+                       );\r
+               else\r
+                       \$mul #(\r
+                               .A_SIGNED(A_SIGNED),\r
+                               .B_SIGNED(B_SIGNED),\r
+                               .A_WIDTH(A_WIDTH),\r
+                               .B_WIDTH(B_WIDTH),\r
+                               .Y_WIDTH(Y_WIDTH)\r
+                       ) _TECHMAP_REPLACE_ (\r
+                               .A(A),\r
+                               .B(B),\r
+                               .Y(Y)\r
+                       );\r
+       endgenerate\r
+endmodule\r