// ************************************************************************** //
//                                                                            //
//    eses                   eses                                             //
//   eses                     eses                                            //
//  eses    eseses  esesese    eses   Embedded Systems Group                  //
//  ese    ese  ese ese         ese                                           //
//  ese    eseseses eseseses    ese   Department of Computer Science          //
//  eses   eses          ese   eses                                           //
//   eses   eseses  eseseses  eses    University of Kaiserslautern            //
//    eses                   eses                                             //
//                                                                            //
// ************************************************************************** //


[64]nat x;
[64]nat y;
[65]nat s;

thread RadixBAddCarryLookahead64 {
    [64]bool g;
    [64]bool p;
    // preliminary sum digits
    s[0] = x[0] + y[0];
    s[1] = x[1] + y[1];
    s[2] = x[2] + y[2];
    s[3] = x[3] + y[3];
    s[4] = x[4] + y[4];
    s[5] = x[5] + y[5];
    s[6] = x[6] + y[6];
    s[7] = x[7] + y[7];
    s[8] = x[8] + y[8];
    s[9] = x[9] + y[9];
    s[10] = x[10] + y[10];
    s[11] = x[11] + y[11];
    s[12] = x[12] + y[12];
    s[13] = x[13] + y[13];
    s[14] = x[14] + y[14];
    s[15] = x[15] + y[15];
    s[16] = x[16] + y[16];
    s[17] = x[17] + y[17];
    s[18] = x[18] + y[18];
    s[19] = x[19] + y[19];
    s[20] = x[20] + y[20];
    s[21] = x[21] + y[21];
    s[22] = x[22] + y[22];
    s[23] = x[23] + y[23];
    s[24] = x[24] + y[24];
    s[25] = x[25] + y[25];
    s[26] = x[26] + y[26];
    s[27] = x[27] + y[27];
    s[28] = x[28] + y[28];
    s[29] = x[29] + y[29];
    s[30] = x[30] + y[30];
    s[31] = x[31] + y[31];
    s[32] = x[32] + y[32];
    s[33] = x[33] + y[33];
    s[34] = x[34] + y[34];
    s[35] = x[35] + y[35];
    s[36] = x[36] + y[36];
    s[37] = x[37] + y[37];
    s[38] = x[38] + y[38];
    s[39] = x[39] + y[39];
    s[40] = x[40] + y[40];
    s[41] = x[41] + y[41];
    s[42] = x[42] + y[42];
    s[43] = x[43] + y[43];
    s[44] = x[44] + y[44];
    s[45] = x[45] + y[45];
    s[46] = x[46] + y[46];
    s[47] = x[47] + y[47];
    s[48] = x[48] + y[48];
    s[49] = x[49] + y[49];
    s[50] = x[50] + y[50];
    s[51] = x[51] + y[51];
    s[52] = x[52] + y[52];
    s[53] = x[53] + y[53];
    s[54] = x[54] + y[54];
    s[55] = x[55] + y[55];
    s[56] = x[56] + y[56];
    s[57] = x[57] + y[57];
    s[58] = x[58] + y[58];
    s[59] = x[59] + y[59];
    s[60] = x[60] + y[60];
    s[61] = x[61] + y[61];
    s[62] = x[62] + y[62];
    s[63] = x[63] + y[63];
    // initial generate conditions
    g[0] = s[0]>255;
    g[1] = s[1]>255;
    g[2] = s[2]>255;
    g[3] = s[3]>255;
    g[4] = s[4]>255;
    g[5] = s[5]>255;
    g[6] = s[6]>255;
    g[7] = s[7]>255;
    g[8] = s[8]>255;
    g[9] = s[9]>255;
    g[10] = s[10]>255;
    g[11] = s[11]>255;
    g[12] = s[12]>255;
    g[13] = s[13]>255;
    g[14] = s[14]>255;
    g[15] = s[15]>255;
    g[16] = s[16]>255;
    g[17] = s[17]>255;
    g[18] = s[18]>255;
    g[19] = s[19]>255;
    g[20] = s[20]>255;
    g[21] = s[21]>255;
    g[22] = s[22]>255;
    g[23] = s[23]>255;
    g[24] = s[24]>255;
    g[25] = s[25]>255;
    g[26] = s[26]>255;
    g[27] = s[27]>255;
    g[28] = s[28]>255;
    g[29] = s[29]>255;
    g[30] = s[30]>255;
    g[31] = s[31]>255;
    g[32] = s[32]>255;
    g[33] = s[33]>255;
    g[34] = s[34]>255;
    g[35] = s[35]>255;
    g[36] = s[36]>255;
    g[37] = s[37]>255;
    g[38] = s[38]>255;
    g[39] = s[39]>255;
    g[40] = s[40]>255;
    g[41] = s[41]>255;
    g[42] = s[42]>255;
    g[43] = s[43]>255;
    g[44] = s[44]>255;
    g[45] = s[45]>255;
    g[46] = s[46]>255;
    g[47] = s[47]>255;
    g[48] = s[48]>255;
    g[49] = s[49]>255;
    g[50] = s[50]>255;
    g[51] = s[51]>255;
    g[52] = s[52]>255;
    g[53] = s[53]>255;
    g[54] = s[54]>255;
    g[55] = s[55]>255;
    g[56] = s[56]>255;
    g[57] = s[57]>255;
    g[58] = s[58]>255;
    g[59] = s[59]>255;
    g[60] = s[60]>255;
    g[61] = s[61]>255;
    g[62] = s[62]>255;
    g[63] = s[63]>255;
    // initial propagate conditions
    p[0] = s[0]==255;
    p[1] = s[1]==255;
    p[2] = s[2]==255;
    p[3] = s[3]==255;
    p[4] = s[4]==255;
    p[5] = s[5]==255;
    p[6] = s[6]==255;
    p[7] = s[7]==255;
    p[8] = s[8]==255;
    p[9] = s[9]==255;
    p[10] = s[10]==255;
    p[11] = s[11]==255;
    p[12] = s[12]==255;
    p[13] = s[13]==255;
    p[14] = s[14]==255;
    p[15] = s[15]==255;
    p[16] = s[16]==255;
    p[17] = s[17]==255;
    p[18] = s[18]==255;
    p[19] = s[19]==255;
    p[20] = s[20]==255;
    p[21] = s[21]==255;
    p[22] = s[22]==255;
    p[23] = s[23]==255;
    p[24] = s[24]==255;
    p[25] = s[25]==255;
    p[26] = s[26]==255;
    p[27] = s[27]==255;
    p[28] = s[28]==255;
    p[29] = s[29]==255;
    p[30] = s[30]==255;
    p[31] = s[31]==255;
    p[32] = s[32]==255;
    p[33] = s[33]==255;
    p[34] = s[34]==255;
    p[35] = s[35]==255;
    p[36] = s[36]==255;
    p[37] = s[37]==255;
    p[38] = s[38]==255;
    p[39] = s[39]==255;
    p[40] = s[40]==255;
    p[41] = s[41]==255;
    p[42] = s[42]==255;
    p[43] = s[43]==255;
    p[44] = s[44]==255;
    p[45] = s[45]==255;
    p[46] = s[46]==255;
    p[47] = s[47]==255;
    p[48] = s[48]==255;
    p[49] = s[49]==255;
    p[50] = s[50]==255;
    p[51] = s[51]==255;
    p[52] = s[52]==255;
    p[53] = s[53]==255;
    p[54] = s[54]==255;
    p[55] = s[55]==255;
    p[56] = s[56]==255;
    p[57] = s[57]==255;
    p[58] = s[58]==255;
    p[59] = s[59]==255;
    p[60] = s[60]==255;
    p[61] = s[61]==255;
    p[62] = s[62]==255;
    p[63] = s[63]==255;
    // carry propagation prefix tree
    // up-level 1
    g[1] = g[0] & p[1] | g[1];
    p[1] = p[1] & p[0];
    g[3] = g[2] & p[3] | g[3];
    p[3] = p[3] & p[2];
    g[5] = g[4] & p[5] | g[5];
    p[5] = p[5] & p[4];
    g[7] = g[6] & p[7] | g[7];
    p[7] = p[7] & p[6];
    g[9] = g[8] & p[9] | g[9];
    p[9] = p[9] & p[8];
    g[11] = g[10] & p[11] | g[11];
    p[11] = p[11] & p[10];
    g[13] = g[12] & p[13] | g[13];
    p[13] = p[13] & p[12];
    g[15] = g[14] & p[15] | g[15];
    p[15] = p[15] & p[14];
    g[17] = g[16] & p[17] | g[17];
    p[17] = p[17] & p[16];
    g[19] = g[18] & p[19] | g[19];
    p[19] = p[19] & p[18];
    g[21] = g[20] & p[21] | g[21];
    p[21] = p[21] & p[20];
    g[23] = g[22] & p[23] | g[23];
    p[23] = p[23] & p[22];
    g[25] = g[24] & p[25] | g[25];
    p[25] = p[25] & p[24];
    g[27] = g[26] & p[27] | g[27];
    p[27] = p[27] & p[26];
    g[29] = g[28] & p[29] | g[29];
    p[29] = p[29] & p[28];
    g[31] = g[30] & p[31] | g[31];
    p[31] = p[31] & p[30];
    g[33] = g[32] & p[33] | g[33];
    p[33] = p[33] & p[32];
    g[35] = g[34] & p[35] | g[35];
    p[35] = p[35] & p[34];
    g[37] = g[36] & p[37] | g[37];
    p[37] = p[37] & p[36];
    g[39] = g[38] & p[39] | g[39];
    p[39] = p[39] & p[38];
    g[41] = g[40] & p[41] | g[41];
    p[41] = p[41] & p[40];
    g[43] = g[42] & p[43] | g[43];
    p[43] = p[43] & p[42];
    g[45] = g[44] & p[45] | g[45];
    p[45] = p[45] & p[44];
    g[47] = g[46] & p[47] | g[47];
    p[47] = p[47] & p[46];
    g[49] = g[48] & p[49] | g[49];
    p[49] = p[49] & p[48];
    g[51] = g[50] & p[51] | g[51];
    p[51] = p[51] & p[50];
    g[53] = g[52] & p[53] | g[53];
    p[53] = p[53] & p[52];
    g[55] = g[54] & p[55] | g[55];
    p[55] = p[55] & p[54];
    g[57] = g[56] & p[57] | g[57];
    p[57] = p[57] & p[56];
    g[59] = g[58] & p[59] | g[59];
    p[59] = p[59] & p[58];
    g[61] = g[60] & p[61] | g[61];
    p[61] = p[61] & p[60];
    g[63] = g[62] & p[63] | g[63];
    p[63] = p[63] & p[62];
    // up-level 2
    g[3] = g[1] & p[3] | g[3];
    p[3] = p[3] & p[1];
    g[7] = g[5] & p[7] | g[7];
    p[7] = p[7] & p[5];
    g[11] = g[9] & p[11] | g[11];
    p[11] = p[11] & p[9];
    g[15] = g[13] & p[15] | g[15];
    p[15] = p[15] & p[13];
    g[19] = g[17] & p[19] | g[19];
    p[19] = p[19] & p[17];
    g[23] = g[21] & p[23] | g[23];
    p[23] = p[23] & p[21];
    g[27] = g[25] & p[27] | g[27];
    p[27] = p[27] & p[25];
    g[31] = g[29] & p[31] | g[31];
    p[31] = p[31] & p[29];
    g[35] = g[33] & p[35] | g[35];
    p[35] = p[35] & p[33];
    g[39] = g[37] & p[39] | g[39];
    p[39] = p[39] & p[37];
    g[43] = g[41] & p[43] | g[43];
    p[43] = p[43] & p[41];
    g[47] = g[45] & p[47] | g[47];
    p[47] = p[47] & p[45];
    g[51] = g[49] & p[51] | g[51];
    p[51] = p[51] & p[49];
    g[55] = g[53] & p[55] | g[55];
    p[55] = p[55] & p[53];
    g[59] = g[57] & p[59] | g[59];
    p[59] = p[59] & p[57];
    g[63] = g[61] & p[63] | g[63];
    p[63] = p[63] & p[61];
    // up-level 3
    g[7] = g[3] & p[7] | g[7];
    p[7] = p[7] & p[3];
    g[15] = g[11] & p[15] | g[15];
    p[15] = p[15] & p[11];
    g[23] = g[19] & p[23] | g[23];
    p[23] = p[23] & p[19];
    g[31] = g[27] & p[31] | g[31];
    p[31] = p[31] & p[27];
    g[39] = g[35] & p[39] | g[39];
    p[39] = p[39] & p[35];
    g[47] = g[43] & p[47] | g[47];
    p[47] = p[47] & p[43];
    g[55] = g[51] & p[55] | g[55];
    p[55] = p[55] & p[51];
    g[63] = g[59] & p[63] | g[63];
    p[63] = p[63] & p[59];
    // up-level 4
    g[15] = g[7] & p[15] | g[15];
    p[15] = p[15] & p[7];
    g[31] = g[23] & p[31] | g[31];
    p[31] = p[31] & p[23];
    g[47] = g[39] & p[47] | g[47];
    p[47] = p[47] & p[39];
    g[63] = g[55] & p[63] | g[63];
    p[63] = p[63] & p[55];
    // up-level 5
    g[31] = g[15] & p[31] | g[31];
    p[31] = p[31] & p[15];
    g[63] = g[47] & p[63] | g[63];
    p[63] = p[63] & p[47];
    // up-level 6
    g[63] = g[31] & p[63] | g[63];
    p[63] = p[63] & p[31];
    // down-level 8
    // down-level 9
    g[47] = g[31] & p[47] | g[47];
    p[47] = p[47] & p[31];
    // down-level 10
    g[23] = g[15] & p[23] | g[23];
    p[23] = p[23] & p[15];
    g[39] = g[31] & p[39] | g[39];
    p[39] = p[39] & p[31];
    g[55] = g[47] & p[55] | g[55];
    p[55] = p[55] & p[47];
    // down-level 11
    g[11] = g[7] & p[11] | g[11];
    p[11] = p[11] & p[7];
    g[19] = g[15] & p[19] | g[19];
    p[19] = p[19] & p[15];
    g[27] = g[23] & p[27] | g[27];
    p[27] = p[27] & p[23];
    g[35] = g[31] & p[35] | g[35];
    p[35] = p[35] & p[31];
    g[43] = g[39] & p[43] | g[43];
    p[43] = p[43] & p[39];
    g[51] = g[47] & p[51] | g[51];
    p[51] = p[51] & p[47];
    g[59] = g[55] & p[59] | g[59];
    p[59] = p[59] & p[55];
    // down-level 12
    g[5] = g[3] & p[5] | g[5];
    p[5] = p[5] & p[3];
    g[9] = g[7] & p[9] | g[9];
    p[9] = p[9] & p[7];
    g[13] = g[11] & p[13] | g[13];
    p[13] = p[13] & p[11];
    g[17] = g[15] & p[17] | g[17];
    p[17] = p[17] & p[15];
    g[21] = g[19] & p[21] | g[21];
    p[21] = p[21] & p[19];
    g[25] = g[23] & p[25] | g[25];
    p[25] = p[25] & p[23];
    g[29] = g[27] & p[29] | g[29];
    p[29] = p[29] & p[27];
    g[33] = g[31] & p[33] | g[33];
    p[33] = p[33] & p[31];
    g[37] = g[35] & p[37] | g[37];
    p[37] = p[37] & p[35];
    g[41] = g[39] & p[41] | g[41];
    p[41] = p[41] & p[39];
    g[45] = g[43] & p[45] | g[45];
    p[45] = p[45] & p[43];
    g[49] = g[47] & p[49] | g[49];
    p[49] = p[49] & p[47];
    g[53] = g[51] & p[53] | g[53];
    p[53] = p[53] & p[51];
    g[57] = g[55] & p[57] | g[57];
    p[57] = p[57] & p[55];
    g[61] = g[59] & p[61] | g[61];
    p[61] = p[61] & p[59];
    // down-level 13
    g[2] = g[1] & p[2] | g[2];
    p[2] = p[2] & p[1];
    g[4] = g[3] & p[4] | g[4];
    p[4] = p[4] & p[3];
    g[6] = g[5] & p[6] | g[6];
    p[6] = p[6] & p[5];
    g[8] = g[7] & p[8] | g[8];
    p[8] = p[8] & p[7];
    g[10] = g[9] & p[10] | g[10];
    p[10] = p[10] & p[9];
    g[12] = g[11] & p[12] | g[12];
    p[12] = p[12] & p[11];
    g[14] = g[13] & p[14] | g[14];
    p[14] = p[14] & p[13];
    g[16] = g[15] & p[16] | g[16];
    p[16] = p[16] & p[15];
    g[18] = g[17] & p[18] | g[18];
    p[18] = p[18] & p[17];
    g[20] = g[19] & p[20] | g[20];
    p[20] = p[20] & p[19];
    g[22] = g[21] & p[22] | g[22];
    p[22] = p[22] & p[21];
    g[24] = g[23] & p[24] | g[24];
    p[24] = p[24] & p[23];
    g[26] = g[25] & p[26] | g[26];
    p[26] = p[26] & p[25];
    g[28] = g[27] & p[28] | g[28];
    p[28] = p[28] & p[27];
    g[30] = g[29] & p[30] | g[30];
    p[30] = p[30] & p[29];
    g[32] = g[31] & p[32] | g[32];
    p[32] = p[32] & p[31];
    g[34] = g[33] & p[34] | g[34];
    p[34] = p[34] & p[33];
    g[36] = g[35] & p[36] | g[36];
    p[36] = p[36] & p[35];
    g[38] = g[37] & p[38] | g[38];
    p[38] = p[38] & p[37];
    g[40] = g[39] & p[40] | g[40];
    p[40] = p[40] & p[39];
    g[42] = g[41] & p[42] | g[42];
    p[42] = p[42] & p[41];
    g[44] = g[43] & p[44] | g[44];
    p[44] = p[44] & p[43];
    g[46] = g[45] & p[46] | g[46];
    p[46] = p[46] & p[45];
    g[48] = g[47] & p[48] | g[48];
    p[48] = p[48] & p[47];
    g[50] = g[49] & p[50] | g[50];
    p[50] = p[50] & p[49];
    g[52] = g[51] & p[52] | g[52];
    p[52] = p[52] & p[51];
    g[54] = g[53] & p[54] | g[54];
    p[54] = p[54] & p[53];
    g[56] = g[55] & p[56] | g[56];
    p[56] = p[56] & p[55];
    g[58] = g[57] & p[58] | g[58];
    p[58] = p[58] & p[57];
    g[60] = g[59] & p[60] | g[60];
    p[60] = p[60] & p[59];
    g[62] = g[61] & p[62] | g[62];
    p[62] = p[62] & p[61];
    // compute final sum digits
    s[0] = s[0] % 256;
    s[1] = (s[1]+(g[0]?1:0)) % 256;
    s[2] = (s[2]+(g[1]?1:0)) % 256;
    s[3] = (s[3]+(g[2]?1:0)) % 256;
    s[4] = (s[4]+(g[3]?1:0)) % 256;
    s[5] = (s[5]+(g[4]?1:0)) % 256;
    s[6] = (s[6]+(g[5]?1:0)) % 256;
    s[7] = (s[7]+(g[6]?1:0)) % 256;
    s[8] = (s[8]+(g[7]?1:0)) % 256;
    s[9] = (s[9]+(g[8]?1:0)) % 256;
    s[10] = (s[10]+(g[9]?1:0)) % 256;
    s[11] = (s[11]+(g[10]?1:0)) % 256;
    s[12] = (s[12]+(g[11]?1:0)) % 256;
    s[13] = (s[13]+(g[12]?1:0)) % 256;
    s[14] = (s[14]+(g[13]?1:0)) % 256;
    s[15] = (s[15]+(g[14]?1:0)) % 256;
    s[16] = (s[16]+(g[15]?1:0)) % 256;
    s[17] = (s[17]+(g[16]?1:0)) % 256;
    s[18] = (s[18]+(g[17]?1:0)) % 256;
    s[19] = (s[19]+(g[18]?1:0)) % 256;
    s[20] = (s[20]+(g[19]?1:0)) % 256;
    s[21] = (s[21]+(g[20]?1:0)) % 256;
    s[22] = (s[22]+(g[21]?1:0)) % 256;
    s[23] = (s[23]+(g[22]?1:0)) % 256;
    s[24] = (s[24]+(g[23]?1:0)) % 256;
    s[25] = (s[25]+(g[24]?1:0)) % 256;
    s[26] = (s[26]+(g[25]?1:0)) % 256;
    s[27] = (s[27]+(g[26]?1:0)) % 256;
    s[28] = (s[28]+(g[27]?1:0)) % 256;
    s[29] = (s[29]+(g[28]?1:0)) % 256;
    s[30] = (s[30]+(g[29]?1:0)) % 256;
    s[31] = (s[31]+(g[30]?1:0)) % 256;
    s[32] = (s[32]+(g[31]?1:0)) % 256;
    s[33] = (s[33]+(g[32]?1:0)) % 256;
    s[34] = (s[34]+(g[33]?1:0)) % 256;
    s[35] = (s[35]+(g[34]?1:0)) % 256;
    s[36] = (s[36]+(g[35]?1:0)) % 256;
    s[37] = (s[37]+(g[36]?1:0)) % 256;
    s[38] = (s[38]+(g[37]?1:0)) % 256;
    s[39] = (s[39]+(g[38]?1:0)) % 256;
    s[40] = (s[40]+(g[39]?1:0)) % 256;
    s[41] = (s[41]+(g[40]?1:0)) % 256;
    s[42] = (s[42]+(g[41]?1:0)) % 256;
    s[43] = (s[43]+(g[42]?1:0)) % 256;
    s[44] = (s[44]+(g[43]?1:0)) % 256;
    s[45] = (s[45]+(g[44]?1:0)) % 256;
    s[46] = (s[46]+(g[45]?1:0)) % 256;
    s[47] = (s[47]+(g[46]?1:0)) % 256;
    s[48] = (s[48]+(g[47]?1:0)) % 256;
    s[49] = (s[49]+(g[48]?1:0)) % 256;
    s[50] = (s[50]+(g[49]?1:0)) % 256;
    s[51] = (s[51]+(g[50]?1:0)) % 256;
    s[52] = (s[52]+(g[51]?1:0)) % 256;
    s[53] = (s[53]+(g[52]?1:0)) % 256;
    s[54] = (s[54]+(g[53]?1:0)) % 256;
    s[55] = (s[55]+(g[54]?1:0)) % 256;
    s[56] = (s[56]+(g[55]?1:0)) % 256;
    s[57] = (s[57]+(g[56]?1:0)) % 256;
    s[58] = (s[58]+(g[57]?1:0)) % 256;
    s[59] = (s[59]+(g[58]?1:0)) % 256;
    s[60] = (s[60]+(g[59]?1:0)) % 256;
    s[61] = (s[61]+(g[60]?1:0)) % 256;
    s[62] = (s[62]+(g[61]?1:0)) % 256;
    s[63] = (s[63]+(g[62]?1:0)) % 256;
    s[64] = (g[63]?1:0);
}