/* * Model for 4x4 ASPIN. The model can be extended for lager NoCs by declaring routers in main part (last section of the code). *In the model only one packet is sent from router R00 to router R23. More packets can be scheduled to sent from a source to destination as like in "Router" mesage server. */ reactiveclass Manager(10){ knownrebecs{ Router r00; Router r10; Router r20; Router r30; Router r01; Router r11; Router r21; Router r31; Router r02; Router r12; Router r22; Router r32; Router r03; Router r13; Router r23; Router r33; } statevars{ } Manager(){ } msgsrv reset(){ //each source and destination routeeer should be initialized here. r01.reStart() after(700); //source } } reactiveclass Router(10) { knownrebecs { Manager manager; Router N; // : 0 Router E; // : 1 Router S; // : 2 Router W; // : 3 } statevars { int bufSize; int maxTime; // To check if a packet is recieved by the time maxTime int recieved; byte[4] bufNum; //for each of four sides boolean[4] full; boolean[4] enable; boolean [4] outMutex; byte Xid; byte Yid; } Router(byte X, byte Y){ Xid = X; Yid = Y; bufSize = 2; maxTime = 250 ; recieved = 0; for(int i=0;i<4;i++){ enable[i] = true; outMutex[i] = true; bufNum[i] = 0; full[i] = false; } //packet generation if(X == 0 && Y == 0){ self.reqSend(2,3,1,5) after(10); //sending a packet } if(X == 0 && Y == 1){ // permamnet, don't change. self.reStart() after(700); } if(X == 2 && Y == 3){ // in destination router. not necessary for all packets. just to check when the packet is recieved self.checkRecieved()after(maxTime); } } msgsrv reqSend(byte Xtarget, byte Ytarget, int directionS, int packId){ if (enable[directionS] == true){ boolean sent = false; if(Xtarget > Xid){ // Routing Algorithm XY: first move through horisental channels if(outMutex[1] == true){ E.give_Ack(Xtarget, Ytarget,directionS,3,5, packId) after(26); outMutex[1] = false; enable[directionS] = false; sent = true; }else self.reqSend(Xtarget, Ytarget,directionS, packId) after(1); } else if(Xtarget < Xid){ if(outMutex[3] == true){ W.give_Ack(Xtarget, Ytarget,directionS,1,5, packId ) after(26); outMutex[3] = false; enable[directionS] = false; sent = true; } else self.reqSend(Xtarget, Ytarget,directionS, packId) after(1); } else if(Ytarget > Yid){ if(outMutex[2] == true){ S.give_Ack(Xtarget, Ytarget,directionS,0,5, packId ) after(26); outMutex [2] = false; enable[directionS] = false; sent = true; }else self.reqSend(Xtarget, Ytarget,directionS, packId) after(1); } else if(Ytarget < Yid){ if(outMutex[0] == true){ N.give_Ack(Xtarget, Ytarget,directionS,2,5 , packId) after(26); outMutex[0] = false; enable[directionS] = false; sent = true; }else self.reqSend(Xtarget, Ytarget,directionS,packId) after(1); } if(sent == true){ bufNum[directionS] = (byte)bufNum[directionS] + 1; if (bufNum[directionS] == bufSize) full[directionS] = true; //update the value of "full". } } else self.reqSend(Xtarget, Ytarget,directionS,packId) after(1); } msgsrv get_Ack(int directionS){ enable[directionS] = true; bufNum[directionS] = (byte)bufNum[directionS] - 1; full[directionS] = false; if (sender == N) { outMutex[0] = true; } else if (sender == E){ outMutex[1] = true; } else if (sender == S){ outMutex[2] = true; } else if (sender == W){ outMutex[3] = true; } } msgsrv give_Ack(byte Xtarget, byte Ytarget,int directionS, int directionD,int msgSender, int packId){ int MSGSender; if(sender == N) MSGSender = 0; else if (sender == E) MSGSender = 1; else if (sender == S) MSGSender = 2; else if (sender == W) MSGSender = 3; else {MSGSender = msgSender; } if(!(Xtarget == Xid && Ytarget == Yid)){ if (full[directionD]) //buffer is full, the packet should wait. self.give_Ack(Xtarget, Ytarget,directionS,directionD,MSGSender, packId)after(2)deadline(3); //waiting via recalling give_ack after 2 time units. else{ self.reqSend(Xtarget, Ytarget,directionD, packId); if(MSGSender == 0) N.get_Ack(directionS); else if(MSGSender == 1) E.get_Ack(directionS); else if(MSGSender == 2) S.get_Ack(directionS); else if(MSGSender == 3) W.get_Ack(directionS); } } else if((Xtarget == Xid && Ytarget == Yid)){ //reach target recieved = recieved + 1; if(MSGSender == 0) N.get_Ack(directionS); else if(MSGSender == 1) E.get_Ack(directionS); else if(MSGSender == 2) S.get_Ack(directionS); else if(MSGSender == 3) W.get_Ack(directionS); } } msgsrv reStart(){ manager.reset(); } msgsrv deadlineMiss(){ delay(5); } msgsrv checkPoint(){ // causes to hult self.deadlineMiss() after(1)deadline(3); self.deadlineMiss() after(1)deadline(3); } msgsrv checkRecieved(){ // Halt if recieved is 0, by calling checkpoint.(checkpoint method allways cause program to hult). if (recieved == 0){ self.checkPoint(); } } } main { Manager m(r00,r10,r20,r30,r01,r11,r21,r31,r02,r12,r22,r32,r03,r13,r23,r33):(); Router r00(m,r03,r10,r01,r30):(0,0); Router r10(m,r13,r20,r11,r00):(1,0); Router r20(m,r23,r30,r21,r10):(2,0); Router r30(m,r33,r00,r31,r20):(3,0); Router r01(m,r00,r11,r02,r31):(0,1); Router r11(m,r10,r21,r12,r01):(1,1); Router r21(m,r20,r31,r22,r11):(2,1); Router r31(m,r30,r01,r32,r21):(3,1); Router r02(m,r01,r12,r03,r32):(0,2); Router r12(m,r11,r22,r13,r02):(1,2); Router r22(m,r21,r32,r23,r12):(2,2); Router r32(m,r31,r02,r33,r22):(3,2); Router r03(m,r02,r13,r00,r33):(0,3); Router r13(m,r12,r23,r10,r03):(1,3); Router r23(m,r22,r33,r20,r13):(2,3); Router r33(m,r32,r03,r30,r23):(3,3); }