mul2dsp: Fix edge case where Y_WIDTH is less than B_WIDTH+`DSP_A_MAXWIDTH
authorDavid Shah <dave@ds0.me>
Tue, 16 Jul 2019 15:44:40 +0000 (16:44 +0100)
committerDavid Shah <dave@ds0.me>
Tue, 16 Jul 2019 15:44:40 +0000 (16:44 +0100)
Signed-off-by: David Shah <dave@ds0.me>
techlibs/common/mul2dsp.v

index 69de74cad0caf7842b984a4f50e44523559deb00..262e29986b031bb74550c3fef4f53c86eb6a442f 100644 (file)
@@ -80,19 +80,21 @@ module \$__mul_gen (A, B, Y);
                        localparam n = n_floored + (n_floored*`DSP_A_MAXWIDTH < A_WIDTH ? 1 : 0);\r
                        wire [`DSP_A_MAXWIDTH+B_WIDTH-1:0] partial [n-1:1];\r
                        wire [Y_WIDTH-1:0] partial_sum [n-2:0];\r
+                       localparam int_yw = `MIN(Y_WIDTH, B_WIDTH+`DSP_A_MAXWIDTH);\r
 \r
                        \$__mul_gen #(\r
                                .A_SIGNED(A_SIGNED),\r
                                .B_SIGNED(B_SIGNED),\r
                                .A_WIDTH(`DSP_A_MAXWIDTH),\r
                                .B_WIDTH(B_WIDTH),\r
-                               .Y_WIDTH(B_WIDTH+`DSP_A_MAXWIDTH)\r
+                               .Y_WIDTH(int_yw)\r
                        ) mul_slice_first (\r
                                .A(A[`DSP_A_MAXWIDTH-1:0]),\r
                                .B(B),\r
-                               .Y(partial_sum[0][B_WIDTH+`DSP_A_MAXWIDTH-1:0])\r
+                               .Y(partial_sum[0][int_yw-1:0])\r
                        );\r
-                       assign partial_sum[0][Y_WIDTH-1:B_WIDTH+`DSP_A_MAXWIDTH]=0;\r
+                       if (Y_WIDTH > int_yw)\r
+                               assign partial_sum[0][Y_WIDTH-1:int_yw]=0;\r
 \r
                        for (i = 1; i < n-1; i=i+1) begin:slice\r
                                \$__mul_gen #(\r
@@ -100,15 +102,15 @@ module \$__mul_gen (A, B, Y);
                                        .B_SIGNED(B_SIGNED),\r
                                        .A_WIDTH(`DSP_A_MAXWIDTH),\r
                                        .B_WIDTH(B_WIDTH),\r
-                                       .Y_WIDTH(B_WIDTH+`DSP_A_MAXWIDTH)\r
+                                       .Y_WIDTH(int_yw)\r
                                ) mul_slice (\r
                                        .A(A[(i+1)*`DSP_A_MAXWIDTH-1:i*`DSP_A_MAXWIDTH]),\r
                                        .B(B),\r
-                                       .Y(partial[i][B_WIDTH+`DSP_A_MAXWIDTH-1:0])\r
+                                       .Y(partial[i][int_yw-1:0])\r
                                );\r
                                //assign partial_sum[i] = (partial[i] << i*`DSP_A_MAXWIDTH) + partial_sum[i-1];\r
                                assign partial_sum[i] = {\r
-                                       partial[i][B_WIDTH+`DSP_A_MAXWIDTH-1:0]\r
+                                       partial[i][int_yw-1:0]\r
                                        + partial_sum[i-1][Y_WIDTH-1:(i*`DSP_A_MAXWIDTH)],\r
                                        partial_sum[i-1][(i*`DSP_A_MAXWIDTH)-1:0]\r
                                };\r
@@ -119,15 +121,15 @@ module \$__mul_gen (A, B, Y);
                                .B_SIGNED(B_SIGNED),\r
                                .A_WIDTH(A_WIDTH-(n-1)*`DSP_A_MAXWIDTH),\r
                                .B_WIDTH(B_WIDTH),\r
-                               .Y_WIDTH(A_WIDTH-(n-1)*`DSP_A_MAXWIDTH+B_WIDTH),\r
+                               .Y_WIDTH(`MIN(Y_WIDTH, A_WIDTH-(n-1)*`DSP_A_MAXWIDTH+B_WIDTH)),\r
                        ) mul_slice_last (\r
                                .A(A[A_WIDTH-1:(n-1)*`DSP_A_MAXWIDTH]),\r
                                .B(B),\r
-                               .Y(partial[n-1][A_WIDTH-(n-1)*`DSP_A_MAXWIDTH+B_WIDTH-1:0])\r
+                               .Y(partial[n-1][`MIN(Y_WIDTH, A_WIDTH-(n-1)*`DSP_A_MAXWIDTH+B_WIDTH)-1:0])\r
                        );\r
                        //assign Y = (partial[n-1] << (n-1)*`DSP_A_MAXWIDTH) + partial_sum[n-2];\r
                        assign Y = {\r
-                               partial[n-1][A_WIDTH-(n-1)*`DSP_A_MAXWIDTH+B_WIDTH:0]\r
+                               partial[n-1][`MIN(Y_WIDTH, A_WIDTH-(n-1)*`DSP_A_MAXWIDTH+B_WIDTH):0]\r
                                + partial_sum[n-2][Y_WIDTH-1:((n-1)*`DSP_A_MAXWIDTH)],\r
                                partial_sum[n-2][((n-1)*`DSP_A_MAXWIDTH)-1:0]\r
                        };\r
@@ -137,19 +139,21 @@ module \$__mul_gen (A, B, Y);
                        localparam n = n_floored + (n_floored*`DSP_B_MAXWIDTH < B_WIDTH ? 1 : 0);\r
                        wire [A_WIDTH+`DSP_B_MAXWIDTH-1:0] partial [n-1:1];\r
                        wire [Y_WIDTH-1:0] partial_sum [n-2:0];\r
+                       localparam int_yw = `MIN(Y_WIDTH, A_WIDTH+`DSP_B_MAXWIDTH);\r
 \r
                        \$__mul_gen #(\r
                                .A_SIGNED(A_SIGNED),\r
                                .B_SIGNED(B_SIGNED),\r
                                .A_WIDTH(A_WIDTH),\r
                                .B_WIDTH(`DSP_B_MAXWIDTH),\r
-                               .Y_WIDTH(A_WIDTH+`DSP_B_MAXWIDTH)\r
+                               .Y_WIDTH(int_yw)\r
                        ) mul_first (\r
                                .A(A),\r
                                .B(B[`DSP_B_MAXWIDTH-1:0]),\r
-                               .Y(partial_sum[0][A_WIDTH+`DSP_B_MAXWIDTH-1:0])\r
+                               .Y(partial_sum[0][int_yw-1:0])\r
                        );\r
-                       assign partial_sum[0][Y_WIDTH-1:A_WIDTH+`DSP_B_MAXWIDTH]=0;\r
+                       if (Y_WIDTH > int_yw)\r
+                               assign partial_sum[0][Y_WIDTH-1:A_WIDTH+`DSP_B_MAXWIDTH]=0;\r
 \r
                        for (i = 1; i < n-1; i=i+1) begin:slice\r
                                \$__mul_gen #(\r
@@ -157,11 +161,11 @@ module \$__mul_gen (A, B, Y);
                                        .B_SIGNED(B_SIGNED),\r
                                        .A_WIDTH(A_WIDTH),\r
                                        .B_WIDTH(`DSP_B_MAXWIDTH),\r
-                                               .Y_WIDTH(A_WIDTH+`DSP_B_MAXWIDTH)\r
+                                       .Y_WIDTH(int_yw)\r
                                ) mul (\r
                                        .A(A),\r
                                        .B(B[(i+1)*`DSP_B_MAXWIDTH-1:i*`DSP_B_MAXWIDTH]),\r
-                                       .Y(partial[i][A_WIDTH+`DSP_B_MAXWIDTH-1:0])\r
+                                       .Y(partial[i][int_yw-1:0])\r
                                );\r
                                //assign partial_sum[i] = (partial[i] << i*`DSP_B_MAXWIDTH) + partial_sum[i-1];\r
                                // was:\r
@@ -170,7 +174,7 @@ module \$__mul_gen (A, B, Y);
                                //      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][A_WIDTH+`DSP_B_MAXWIDTH-1:0]\r
+                                       partial[i][int_yw-1:0]\r
                                        + partial_sum[i-1][Y_WIDTH-1:(i*`DSP_B_MAXWIDTH)],\r
                                        partial_sum[i-1][(i*`DSP_B_MAXWIDTH)-1:0] \r
                                };\r
@@ -181,11 +185,11 @@ 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),\r
-                               .Y_WIDTH(A_WIDTH+B_WIDTH-(n-1)*`DSP_B_MAXWIDTH)\r
+                               .Y_WIDTH(`MIN(Y_WIDTH, A_WIDTH+B_WIDTH-(n-1)*`DSP_B_MAXWIDTH))\r
                        ) mul_last (\r
                                .A(A),\r
                                .B(B[B_WIDTH-1:(n-1)*`DSP_B_MAXWIDTH]),\r
-                               .Y(partial[n-1][A_WIDTH+B_WIDTH-(n-1)*`DSP_B_MAXWIDTH-1:0])\r
+                               .Y(partial[n-1][`MIN(Y_WIDTH, A_WIDTH+B_WIDTH-(n-1)*`DSP_B_MAXWIDTH)-1:0])\r
                        );\r
                        // AMD: this came comment out -- looks closer to right answer\r
                        //assign Y = (partial[n-1] << (n-1)*`DSP_B_MAXWIDTH) + partial_sum[n-2];\r
@@ -195,7 +199,7 @@ module \$__mul_gen (A, B, Y);
                        //      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][A_WIDTH+B_WIDTH-(n-1)*`DSP_B_MAXWIDTH-1:0]\r
+                               partial[n-1][`MIN(Y_WIDTH, A_WIDTH+B_WIDTH-(n-1)*`DSP_B_MAXWIDTH)-1:0]\r
                                + partial_sum[n-2][Y_WIDTH-1:((n-1)*`DSP_B_MAXWIDTH)],\r
                                partial_sum[n-2][((n-1)*`DSP_B_MAXWIDTH)-1:0]\r
                        };\r