Working for unsigned
authorEddie Hung <eddie@fpgeh.com>
Thu, 18 Jul 2019 17:53:18 +0000 (10:53 -0700)
committerEddie Hung <eddie@fpgeh.com>
Thu, 18 Jul 2019 17:53:18 +0000 (10:53 -0700)
techlibs/common/mul2dsp.v

index 9da778ace978d063842eeb86e5675d53da94a6f6..4af3b871b5c091efe5f04026d4f993f727c30193 100644 (file)
@@ -34,7 +34,7 @@ module \$mul (A, B, Y);
        output [Y_WIDTH-1:0] Y;\r
 \r
        generate\r
-        if (`DSP_A_SIGNEDONLY && `DSP_B_SIGNEDONLY && !A_SIGNED) begin\r
+        if (`DSP_SIGNEDONLY && !A_SIGNED) begin\r
                wire [1:0] dummy;\r
                \$mul #(\r
                        .A_SIGNED(1),\r
@@ -89,22 +89,23 @@ module \$__mul_gen (A, B, Y);
 \r
        wire [1023:0] _TECHMAP_DO_ = "proc; clean";\r
 \r
+`ifdef DSP_SIGNEDONLY\r
+       localparam sign_headroom = 1;\r
+`else\r
+       localparam sign_headroom = 0;\r
+`endif\r
+\r
        genvar i;\r
        generate\r
                if (A_WIDTH > `DSP_A_MAXWIDTH) begin\r
-`ifdef DSP_A_SIGNEDONLY\r
-                       localparam sign_headroom = 1;\r
-`else  \r
-                       localparam sign_headroom = 0;\r
-`endif\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-2:0];\r
+                       wire [Y_WIDTH-1:0] partial_sum [n-1:0];\r
 \r
                        \$__mul_gen #(\r
                                .A_SIGNED(0),\r
-                               .B_SIGNED(B_SIGNED),\r
+                               .B_SIGNED(0),\r
                                .A_WIDTH(`DSP_A_MAXWIDTH),\r
                                .B_WIDTH(B_WIDTH),\r
                                .Y_WIDTH(partial_Y_WIDTH)\r
@@ -118,7 +119,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(B_SIGNED),\r
+                                       .B_SIGNED(0),\r
                                        .A_WIDTH(`DSP_A_MAXWIDTH),\r
                                        .B_WIDTH(B_WIDTH),\r
                                        .Y_WIDTH(partial_Y_WIDTH)\r
@@ -128,11 +129,6 @@ module \$__mul_gen (A, B, Y);
                                        .Y(partial[i])\r
                                );\r
                                assign partial_sum[i] = (partial[i] << i*(`DSP_A_MAXWIDTH-sign_headroom)) + partial_sum[i-1];\r
-                               //assign partial_sum[i] = {\r
-                               //      partial[i][partial_Y_WIDTH-1:0]\r
-                               //      + partial_sum[i-1][Y_WIDTH-1:(i*(`DSP_A_MAXWIDTH-sign_headroom))],\r
-                               //      partial_sum[i-1][(i*(`DSP_A_MAXWIDTH-sign_headroom))-1:0]\r
-                               //};\r
                        end\r
 \r
                        \$__mul_gen #(\r
@@ -140,18 +136,13 @@ 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(`MIN(Y_WIDTH, A_WIDTH-(n-1)*(`DSP_A_MAXWIDTH-sign_headroom)+B_WIDTH)),\r
+                               .Y_WIDTH(A_WIDTH-(n-1)*(`DSP_A_MAXWIDTH-sign_headroom) + B_WIDTH),\r
                        ) mul_slice_last (\r
                                .A(A[A_WIDTH-1:(n-1)*(`DSP_A_MAXWIDTH-sign_headroom)]),\r
                                .B(B),\r
-                               .Y(partial[n-1][`MIN(Y_WIDTH, A_WIDTH-(n-1)*(`DSP_A_MAXWIDTH-sign_headroom)+B_WIDTH)-1:0])\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 Y = {\r
-                       //      partial[n-1][`MIN(Y_WIDTH, A_WIDTH-(n-1)*(`DSP_A_MAXWIDTH-sign_headroom)+B_WIDTH):0]\r
-                       //      + partial_sum[n-2][Y_WIDTH-1:((n-1)*(`DSP_A_MAXWIDTH-sign_headroom))],\r
-                       //      partial_sum[n-2][((n-1)*(`DSP_A_MAXWIDTH-sign_headroom))-1:0]\r
-                       //};\r
                end\r
                else if (B_WIDTH > `DSP_B_MAXWIDTH) begin\r
 `ifdef DSP_B_SIGNEDONLY\r
@@ -162,7 +153,7 @@ module \$__mul_gen (A, B, Y);
                        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-2:0];\r
+                       wire [Y_WIDTH-1:0] partial_sum [n-1:0];\r
 \r
                        \$__mul_gen #(\r
                                .A_SIGNED(A_SIGNED),\r
@@ -189,17 +180,7 @@ 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
-                               //// was:\r
-                               ////assign partial_sum[i] = {\r
-                               ////  partial[i][A_WIDTH+`DSP_B_MAXWIDTH-1:`DSP_B_MAXWIDTH], \r
-                               ////    partial[i][`DSP_B_MAXWIDTH-1:0] + partial_sum[i-1][A_WIDTH+(i*`DSP_B_MAXWIDTH)-1:A_WIDTH+((i-1)*`DSP_B_MAXWIDTH)],\r
-                               ////    partial_sum[i-1][A_WIDTH+((i-1)*`DSP_B_MAXWIDTH):0]\r
-                               //assign partial_sum[i] = {\r
-                               //      partial[i][partial_Y_WIDTH-1:0]\r
-                               //      + partial_sum[i-1][Y_WIDTH-1:(i*(`DSP_B_MAXWIDTH - sign_headroom))],\r
-                               //      partial_sum[i-1][(i*(`DSP_B_MAXWIDTH - sign_headroom))-1:0] \r
-                               //};\r
+                               assign partial_sum[i] = (partial[i] << i*(`DSP_B_MAXWIDTH - sign_headroom)) + partial_sum[i-1];\r
                        end\r
 \r
                        \$__mul_gen #(\r
@@ -207,34 +188,29 @@ module \$__mul_gen (A, B, Y);
                                .B_SIGNED(B_SIGNED),\r
                                .A_WIDTH(A_WIDTH),\r
                                .B_WIDTH(B_WIDTH-(n-1)*(`DSP_B_MAXWIDTH - sign_headroom)),\r
-                               .Y_WIDTH(`MIN(Y_WIDTH, A_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
                        ) mul_last (\r
                                .A(A),\r
                                .B(B[B_WIDTH-1:(n-1)*(`DSP_B_MAXWIDTH - sign_headroom)]),\r
-                               .Y(partial[n-1][`MIN(Y_WIDTH, A_WIDTH+B_WIDTH-(n-1)*(`DSP_B_MAXWIDTH - sign_headroom))-1:0])\r
+                               .Y(partial[n-1])\r
                        );\r
                        assign Y = (partial[n-1] << (n-1)*(`DSP_B_MAXWIDTH - sign_headroom)) + partial_sum[n-2];\r
-                       //// was (looks broken)\r
-                       ////assign Y = {\r
-                       ////    partial[n-1][A_WIDTH+`DSP_B_MAXWIDTH-1:`DSP_B_MAXWIDTH],\r
-                       ////    partial[n-1][`DSP_B_MAXWIDTH-1:0] + partial_sum[n-2][A_WIDTH+((n-1)*`DSP_B_MAXWIDTH)-1:A_WIDTH+((n-2)*`DSP_B_MAXWIDTH)],\r
-                       ////    partial_sum[n-2][A_WIDTH+((n-2)*`DSP_B_MAXWIDTH):0]\r
-                       //assign Y = {\r
-                       //      partial[n-1][`MIN(Y_WIDTH, A_WIDTH+B_WIDTH-(n-1)*(`DSP_B_MAXWIDTH - sign_headroom))-1:0]\r
-                       //      + partial_sum[n-2][Y_WIDTH-1:((n-1)*(`DSP_B_MAXWIDTH - sign_headroom))],\r
-                       //      partial_sum[n-2][((n-1)*(`DSP_B_MAXWIDTH - sign_headroom))-1:0]\r
-                       //};\r
                end\r
                else begin \r
-                       (* keep *) wire [Y_WIDTH-1:0] Yunsigned;\r
-                       wire signed [`DSP_A_MAXWIDTH-1:0] Asigned = $signed(A);\r
-                       wire signed [`DSP_A_MAXWIDTH-1:0] Bsigned = $signed(B);\r
+                       if (A_SIGNED)\r
+                               wire signed [`DSP_A_MAXWIDTH-1:0] Aext = $signed(A);\r
+                       else\r
+                               wire [`DSP_A_MAXWIDTH-1:0] Aext = A;\r
+                       if (B_SIGNED)\r
+                               wire signed [`DSP_B_MAXWIDTH-1:0] Bext = $signed(B);\r
+                       else\r
+                               wire [`DSP_B_MAXWIDTH-1:0] Bext = B;\r
+\r
                        `DSP_NAME _TECHMAP_REPLACE_ (\r
-                               .A(Asigned),\r
-                               .B(Bsigned),\r
-                               .Y(Yunsigned)\r
+                               .A(Aext),\r
+                               .B(Bext),\r
+                               .Y(Y)\r
                        );\r
-                       assign Y = $signed(Yunsigned[A_WIDTH+B_WIDTH-1:0]);\r
                end\r
        endgenerate\r
 endmodule\r