// reduction' approach also exists...\r
if (i == 0)\r
assign partial_sum[i] = partial[i];\r
- else\r
- assign partial_sum[i] = (partial[i] << i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)) + partial_sum[i-1];\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
+ 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
+ end\r
end\r
\r
\$__mul #(\r
.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
+ //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
assign Y = partial_sum[n];\r
end\r
else if (B_WIDTH > `DSP_B_MAXWIDTH) begin\r
// reduction' approach also exists...\r
if (i == 0)\r
assign partial_sum[i] = partial[i];\r
- else\r
- assign partial_sum[i] = (partial[i] << i*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)) + partial_sum[i-1];\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
+ 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
+ end\r
end\r
\r
\$__mul #(\r
.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
+ //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
assign Y = partial_sum[n];\r
end\r
else begin\r
if (!nodsp || help_mode) {
// NB: Xilinx multipliers are signed only
run("techmap -map +/mul2dsp.v -map +/xilinx/dsp_map.v -D DSP_A_MAXWIDTH=25 -D DSP_A_MAXWIDTH_PARTIAL=18 -D DSP_B_MAXWIDTH=18 -D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL25X18", "(skip if '-nodsp')");
- // Necessary for optimising away $shl cells, as well as $add cells
- // that have inputs with 1'b0 LSBs
- run("opt_expr -fine", " (skip if '-nodsp')");
run("xilinx_dsp", " (skip if '-nodsp')");
run("chtype -set $mul t:$__soft_mul"," (skip if '-nodsp')");
}