def __init__(self, id: int, cacheSz: int, blockSz: int, a: int, bus: Bus, processor: Processor): """ Constructor for the class ... Parameters ---------- id: int id of the processor cacheSz: int size of the cache blockSz: int size of the block a: int Associativity bus: Bus bus object processor: Processor processor object """ self.id = id self.num_entries = int(cacheSz / blockSz) self.entries = [CacheEntry() for i in range(self.num_entries)] self.cacheSz = cacheSz self.blockSz = blockSz self.num_sets = self.num_entries // a self.num_entries_per_set = self.num_entries // self.num_sets self.a = a self.bus = bus self.processor = processor self.currentRequestAddr = None self.currentRequestType = None self.currentRequestId = None # Stats related fields self.cacheAccesses = 0 self.cacheHits = 0 self.cacheMisses = 0 self.numMemBusTransaction = 0 self.numCacheBusTransaction = 0
def snoopBus(self, clock: int): """Snoops the bus and updates accordingly ..... Parameters ---------- clock: int the clock tick number Returns ------- str Action performed by cache on Snooping """ if self.bus.currentData != None: request = deepcopy(self.bus.currentData) print(request.addr, request.coreId, request.msg, self.id, request.response) # entry_id = self.containsEntry(request.addr) if request.response or request.msg == 'Flush': # This is a response to some data request if request.addr != None and request.id == self.currentRequestId and request.coreId == self.id and request.addr == self.currentRequestAddr: entry_id = self.containsEntry(request.addr) if request.responseTime == 0: self.numCacheBusTransaction += 1 if request.responseTime > 0 or request.msg == 'Flush': self.numMemBusTransaction += 1 if request.response: self.bus.currentData = None if entry_id != -1: if self.currentRequestType != 'READ': self.entries[entry_id].state == 'M' else: # print(f"Setting the state as E or s for index {entry_id}") self.entries[ entry_id].state = 'E' if request.responseTime > 0 else 'S' self.entries[ entry_id].access = clock # Relying on python's mutable objects else: newEntry = CacheEntry() if request.entry != None: newEntry = request.entry else: newEntry.access = clock newEntry.valid, newEntry.tag, newEntry.index = True, ( request.addr // self.blockSz ) // self.num_sets, (request.addr // self.blockSz) % self.num_sets if self.currentRequestType != 'READ': # print("M must be added") newEntry.state = 'M' else: # print("E or S must be added") newEntry.state = 'E' if request.responseTime > 0 else 'S' # print("Adding a new ENTRY!!!!!!!!!!!!!!!!!!!!!!") self.addEntry(newEntry) return 'RECV_DATA' else: entry_id = self.containsEntry(request.addr) if entry_id != -1: entry = self.entries[entry_id] # State must be M or S if request.msg == 'BusRd': if entry.state == 'S' or entry.state == 'E': entry.access = clock entry.state = 'S' request.response = True self.bus.reply = request self.bus.reply.entry = entry self.entries[entry_id] = entry elif entry.state == 'M': # writeBackRequest = Request(request.addr, 'Flush', self.id) self.bus.reply = request self.bus.reply.msg = 'Flush' self.bus.reply.responseTime = 0 entry.access = clock entry.state = 'S' else: print("snoopBus: Incorrect state while snooping") exit() print( f'Cache {self.id} performed bus request for msg {request.msg}' ) return 'BusRd' elif request.msg == 'BusRdX' and request.coreId != self.id: # State is either 'M' or 'S or 'E' entry.valid = False # print(self.bus.currentData.response) request.response = True # print(self.bus.currentData.response) self.bus.reply = request self.entries[entry_id] = entry print( f'Cache {self.id} performed bus request for msg {request.msg}' ) return 'BusRdX' elif request.msg in ['BusRdX' ] and request.coreId == self.id: pass elif request.msg == 'BusUpgr' and request.coreId != self.id: entry.valid = False request.response = True self.bus.reply = request self.entries[entry_id] = entry print( f'Cache {self.id} performed bus request for msg {request.msg}' ) return 'BusUpgr' elif request.msg == 'BusUpgr' and request.coreId == self.id: # print(self.bus.currentData.response) request.response = True # print(self.bus.currentData.response) self.bus.reply = request return 'BusUpgr' else: print( f'Wrong msg {request.msg}, {request.coreId} detected in the bus while snooping by cache {self.id}' ) return 'UNUSED'