// the module CacheBus implements communication between caches // if more than one cache demands data from other caches, they can not do it at the same time. // the CacheBus does the arbitration for the caches, so that only one of them gets the bus and // can broadcast requirements to other caches. the rest requesting caches have to try again at // the next cycle. // // the design reflects the fact that communication matters in a multi-processor architecture. // with the original design where only one bus is available for all caches and the main memory, // the competition was realy intensive. To use an extra bus for inter-cache communication relaxes // the communication. A more costly design would be using more complex connections among caches. macro NumOfProcs = 2; // number of processors, or caches module CacheBus(event [NumProcs]bool ?reqBusCache, !ackBusCache) { nat{NumProcs} token; // by default the first CPU has the token, // i.e. the right to access the bus token = 0; loop { for(i=0..NumProcs-1) { ackBusCache[(token+i)%NumProcs] = reqBusCache[(token+i)%NumProcs] & (i==0 ? true : forall(j=0..i-1) !ackBusCache[(token+j)%NumProcs]); } // pass token around next(token) = (token+1) % NumProcs; pause; } }