blob: 298a8b0b33e18670bd3cd4b6ea6e6ee9a57b0fd0 [file] [log] [blame] [edit]
// Output CO directly
module CARRY_CO_DIRECT(input CO, input O, input S, input DI, output OUT);
parameter TOP_OF_CHAIN = 1'b0;
assign OUT = CO;
endmodule
// Compute CO from S, DI, O.
module CARRY_CO_LUT(input CO, input O, input S, input DI, output OUT);
parameter TOP_OF_CHAIN = 1'b0;
generate if(TOP_OF_CHAIN)
// S == S[i]
// DI == DI[i]
// O == O[i]
// CO == CO[i]
//
// Need to replicate both MUXCY and XORCY to get CO[i].
//
// Equations:
// 1) CO[i] = S[i] ? CO[i-1] : DI[i]
// 2) O[i] = S[i] ^ CO[i-1]
//
// -- Add "S[i] ^" to the front of both sides of eq 2 --
//
// 3) S[i] ^ O[i] = S[i] ^ S[i] ^ CO[i-1]
//
// -- Apply A ^ A = 0 to eq 3 --
//
// 4) S[i] ^ O[i] = 0 ^ CO[i-1]
//
// -- Apply A ^ B = B ^ A to eq 4
//
// 5) S[i] ^ O[i] = CO[i-1] ^ 0
//
// -- Apply A ^ 0 = A to eq 5
//
// 6) S[i] ^ O[i] = CO[i-1]
//
// -- subsititude CO[i-1] from eq 6 into equation 1 --
//
// 7) CO[i] = S[i] ? (S[i] ^ O[i]) : DI[i]
//
// DI, S, O (0, 0, 0) = 0 => OUT = DI => 0
// DI, S, O (0, 0, 1) = 1 => OUT = DI => 0
// DI, S, O (0, 1, 0) = 2 => OUT = S ^ O => 1
// DI, S, O (0, 1, 1) = 3 => OUT = S ^ O => 0
// DI, S, O (1, 0, 0) = 4 => OUT = DI => 1
// DI, S, O (1, 0, 1) = 5 => OUT = DI => 1
// DI, S, O (1, 1, 0) = 6 => OUT = S ^ O => 1
// DI, S, O (1, 1, 1) = 7 => OUT = S ^ O => 0
//
LUT3 #(.INIT(8'b01110100)) mux_and_xor_lut (.I0(O), .I1(S), .I2(DI), .O(OUT));
else
// S == S[i+1]
// O == O[i+1]
// CO == CO[i]
//
// Because S/O from next level is available, equation is simply:
//
// CO[i] = S[i+1] ^ O[i+1]
//
// S, O (0, 0) = 0 => 0
// S, O (0, 1) = 1 => 1
// S, O (1, 0) = 2 => 1
// S, O (1, 1) = 3 => 0
//
LUT2 #(.INIT(4'b0110)) xor_lut (.I0(O), .I1(S), .O(OUT));
endgenerate
endmodule
module CARRY_CO_TOP_POP(input CO, input O, input S, input DI, output OUT);
// Add 1 dummy layer to the carry chain to get the CO, this can only be used
// at the top of the carry chain when CO[3] was needed.
parameter TOP_OF_CHAIN = 1'b0;
wire cin_from_below;
CARRY_COUT_PLUG cin_plug(
.CIN(CO),
.COUT(cin_from_below)
);
CARRY4_VPR #(
.CYINIT_AX(1'b0),
.CYINIT_C0(1'b0),
.CYINIT_C1(1'b0)
) dummy (
.CIN(cin_from_below),
.O0(OUT),
.S0(1'b0)
);
endmodule