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

package ComputerArchitecture.AsynchronousCircuits.AsyncArbiter;

// -------------------------------------------------------
// In [DiCL86], an ME-element (mutual exclusion element)
// is used which behaves as follows:
//  (1) The two outputs are never both high.
//  (2) When both inputs are low, so are the outputs.
//  (3) When only one input is high, the corresponding
//      output will eventually go high.
//  (4) When an input is high and the corresponding
//      output is high, then the output remains high
//      until the input goes low.
//  (5) When both inputs are high and the outputs are
//      both low, then the ME element has the nondet.
//      choice to raise one of them.
// -------------------------------------------------------


module ME_Element(bool ?delay,?in1,?in2,out1,out2) {
    out1 = false;
    out2 = false;
    loop {
        if(!delay) {
            if(!in1 or !in2) {
                next(out1) = in1;
                next(out2) = in2;
            } else if(in1&in2&!out1&!out2) {
                choose next(out1) = true;
                else   next(out2) = true;
                nothing;
            } else
                nothing;
        }
        pause;
    }
}