diff options
author | Clifford Wolf <clifford@clifford.at> | 2014-03-06 11:54:22 +0100 |
---|---|---|
committer | Clifford Wolf <clifford@clifford.at> | 2014-03-06 12:14:20 +0100 |
commit | d7f29bb23f9bb2c74e02bc1221bcf27efc7ee4dc (patch) | |
tree | 903f3af6c8ea53b48851c2a3d8b99a10f1fce6c3 /techlibs | |
parent | a1bfde8c5ea0d5c9778579bf78165637ac6c9b25 (diff) | |
download | yosys-d7f29bb23f9bb2c74e02bc1221bcf27efc7ee4dc.tar.gz yosys-d7f29bb23f9bb2c74e02bc1221bcf27efc7ee4dc.tar.bz2 yosys-d7f29bb23f9bb2c74e02bc1221bcf27efc7ee4dc.zip |
Improved techmap of shift with wide B inputs
Diffstat (limited to 'techlibs')
-rw-r--r-- | techlibs/common/stdcells.v | 50 |
1 files changed, 37 insertions, 13 deletions
diff --git a/techlibs/common/stdcells.v b/techlibs/common/stdcells.v index fdee26b6f..a51dcb944 100644 --- a/techlibs/common/stdcells.v +++ b/techlibs/common/stdcells.v @@ -165,6 +165,7 @@ parameter B_WIDTH = 1; parameter Y_WIDTH = 1; parameter WIDTH = Y_WIDTH; +localparam BB_WIDTH = $clog2(WIDTH) + 1 < B_WIDTH ? $clog2(WIDTH) + 1 : B_WIDTH; input [A_WIDTH-1:0] A; input [B_WIDTH-1:0] B; @@ -181,11 +182,16 @@ generate .A(A), .Y(chain[WIDTH-1:0]) ); - assign Y = chain[WIDTH*(B_WIDTH+1)-1 : WIDTH*B_WIDTH]; - for (i = 0; i < B_WIDTH; i = i + 1) begin:V + assign Y = chain[WIDTH*(BB_WIDTH+1)-1 : WIDTH*BB_WIDTH]; + for (i = 0; i < BB_WIDTH; i = i + 1) begin:V wire [WIDTH-1:0] unshifted, shifted, result; assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i]; assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result; + wire BBIT; + if (i == BB_WIDTH-1 && BB_WIDTH < B_WIDTH) + assign BBIT = |B[B_WIDTH-1:BB_WIDTH-1]; + else + assign BBIT = B[i]; \$__shift #( .WIDTH(WIDTH), .SHIFT(0 - (2 ** (i > 30 ? 30 : i))) @@ -200,7 +206,7 @@ generate .A(unshifted), .B(shifted), .Y(result), - .S(B[i]) + .S(BBIT) ); end endgenerate @@ -218,6 +224,7 @@ parameter B_WIDTH = 1; parameter Y_WIDTH = 1; localparam WIDTH = A_WIDTH > Y_WIDTH ? A_WIDTH : Y_WIDTH; +localparam BB_WIDTH = $clog2(WIDTH) + 1 < B_WIDTH ? $clog2(WIDTH) + 1 : B_WIDTH; input [A_WIDTH-1:0] A; input [B_WIDTH-1:0] B; @@ -225,7 +232,7 @@ output [Y_WIDTH-1:0] Y; genvar i; generate - wire [WIDTH*(B_WIDTH+1)-1:0] chain; + wire [WIDTH*(BB_WIDTH+1)-1:0] chain; \$pos #( .A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), @@ -234,11 +241,16 @@ generate .A(A), .Y(chain[WIDTH-1:0]) ); - assign Y = chain[WIDTH*(B_WIDTH+1)-1 : WIDTH*B_WIDTH]; - for (i = 0; i < B_WIDTH; i = i + 1) begin:V + assign Y = chain[WIDTH*(BB_WIDTH+1)-1 : WIDTH*BB_WIDTH]; + for (i = 0; i < BB_WIDTH; i = i + 1) begin:V wire [WIDTH-1:0] unshifted, shifted, result; assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i]; assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result; + wire BBIT; + if (i == BB_WIDTH-1 && BB_WIDTH < B_WIDTH) + assign BBIT = |B[B_WIDTH-1:BB_WIDTH-1]; + else + assign BBIT = B[i]; \$__shift #( .WIDTH(WIDTH), .SHIFT(2 ** (i > 30 ? 30 : i)) @@ -253,7 +265,7 @@ generate .A(unshifted), .B(shifted), .Y(result), - .S(B[i]) + .S(BBIT) ); end endgenerate @@ -271,6 +283,7 @@ parameter B_WIDTH = 1; parameter Y_WIDTH = 1; localparam WIDTH = Y_WIDTH; +localparam BB_WIDTH = $clog2(WIDTH) + 1 < B_WIDTH ? $clog2(WIDTH) + 1 : B_WIDTH; input [A_WIDTH-1:0] A; input [B_WIDTH-1:0] B; @@ -292,6 +305,11 @@ generate wire [WIDTH-1:0] unshifted, shifted, result; assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i]; assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result; + wire BBIT; + if (i == BB_WIDTH-1 && BB_WIDTH < B_WIDTH) + assign BBIT = |B[B_WIDTH-1:BB_WIDTH-1]; + else + assign BBIT = B[i]; \$__shift #( .WIDTH(WIDTH), .SHIFT(0 - (2 ** (i > 30 ? 30 : i))) @@ -306,7 +324,7 @@ generate .A(unshifted), .B(shifted), .Y(result), - .S(B[i]) + .S(BBIT) ); end endgenerate @@ -324,6 +342,7 @@ parameter B_WIDTH = 1; parameter Y_WIDTH = 1; localparam WIDTH = A_WIDTH > Y_WIDTH ? A_WIDTH : Y_WIDTH; +localparam BB_WIDTH = $clog2(WIDTH) + 1 < B_WIDTH ? $clog2(WIDTH) + 1 : B_WIDTH; input [A_WIDTH-1:0] A; input [B_WIDTH-1:0] B; @@ -331,7 +350,7 @@ output [Y_WIDTH-1:0] Y; genvar i; generate - wire [WIDTH*(B_WIDTH+1)-1:0] chain; + wire [WIDTH*(BB_WIDTH+1)-1:0] chain; \$pos #( .A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), @@ -342,18 +361,23 @@ generate ); for (i = 0; i < Y_WIDTH; i = i + 1) begin:Y if (i < WIDTH) begin - assign Y[i] = chain[WIDTH*B_WIDTH + i]; + assign Y[i] = chain[WIDTH*BB_WIDTH + i]; end else if (A_SIGNED) begin - assign Y[i] = chain[WIDTH*B_WIDTH + WIDTH-1]; + assign Y[i] = chain[WIDTH*BB_WIDTH + WIDTH-1]; end else begin assign Y[i] = 0; end end - for (i = 0; i < B_WIDTH; i = i + 1) begin:V + for (i = 0; i < BB_WIDTH; i = i + 1) begin:V wire [WIDTH-1:0] unshifted, shifted, result; assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i]; assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result; + wire BBIT; + if (i == BB_WIDTH-1 && BB_WIDTH < B_WIDTH) + assign BBIT = |B[B_WIDTH-1:BB_WIDTH-1]; + else + assign BBIT = B[i]; \$__shift #( .WIDTH(WIDTH), .SHIFT(2 ** (i > 30 ? 30 : i)) @@ -368,7 +392,7 @@ generate .A(unshifted), .B(shifted), .Y(result), - .S(B[i]) + .S(BBIT) ); end endgenerate |