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

                                                                           
macro DataWidth = 8;      // bit-width of registers 
                                                                           
module euclid(bv{16} ?instr,nat pc) {                              
    event nat adrMem;                 // address for memory access         
    event bv{DataWidth} dataMem;      // data for memory access            
    event readMem,writeMem;           // flags for reading/writing         
    event reqMem,ackMem,doneMem;      // signals for memory transaction    
    // single CPU
    cpu: ScalarBehav(instr,pc,adrMem,dataMem,readMem,writeMem,reqMem,ackMem,doneMem);
    ||
    // connected to data memory
    memory: MainMemory(adrMem,dataMem,readMem,writeMem,reqMem,ackMem,doneMem);
}
drivenby euclidDrv {
    [8]bv{16} Prog;
    Prog = [
        0b1000010011111100,  //   0:         movu R1,124     
        0b1000010101010100,  //   1:         movu R2,84      
        0b0000100110100000,  //   2:   loop: movr R3,R2      
        0b0011010100010100,  //   3:         divu R2,R1,R2   
        0b1001110100000001,  //   4:         ovf R2          
        0b0000100010110000,  //   5:         movr R1,R3      
        0b1000110100001100,  //   6:         bnz R2,R0,loop  
        0b0000100000000000   //   7:    end: nop             
    ];
    pause;
    weak abort {
        loop {
            instr = Prog[pc];
            pause;
        }
    } when(pc>=7);
}