// ************************************************************************** //
//                                                                            //
//    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                                             //
//                                                                            //
// ************************************************************************** //
// This module approximates pi = 3.1415... with N decimal digits. To this end,//
// the Machin's equation pi/4 = 4*arctan(1/5) - arctan(1/239) is used, where  //
// arctan(x) = x − (x^3)/3 + (x^5)/5 − (x^7)/7 + (x^9)/9 − (x^11)/11 + ...    //
// There are faster iterations to compute pi like the Bailey-Borwein-Plouffe  //
// iteration, but we only intend to test the multiprecision arithmetic of the //
// compiler and simulator, so we are more interested in simple iterations than//
// in high speed iterations. An alternative would be Vega's iteration that is //
// pi/4 = 5*arctan(1/7) + 2*arctan(3/79).                                     //
// All computations are made on type nat using a fixpoint arithmetic where the//
// decimal point is moved N decimal digits to the left.                       //
// ************************************************************************** //

macro N = 400;
macro mult(x,y) = (x*y)/exp(10,N);

module Pi(nat pi,event !rdy) {
    nat xp1,xp2,x1,x2,i;
    bool sign;
    xp1 = exp(10,N) / 5;    // means 1/5
    xp2 = exp(10,N) / 239;  // means 1/239
    x1 = mult(xp1,xp1);     // means (1/5)^2
    x2 = mult(xp2,xp2);     // means (1/239)^2
    i = 1;
    sign = true;
    do {
        next(xp1) = mult(xp1,x1);
        next(xp2) = mult(xp2,x2);
        next(i) = i+2;
        next(sign) = not sign;
        if(sign) 
            next(pi) = pi + (4*xp1 - xp2)/i;
        else
            next(pi) = pi - (4*xp1 - xp2)/i;
        pause;
    } while(xp1>0);
    next(pi) = pi * 4;
    pause;
    emit(rdy);
}
drivenby {
    await(rdy);
}