Really get rid of 'opt_expr -fine' by being explicit
authorEddie Hung <eddie@fpgeh.com>
Tue, 10 Sep 2019 21:26:12 +0000 (14:26 -0700)
committerEddie Hung <eddie@fpgeh.com>
Tue, 10 Sep 2019 21:26:12 +0000 (14:26 -0700)
techlibs/common/mul2dsp.v
techlibs/xilinx/synth_xilinx.cc

index 75b1242a2dcd4722c75ed834965747e6a4243088..51a6c5fb9978e4e29fe931c045f006f4f0c050cf 100644 (file)
@@ -148,8 +148,17 @@ module _80_mul (A, B, Y);
                                //       reduction' approach also exists...\r
                                if (i == 0)\r
                                        assign partial_sum[i] = partial[i];\r
-                               else\r
-                                       assign partial_sum[i] = (partial[i] << i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)) + partial_sum[i-1];\r
+                               else begin\r
+                                       // Rewrite the following statement explicitly in order\r
+                                       //   to save on a call to 'opt_expr -fine' which would\r
+                                       //   optimise away the '<<' op and trim size of adder\r
+                                       //assign partial_sum[i] = (partial[i] << i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)) + partial_sum[i-1];\r
+                                       wire [Y_WIDTH-1:0] shifted_sum = {partial[i], {i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom){1'b0}}};\r
+                                       assign partial_sum[i] = {\r
+                                               partial_sum[i-1][i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)-1:0],\r
+                                               shifted_sum[Y_WIDTH-1:i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)] + partial_sum[i-1][Y_WIDTH-1:i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)]\r
+                                       };\r
+                               end\r
                        end\r
 \r
                        \$__mul #(\r
@@ -163,7 +172,12 @@ module _80_mul (A, B, Y);
                                .B(B),\r
                                .Y(last_partial)\r
                        );\r
-                       assign partial_sum[n] = (last_partial << n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)) + partial_sum[n-1];\r
+                       //assign partial_sum[n] = (last_partial << n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)) + partial_sum[n-1];\r
+                       wire [Y_WIDTH-1:0] shifted_sum = {last_partial, {n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom){1'b0}}};\r
+                       assign partial_sum[n] = {\r
+                               partial_sum[n-1][n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)-1:0],\r
+                               shifted_sum[Y_WIDTH-1:n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)] + partial_sum[n-1][Y_WIDTH-1:n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)]\r
+                       };\r
                        assign Y = partial_sum[n];\r
                end\r
                else if (B_WIDTH > `DSP_B_MAXWIDTH) begin\r
@@ -199,8 +213,16 @@ module _80_mul (A, B, Y);
                                //       reduction' approach also exists...\r
                                if (i == 0)\r
                                        assign partial_sum[i] = partial[i];\r
-                               else\r
-                                       assign partial_sum[i] = (partial[i] << i*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)) + partial_sum[i-1];\r
+                               else begin\r
+                                       // Rewrite the following statement explicitly in order\r
+                                       //   to save on a call to 'opt_expr -fine' which would\r
+                                       //   optimise away the '<<' op and trim size of adder\r
+                                       wire [Y_WIDTH-1:0] shifted_sum = {partial[i], {i*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom){1'b0}}};\r
+                                       assign partial_sum[i] = {\r
+                                               partial_sum[i-1][i*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)-1:0],\r
+                                               shifted_sum[Y_WIDTH-1:i*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)] + partial_sum[i-1][Y_WIDTH-1:i*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)]\r
+                                       };\r
+                               end\r
                        end\r
 \r
                        \$__mul #(\r
@@ -214,7 +236,12 @@ module _80_mul (A, B, Y);
                                .B(B[B_WIDTH-1 -: last_B_WIDTH]),\r
                                .Y(last_partial)\r
                        );\r
-                       assign partial_sum[n] = (last_partial << n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)) + partial_sum[n-1];\r
+                       //assign partial_sum[n] = (last_partial << n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)) + partial_sum[n-1];\r
+                       wire [Y_WIDTH-1:0] shifted_sum = {last_partial, {n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom){1'b0}}};\r
+                       assign partial_sum[n] = {\r
+                               partial_sum[n-1][n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)-1:0],\r
+                               shifted_sum[Y_WIDTH-1:n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)] + partial_sum[n-1][Y_WIDTH-1:n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)]\r
+                       };\r
                        assign Y = partial_sum[n];\r
                end\r
                else begin\r
index 9ad28a9335625e9303110b3b49337b4433b2001b..4ca8a466747e580c4abffe37a506a2d7662706b1 100644 (file)
@@ -325,9 +325,6 @@ struct SynthXilinxPass : public ScriptPass
                        if (!nodsp || help_mode) {
                                // NB: Xilinx multipliers are signed only
                                run("techmap -map +/mul2dsp.v -map +/xilinx/dsp_map.v -D DSP_A_MAXWIDTH=25 -D DSP_A_MAXWIDTH_PARTIAL=18 -D DSP_B_MAXWIDTH=18 -D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL25X18", "(skip if '-nodsp')");
-                               // Necessary for optimising away $shl cells, as well as $add cells
-                               //   that have inputs with 1'b0 LSBs
-                               run("opt_expr -fine", "                 (skip if '-nodsp')");
                                run("xilinx_dsp", "                     (skip if '-nodsp')");
                                run("chtype -set $mul t:$__soft_mul","  (skip if '-nodsp')");
                        }