Be sensitive to signedness
authorEddie Hung <eddie@fpgeh.com>
Tue, 10 Sep 2019 22:14:55 +0000 (15:14 -0700)
committerEddie Hung <eddie@fpgeh.com>
Tue, 10 Sep 2019 22:14:55 +0000 (15:14 -0700)
techlibs/common/mul2dsp.v

index 51a6c5fb9978e4e29fe931c045f006f4f0c050cf..f2b44222e1f943a2b96e5380c7f84638cbf996a4 100644 (file)
@@ -153,11 +153,11 @@ module _80_mul (A, B, Y);
                                        //   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
+                                       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
                        end\r
 \r
@@ -173,11 +173,11 @@ module _80_mul (A, B, Y);
                                .Y(last_partial)\r
                        );\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
+                       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 Y = partial_sum[n];\r
                end\r
                else if (B_WIDTH > `DSP_B_MAXWIDTH) begin\r
@@ -217,11 +217,12 @@ module _80_mul (A, B, Y);
                                        // 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
+                                       //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
                        end\r
 \r
@@ -237,11 +238,11 @@ module _80_mul (A, B, Y);
                                .Y(last_partial)\r
                        );\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
+                       if (A_SIGNED && B_SIGNED)\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
+                       else\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
+                       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 Y = partial_sum[n];\r
                end\r
                else begin\r