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


[8]nat x;
[8]nat y;
[9]nat s;

thread RadixBAddCarryLookahead8 {
    [8]bool g;
    [8]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];
    // 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;
    // 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;
    // 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];
    // 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];
    // up-level 3
    g[7] = g[3] & p[7] | g[7];
    p[7] = p[7] & p[3];
    // down-level 5
    // down-level 6
    g[5] = g[3] & p[5] | g[5];
    p[5] = p[5] & p[3];
    // down-level 7
    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];
    // 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] = (g[7]?1:0);
}