diff options
Diffstat (limited to 'techlibs/xilinx/arith_map.v')
-rw-r--r-- | techlibs/xilinx/arith_map.v | 205 |
1 files changed, 85 insertions, 120 deletions
diff --git a/techlibs/xilinx/arith_map.v b/techlibs/xilinx/arith_map.v index 40c378d16..2b8b0dcc1 100644 --- a/techlibs/xilinx/arith_map.v +++ b/techlibs/xilinx/arith_map.v @@ -34,6 +34,12 @@ module _80_xilinx_lcu (P, G, CI, CO); genvar i; `ifdef _EXPLICIT_CARRY + localparam EXPLICIT_CARRY = 1'b1; +`else + localparam EXPLICIT_CARRY = 1'b0; +`endif + +generate if (EXPLICIT_CARRY || `LUT_SIZE == 4) begin wire [WIDTH-1:0] C = {CO, CI}; wire [WIDTH-1:0] S = P & ~G; @@ -47,71 +53,39 @@ module _80_xilinx_lcu (P, G, CI, CO); ); end endgenerate -`else +end else begin localparam CARRY4_COUNT = (WIDTH + 3) / 4; localparam MAX_WIDTH = CARRY4_COUNT * 4; localparam PAD_WIDTH = MAX_WIDTH - WIDTH; - wire [MAX_WIDTH-1:0] S = {{PAD_WIDTH{1'b0}}, P & ~G}; - wire [MAX_WIDTH-1:0] C = CO; + wire [MAX_WIDTH-1:0] S = {{PAD_WIDTH{1'b0}}, P & ~G}; + wire [MAX_WIDTH-1:0] GG = {{PAD_WIDTH{1'b0}}, G}; + wire [MAX_WIDTH-1:0] C; + assign CO = C; generate for (i = 0; i < CARRY4_COUNT; i = i + 1) begin:slice - - // Partially occupied CARRY4 - if ((i+1)*4 > WIDTH) begin - - // First one - if (i == 0) begin - CARRY4 carry4_1st_part - ( - .CYINIT(CI), - .CI (1'd0), - .DI (G [(WIDTH - 1):i*4]), - .S (S [(WIDTH - 1):i*4]), - .CO (CO[(WIDTH - 1):i*4]), - ); - // Another one - end else begin - CARRY4 carry4_part - ( - .CYINIT(1'd0), - .CI (C [i*4 - 1]), - .DI (G [(WIDTH - 1):i*4]), - .S (S [(WIDTH - 1):i*4]), - .CO (CO[(WIDTH - 1):i*4]), - ); - end - - // Fully occupied CARRY4 + if (i == 0) begin + CARRY4 carry4 + ( + .CYINIT(CI), + .CI (1'd0), + .DI (GG[i*4 +: 4]), + .S (S [i*4 +: 4]), + .CO (C [i*4 +: 4]), + ); end else begin - - // First one - if (i == 0) begin - CARRY4 carry4_1st_full - ( - .CYINIT(CI), - .CI (1'd0), - .DI (G [((i+1)*4 - 1):i*4]), - .S (S [((i+1)*4 - 1):i*4]), - .CO (CO[((i+1)*4 - 1):i*4]), - ); - // Another one - end else begin - CARRY4 carry4_full - ( - .CYINIT(1'd0), - .CI (C [i*4 - 1]), - .DI (G [((i+1)*4 - 1):i*4]), - .S (S [((i+1)*4 - 1):i*4]), - .CO (CO[((i+1)*4 - 1):i*4]), - ); - end - + CARRY4 carry4 + ( + .CYINIT(1'd0), + .CI (C [i*4 - 1]), + .DI (GG[i*4 +: 4]), + .S (S [i*4 +: 4]), + .CO (C [i*4 +: 4]), + ); end - end endgenerate -`endif +end endgenerate endmodule @@ -148,9 +122,34 @@ module _80_xilinx_alu (A, B, CI, BI, X, Y, CO); genvar i; `ifdef _EXPLICIT_CARRY + localparam EXPLICIT_CARRY = 1'b1; +`else + localparam EXPLICIT_CARRY = 1'b0; +`endif + +generate if (`LUT_SIZE == 4) begin + + wire [Y_WIDTH-1:0] C = {CO, CI}; + wire [Y_WIDTH-1:0] S = {AA ^ BB}; + + genvar i; + generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice + MUXCY muxcy ( + .CI(C[i]), + .DI(AA[i]), + .S(S[i]), + .O(CO[i]) + ); + XORCY xorcy ( + .CI(C[i]), + .LI(S[i]), + .O(Y[i]) + ); + end endgenerate + +end else if (EXPLICIT_CARRY) begin wire [Y_WIDTH-1:0] S = AA ^ BB; - wire [Y_WIDTH-1:0] DI = AA & BB; wire CINIT; // Carry chain. @@ -170,7 +169,7 @@ module _80_xilinx_alu (A, B, CI, BI, X, Y, CO); generate for (i = 0; i < 1; i = i + 1) begin:slice CARRY0 #(.CYINIT_FABRIC(1)) carry( .CI_INIT(CI), - .DI(DI[0]), + .DI(AA[0]), .S(S[0]), .CO_CHAIN(CO_CHAIN[0]), .CO_FABRIC(CO[0]), @@ -182,7 +181,7 @@ module _80_xilinx_alu (A, B, CI, BI, X, Y, CO); if(i % 4 == 0) begin CARRY0 carry ( .CI(C[i]), - .DI(DI[i]), + .DI(AA[i]), .S(S[i]), .CO_CHAIN(CO_CHAIN[i]), .CO_FABRIC(CO[i]), @@ -193,7 +192,7 @@ module _80_xilinx_alu (A, B, CI, BI, X, Y, CO); begin CARRY carry ( .CI(C[i]), - .DI(DI[i]), + .DI(AA[i]), .S(S[i]), .CO_CHAIN(CO_CHAIN[i]), .CO_FABRIC(CO[i]), @@ -206,7 +205,7 @@ module _80_xilinx_alu (A, B, CI, BI, X, Y, CO); if(i % 4 == 0) begin CARRY0 top_of_carry ( .CI(C[i]), - .DI(DI[i]), + .DI(AA[i]), .S(S[i]), .CO_CHAIN(CO_CHAIN[i]), .O(Y[i]) @@ -216,7 +215,7 @@ module _80_xilinx_alu (A, B, CI, BI, X, Y, CO); begin CARRY top_of_carry ( .CI(C[i]), - .DI(DI[i]), + .DI(AA[i]), .S(S[i]), .CO_CHAIN(CO_CHAIN[i]), .O(Y[i]) @@ -245,79 +244,45 @@ module _80_xilinx_alu (A, B, CI, BI, X, Y, CO); end end endgenerate -`else +end else begin localparam CARRY4_COUNT = (Y_WIDTH + 3) / 4; localparam MAX_WIDTH = CARRY4_COUNT * 4; localparam PAD_WIDTH = MAX_WIDTH - Y_WIDTH; wire [MAX_WIDTH-1:0] S = {{PAD_WIDTH{1'b0}}, AA ^ BB}; - wire [MAX_WIDTH-1:0] DI = {{PAD_WIDTH{1'b0}}, AA & BB}; + wire [MAX_WIDTH-1:0] DI = {{PAD_WIDTH{1'b0}}, AA}; - wire [MAX_WIDTH-1:0] C = CO; + wire [MAX_WIDTH-1:0] O; + wire [MAX_WIDTH-1:0] C; + assign Y = O, CO = C; genvar i; generate for (i = 0; i < CARRY4_COUNT; i = i + 1) begin:slice - - // Partially occupied CARRY4 - if ((i+1)*4 > Y_WIDTH) begin - - // First one - if (i == 0) begin - CARRY4 carry4_1st_part - ( - .CYINIT(CI), - .CI (1'd0), - .DI (DI[(Y_WIDTH - 1):i*4]), - .S (S [(Y_WIDTH - 1):i*4]), - .O (Y [(Y_WIDTH - 1):i*4]), - .CO (CO[(Y_WIDTH - 1):i*4]) - ); - // Another one - end else begin - CARRY4 carry4_part - ( - .CYINIT(1'd0), - .CI (C [i*4 - 1]), - .DI (DI[(Y_WIDTH - 1):i*4]), - .S (S [(Y_WIDTH - 1):i*4]), - .O (Y [(Y_WIDTH - 1):i*4]), - .CO (CO[(Y_WIDTH - 1):i*4]) - ); - end - - // Fully occupied CARRY4 + if (i == 0) begin + CARRY4 carry4 + ( + .CYINIT(CI), + .CI (1'd0), + .DI (DI[i*4 +: 4]), + .S (S [i*4 +: 4]), + .O (O [i*4 +: 4]), + .CO (C [i*4 +: 4]) + ); end else begin - - // First one - if (i == 0) begin - CARRY4 carry4_1st_full - ( - .CYINIT(CI), - .CI (1'd0), - .DI (DI[((i+1)*4 - 1):i*4]), - .S (S [((i+1)*4 - 1):i*4]), - .O (Y [((i+1)*4 - 1):i*4]), - .CO (CO[((i+1)*4 - 1):i*4]) - ); - // Another one - end else begin - CARRY4 carry4_full - ( - .CYINIT(1'd0), - .CI (C [i*4 - 1]), - .DI (DI[((i+1)*4 - 1):i*4]), - .S (S [((i+1)*4 - 1):i*4]), - .O (Y [((i+1)*4 - 1):i*4]), - .CO (CO[((i+1)*4 - 1):i*4]) - ); - end - + CARRY4 carry4 + ( + .CYINIT(1'd0), + .CI (C [i*4 - 1]), + .DI (DI[i*4 +: 4]), + .S (S [i*4 +: 4]), + .O (O [i*4 +: 4]), + .CO (C [i*4 +: 4]) + ); end - end endgenerate -`endif +end endgenerate assign X = S; endmodule |