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


[4]nat x;
[4]nat y;
[5]nat s;

thread RadixBAddCarryLookahead4 {
    bool g0,g1,g2,g3;
    bool p0,p1,p2,p3;
    nat x0,x1,x2,x3;
    nat y0,y1,y2,y3;
    nat s0,s1,s2,s3,s4;
    x0 = x[0];
    x1 = x[1];
    x2 = x[2];
    x3 = x[3];
    y0 = y[0];
    y1 = y[1];
    y2 = y[2];
    y3 = y[3];
    // preliminary sum digits
    s0 = x0 + y0;
    s1 = x1 + y1;
    s2 = x2 + y2;
    s3 = x3 + y3;
    // initial generate conditions
    g0 = s0>255;
    g1 = s1>255;
    g2 = s2>255;
    g3 = s3>255;
    // initial propagate conditions
    p0 = s0==255;
    p1 = s1==255;
    p2 = s2==255;
    p3 = s3==255;
    // carry propagation prefix tree
    // up-level 1
    g1 = g0 & p1 | g1;
    p1 = p1 & p0;
    g3 = g2 & p3 | g3;
    p3 = p3 & p2;
    // up-level 2
    g3 = g1 & p3 | g3;
    p3 = p3 & p1;
    // down-level 4
    // down-level 5
    g2 = g1 & p2 | g2;
    p2 = p2 & p1;
    // compute final sum digits
    s[0] = s0 % 256;
    s[1] = (s1+(g0?1:0)) % 256;
    s[2] = (s2+(g1?1:0)) % 256;
    s[3] = (s3+(g2?1:0)) % 256;
    s[4] = (g3?1:0);
}