Stop trying to be too smart by prematurely optimising
authorEddie Hung <eddie@fpgeh.com>
Thu, 26 Sep 2019 16:57:11 +0000 (09:57 -0700)
committerEddie Hung <eddie@fpgeh.com>
Thu, 26 Sep 2019 16:57:11 +0000 (09:57 -0700)
techlibs/common/mul2dsp.v
techlibs/ice40/synth_ice40.cc
techlibs/xilinx/synth_xilinx.cc

index 60b180ac040b4f0752e107abab9a5d395f00d8df..6dcdcf226d29721681ea2a64f8e38e6f79da67f1 100644 (file)
@@ -146,17 +146,8 @@ module _80_mul (A, B, Y);
                                //       reduction' approach also exists...\r
                                if (i == 0)\r
                                        assign partial_sum[i] = partial[i];\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
-                                       if (A_SIGNED && B_SIGNED)\r
-                                               assign partial_sum[i][Y_WIDTH-1:i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)] = partial[i] + $signed(partial_sum[i-1][Y_WIDTH-1:i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)]);\r
-                                       else\r
-                                               assign partial_sum[i][Y_WIDTH-1:i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)] = partial[i] + partial_sum[i-1][Y_WIDTH-1:i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)];\r
-                                       assign partial_sum[i][i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)-1:0] = partial_sum[i-1][i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)-1:0];\r
-                               end\r
+                               else\r
+                                       assign partial_sum[i] = (partial[i] << (* mul2dsp *) i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)) + (* mul2dsp *) partial_sum[i-1];\r
                        end\r
 \r
                        \$__mul #(\r
@@ -170,12 +161,7 @@ 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
-                       if (A_SIGNED && B_SIGNED)\r
-                               assign partial_sum[n][Y_WIDTH-1:n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)] = last_partial + $signed(partial_sum[n-1][Y_WIDTH-1:n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)]);\r
-                       else\r
-                               assign partial_sum[n][Y_WIDTH-1:n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)] = last_partial + partial_sum[n-1][Y_WIDTH-1:n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)];\r
-                       assign partial_sum[n][n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)-1:0] = partial_sum[n-1][n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)-1:0];\r
+                       assign partial_sum[n] = (last_partial << (* mul2dsp *) n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)) + (* mul2dsp *) partial_sum[n-1];\r
                        assign Y = partial_sum[n];\r
                end\r
                else if (B_WIDTH > `DSP_B_MAXWIDTH) begin\r
@@ -211,17 +197,8 @@ module _80_mul (A, B, Y);
                                //       reduction' approach also exists...\r
                                if (i == 0)\r
                                        assign partial_sum[i] = partial[i];\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_B_MAXWIDTH_PARTIAL-sign_headroom)) + partial_sum[i-1];\r
-                                       if (A_SIGNED && B_SIGNED)\r
-                                               assign partial_sum[i][Y_WIDTH-1:i*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)] = partial[i] + $signed(partial_sum[i-1][Y_WIDTH-1:i*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)]);\r
-                                       else\r
-                                               assign partial_sum[i][Y_WIDTH-1:i*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)] = partial[i] + partial_sum[i-1][Y_WIDTH-1:i*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)];\r
-                                       assign partial_sum[i][i*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)-1:0] = partial_sum[i-1][i*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)-1:0];\r
-                               end\r
+                               else\r
+                                       assign partial_sum[i] = (partial[i] << i*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)) + partial_sum[i-1];\r
                        end\r
 \r
                        \$__mul #(\r
@@ -235,12 +212,7 @@ 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
-                       if (A_SIGNED && B_SIGNED)\r
-                               assign partial_sum[n][Y_WIDTH-1:n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)] = last_partial + $signed(partial_sum[n-1][Y_WIDTH-1:n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)]);\r
-                       else\r
-                               assign partial_sum[n][Y_WIDTH-1:n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)] = last_partial + partial_sum[n-1][Y_WIDTH-1:n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)];\r
-                       assign partial_sum[n][n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)-1:0] = partial_sum[n-1][n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)-1:0];\r
+                       assign partial_sum[n] = (last_partial << n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)) + partial_sum[n-1];\r
                        assign Y = partial_sum[n];\r
                end\r
                else begin\r
index 98d3e44e391febcabc637df4b1ae90de3942a5c9..694782e5b87dd3f7128ad4533ae073d61ebc63c5 100644 (file)
@@ -276,9 +276,11 @@ struct SynthIce40Pass : public ScriptPass
                                run("techmap -map +/mul2dsp.v -map +/ice40/dsp_map.v -D DSP_A_MAXWIDTH=16 -D DSP_B_MAXWIDTH=16 "
                                                "-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_Y_MINWIDTH=11 "
                                                "-D DSP_NAME=$__MUL16X16", "(if -dsp)");
-                               run("wreduce t:$add", "               (if -dsp)");
-                               run("ice40_dsp", "                    (if -dsp)");
-                               run("chtype -set $mul t:$__soft_mul","(if -dsp)");
+                               run("opt_expr -fine a:mul2dsp", "        (if -dsp)");
+                               run("wreduce a:mul2dsp", "               (if -dsp)");
+                               run("ice40_dsp", "                       (if -dsp)");
+                               run("setattr -unset mul2dsp a:mul2dsp", "(if -dsp)");
+                               run("chtype -set $mul t:$__soft_mul", "  (if -dsp)");
                        }
                        run("alumacc");
                        run("opt");
index ca108e9d6ea5d034d1029413920445a560849e25..b87fa9f6ffbd9ec0e2d738915b33ba3168ed4e45 100644 (file)
@@ -346,7 +346,9 @@ struct SynthXilinxPass : public ScriptPass
                                                "-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
                                                "-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
                                                "-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL25X18");
-                               run("wreduce t:$add");
+                               run("opt_expr -fine a:mul2dsp");
+                               run("wreduce a:mul2dsp");
+                               run("setattr -unset mul2dsp a:mul2dsp");
                                run("xilinx_dsp");
                                run("chtype -set $mul t:$__soft_mul");
                        }