| // 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 |