Fix signed multiplier decomposition
authorEddie Hung <eddie@fpgeh.com>
Thu, 18 Jul 2019 20:11:26 +0000 (13:11 -0700)
committerEddie Hung <eddie@fpgeh.com>
Thu, 18 Jul 2019 20:11:26 +0000 (13:11 -0700)
techlibs/common/mul2dsp.v

index 4af3b871b5c091efe5f04026d4f993f727c30193..2819c939e1bb909425a7a6c438fde0e1c00c7304 100644 (file)
@@ -5,14 +5,11 @@
 `ifndef DSP_A_MAXWIDTH\r
 $error("Macro DSP_A_MAXWIDTH must be defined");\r
 `endif\r
-`ifndef DSP_A_SIGNEDONLY\r
-`define DSP_A_SIGNEDONLY 0\r
-`endif\r
 `ifndef DSP_B_MAXWIDTH\r
 $error("Macro DSP_B_MAXWIDTH must be defined");\r
 `endif\r
-`ifndef DSP_B_SIGNEDONLY\r
-`define DSP_B_SIGNEDONLY 0\r
+`ifndef DSP_SIGNEDONLY\r
+`define DSP_SIGNEDONLY 0\r
 `endif\r
 \r
 `ifndef DSP_NAME\r
@@ -34,7 +31,9 @@ module \$mul (A, B, Y);
        output [Y_WIDTH-1:0] Y;\r
 \r
        generate\r
-        if (`DSP_SIGNEDONLY && !A_SIGNED) begin\r
+       if (A_SIGNED != B_SIGNED)\r
+               wire _TECHMAP_FAIL_ = 1;\r
+        else if (`DSP_SIGNEDONLY && !A_SIGNED) begin\r
                wire [1:0] dummy;\r
                \$mul #(\r
                        .A_SIGNED(1),\r
@@ -98,19 +97,25 @@ module \$__mul_gen (A, B, Y);
        genvar i;\r
        generate\r
                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 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
-                       wire [partial_Y_WIDTH-1:0] partial [n-1:1];\r
-                       wire [Y_WIDTH-1:0] partial_sum [n-1:0];\r
+                       if (A_SIGNED && B_SIGNED) begin\r
+                               wire signed [partial_Y_WIDTH-1:0] partial [n-1:0];\r
+                               wire signed [Y_WIDTH-1:0] partial_sum [n-1:0];\r
+                       end\r
+                       else begin\r
+                               wire [partial_Y_WIDTH-1:0] partial [n-1:0];\r
+                               wire [Y_WIDTH-1:0] partial_sum [n-1:0];\r
+                       end\r
 \r
                        \$__mul_gen #(\r
                                .A_SIGNED(0),\r
-                               .B_SIGNED(0),\r
+                               .B_SIGNED(B_SIGNED),\r
                                .A_WIDTH(`DSP_A_MAXWIDTH),\r
                                .B_WIDTH(B_WIDTH),\r
                                .Y_WIDTH(partial_Y_WIDTH)\r
                        ) mul_slice_first (\r
-                               .A({{sign_headroom{1'b0}}, A[`DSP_A_MAXWIDTH-sign_headroom-1:0]}),\r
+                               .A({{sign_headroom{1'b0}}, A[`DSP_A_MAXWIDTH-sign_headroom-1 : 0]}),\r
                                .B(B),\r
                                .Y(partial[0])\r
                        );\r
@@ -119,7 +124,7 @@ module \$__mul_gen (A, B, Y);
                        for (i = 1; i < n-1; i=i+1) begin:slice\r
                                \$__mul_gen #(\r
                                        .A_SIGNED(0),\r
-                                       .B_SIGNED(0),\r
+                                       .B_SIGNED(B_SIGNED),\r
                                        .A_WIDTH(`DSP_A_MAXWIDTH),\r
                                        .B_WIDTH(B_WIDTH),\r
                                        .Y_WIDTH(partial_Y_WIDTH)\r
@@ -136,24 +141,26 @@ module \$__mul_gen (A, B, Y);
                                .B_SIGNED(B_SIGNED),\r
                                .A_WIDTH(A_WIDTH-(n-1)*(`DSP_A_MAXWIDTH-sign_headroom)),\r
                                .B_WIDTH(B_WIDTH),\r
-                               .Y_WIDTH(A_WIDTH-(n-1)*(`DSP_A_MAXWIDTH-sign_headroom) + B_WIDTH),\r
+                               .Y_WIDTH(partial_Y_WIDTH)\r
                        ) mul_slice_last (\r
-                               .A(A[A_WIDTH-1:(n-1)*(`DSP_A_MAXWIDTH-sign_headroom)]),\r
+                               .A(A[A_WIDTH-1 : (n-1)*(`DSP_A_MAXWIDTH-sign_headroom)]),\r
                                .B(B),\r
                                .Y(partial[n-1])\r
                        );\r
-                       assign Y = (partial[n-1] << (n-1)*(`DSP_A_MAXWIDTH-sign_headroom)) + partial_sum[n-2];\r
+                       assign partial_sum[n-1] = (partial[n-1] << (n-1)*(`DSP_A_MAXWIDTH-sign_headroom)) + partial_sum[n-2];\r
+                       assign Y = partial_sum[n-1];\r
                end\r
                else if (B_WIDTH > `DSP_B_MAXWIDTH) begin\r
-`ifdef DSP_B_SIGNEDONLY\r
-                       localparam sign_headroom = 1;\r
-`else  \r
-                       localparam sign_headroom = 0;\r
-`endif\r
-                       localparam n = (B_WIDTH + `DSP_B_MAXWIDTH - sign_headroom - 1)/(`DSP_B_MAXWIDTH - sign_headroom);\r
+                       localparam n = (B_WIDTH+`DSP_B_MAXWIDTH-sign_headroom-1) / (`DSP_B_MAXWIDTH-sign_headroom);\r
                        localparam partial_Y_WIDTH = `MIN(Y_WIDTH, A_WIDTH+`DSP_B_MAXWIDTH);\r
-                       wire [partial_Y_WIDTH-1:0] partial [n-1:1];\r
-                       wire [Y_WIDTH-1:0] partial_sum [n-1:0];\r
+                       if (A_SIGNED && B_SIGNED) begin\r
+                               wire signed [partial_Y_WIDTH-1:0] partial [n-1:0];\r
+                               wire signed [Y_WIDTH-1:0] partial_sum [n-1:0];\r
+                       end\r
+                       else begin\r
+                               wire [partial_Y_WIDTH-1:0] partial [n-1:0];\r
+                               wire [Y_WIDTH-1:0] partial_sum [n-1:0];\r
+                       end\r
 \r
                        \$__mul_gen #(\r
                                .A_SIGNED(A_SIGNED),\r
@@ -163,7 +170,7 @@ module \$__mul_gen (A, B, Y);
                                .Y_WIDTH(partial_Y_WIDTH)\r
                        ) mul_first (\r
                                .A(A),\r
-                               .B({{sign_headroom{1'b0}}, B[`DSP_B_MAXWIDTH-sign_headroom-1:0]}),\r
+                               .B({{sign_headroom{1'b0}}, B[`DSP_B_MAXWIDTH-sign_headroom-1 : 0]}),\r
                                .Y(partial[0])\r
                        );\r
                        assign partial_sum[0] = partial[0];\r
@@ -180,21 +187,21 @@ module \$__mul_gen (A, B, Y);
                                        .B({{sign_headroom{1'b0}}, B[i*(`DSP_B_MAXWIDTH-sign_headroom) +: `DSP_B_MAXWIDTH-sign_headroom]}),\r
                                        .Y(partial[i])\r
                                );\r
-                               assign partial_sum[i] = (partial[i] << i*(`DSP_B_MAXWIDTH - sign_headroom)) + partial_sum[i-1];\r
+                               assign partial_sum[i] = (partial[i] << i*(`DSP_B_MAXWIDTH-sign_headroom)) + partial_sum[i-1];\r
                        end\r
 \r
                        \$__mul_gen #(\r
                                .A_SIGNED(A_SIGNED),\r
                                .B_SIGNED(B_SIGNED),\r
                                .A_WIDTH(A_WIDTH),\r
-                               .B_WIDTH(B_WIDTH-(n-1)*(`DSP_B_MAXWIDTH - sign_headroom)),\r
-                               .Y_WIDTH(A_WIDTH + B_WIDTH-(n-1)*(`DSP_B_MAXWIDTH - sign_headroom))\r
+                               .B_WIDTH(B_WIDTH-(n-1)*(`DSP_B_MAXWIDTH-sign_headroom)),\r
+                               .Y_WIDTH(partial_Y_WIDTH)\r
                        ) mul_last (\r
                                .A(A),\r
-                               .B(B[B_WIDTH-1:(n-1)*(`DSP_B_MAXWIDTH - sign_headroom)]),\r
+                               .B(B[B_WIDTH-1 : (n-1)*(`DSP_B_MAXWIDTH-sign_headroom)]),\r
                                .Y(partial[n-1])\r
                        );\r
-                       assign Y = (partial[n-1] << (n-1)*(`DSP_B_MAXWIDTH - sign_headroom)) + partial_sum[n-2];\r
+                       assign Y = (partial[n-1] << (n-1)*(`DSP_B_MAXWIDTH-sign_headroom)) + partial_sum[n-2];\r
                end\r
                else begin \r
                        if (A_SIGNED)\r