<commit_before>package memorysystem;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import memorysystem.Cache.CacheType;
import memorysystem.Cache.CoherenceType;

import pipeline.inorder.FetchUnitIn;
import pipeline.inorder.MemUnitIn;
import pipeline.statistical.DelayGenerator;
import power.Counters;

import generic.Event;
import generic.EventQueue;
import generic.ExecCompleteEvent;
import generic.GlobalClock;
import generic.OMREntry;
import generic.RequestType;
import generic.SimulationElement;
import config.CacheConfig;

public class InstructionCache extends Cache
{	
	public InstructionCache(CacheConfig cacheParameters, CoreMemorySystem containingMemSys) {
		super(cacheParameters, containingMemSys);
	}
	
	protected void handleAccess(EventQueue eventQ, Event event)
	{
		SimulationElement requestingElement = event.getRequestingElement();
		RequestType requestType = event.getRequestType();
		long address;
		
//		if (this.levelFromTop == CacheType.L1 && !MemorySystem.bypassLSQ)
//			address = ((LSQEntryContainingEvent)(event)).getLsqEntry().getAddr();
//		else
			address = ((AddressCarryingEvent)(event)).getAddress();
		
		//Process the access
		CacheLine cl = this.processRequest(requestType, address);

//		Counters.icache_access[containingMemSys.getCore().getCore_number()]++; //TODO check for correctness!
		this.containingMemSys.getCore().powerCounters.incrementIcacheAccess(1); //TODO check for correctness!
		//IF HIT
		if (cl != null)
		{
			OMREntry omrEntry = null;
			if(requestingElement.getClass() == FetchUnitIn.class)
			{
				 omrEntry = ((FetchUnitIn)requestingElement).getMissStatusHoldingRegister().remove(address);
			}
			while(omrEntry !=null && omrEntry.outStandingEvents.size()>0)
			//Schedule the requesting element to receive the block TODO (for LSQ)
			{
				
				Event tempEvent = omrEntry.outStandingEvents.remove(0);
				if (requestType == RequestType.Cache_Read)
				{
					//Just return the read block
						requestingElement.getPort().put(
								tempEvent.update(
										eventQ,
										requestingElement.getLatencyDelay(),
										this,
										requestingElement,
										RequestType.Mem_Response));
				}
				
				else if (requestType == RequestType.Cache_Write)
				{
					//Write the data to the cache block (Do Nothing)	
					System.out.println(" iCache got 'write' operation : Not possible");
					System.exit(1);
				}
			}
		}
		
		//IF MISS
		else
		{			
			//Add the request to the outstanding request buffer
			int alreadyRequested = this.addOutstandingRequest(event, address);
			
			if (alreadyRequested==0)
			{		
				if(requestingElement.getClass() == FetchUnitIn.class)
				{
					((FetchUnitIn)requestingElement).getMissStatusHoldingRegister().remove(address);
				}
				// access the next level
				if (this.isLastLevel)
				{
					MemorySystem.mainMemory.getPort().put(
							new AddressCarryingEvent(
									eventQ,
									MemorySystem.mainMemory.getLatencyDelay(),
									this, 
									MemorySystem.mainMemory,
									RequestType.Main_Mem_Read,
									address,
									((AddressCarryingEvent)event).coreId));
					return;
				}
				else
				{
					AddressCarryingEvent addressEvent = new AddressCarryingEvent(eventQ,
																				this.nextLevel.getLatencyDelay(),
																				this, 
																				this.nextLevel,
																				RequestType.Cache_Read_from_iCache, 
																				address,
																				((AddressCarryingEvent)event).coreId);
					missStatusHoldingRegister.get((address >> blockSizeBits)).eventToForward = addressEvent;
					this.nextLevel.getPort().put(addressEvent);
					return;
				}
				
			}
			else if(alreadyRequested == 1)
			{
				if(requestingElement.getClass() == FetchUnitIn.class)
				{
					((FetchUnitIn)requestingElement).getMissStatusHoldingRegister().remove(address);
				}
			}
			else if (alreadyRequested ==2)
			{
				if(!this.connectedMSHR.contains(((FetchUnitIn)requestingElement).getMissStatusHoldingRegister()))
					this.connectedMSHR.add(((FetchUnitIn)requestingElement).getMissStatusHoldingRegister());
			}
		}
	}
	
	@Override
	protected void handleMemResponse(EventQueue eventQ, Event event)
	{
		long addr = ((AddressCarryingEvent)(event)).getAddress();
		
		CacheLine evictedLine = this.fill(addr, MESI.EXCLUSIVE);
		if (evictedLine != null)
		{
			if (this.isLastLevel)
				MemorySystem.mainMemory.getPort().put(
						new AddressCarryingEvent(
								eventQ,
								MemorySystem.mainMemory.getLatencyDelay(),
								this, 
								MemorySystem.mainMemory,
								RequestType.Main_Mem_Write,
								evictedLine.getTag() << this.blockSizeBits,
								((AddressCarryingEvent)event).coreId));
			else
				this.nextLevel.getPort().put(
						new AddressCarryingEvent(
								eventQ,
								this.nextLevel.getLatencyDelay(),
								this,
								this.nextLevel,
								RequestType.Cache_Write,<commit_msg>Fixed size MSHR logic added for instruction cache requests in out of order<commit_after>package memorysystem;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import memorysystem.Cache.CacheType;
import memorysystem.Cache.CoherenceType;

import pipeline.inorder.FetchUnitIn;
import pipeline.inorder.MemUnitIn;
import pipeline.outoforder.FetchLogic;
import pipeline.statistical.DelayGenerator;
import power.Counters;

import generic.Event;
import generic.EventQueue;
import generic.ExecCompleteEvent;
import generic.GlobalClock;
import generic.OMREntry;
import generic.RequestType;
import generic.SimulationElement;
import config.CacheConfig;

public class InstructionCache extends Cache
{	
	public InstructionCache(CacheConfig cacheParameters, CoreMemorySystem containingMemSys) {
		super(cacheParameters, containingMemSys);
	}
	
	protected void handleAccess(EventQueue eventQ, Event event)
	{
		SimulationElement requestingElement = event.getRequestingElement();
		RequestType requestType = event.getRequestType();
		long address;
		
//		if (this.levelFromTop == CacheType.L1 && !MemorySystem.bypassLSQ)
//			address = ((LSQEntryContainingEvent)(event)).getLsqEntry().getAddr();
//		else
			address = ((AddressCarryingEvent)(event)).getAddress();
		
		//Process the access
		CacheLine cl = this.processRequest(requestType, address);

//		Counters.icache_access[containingMemSys.getCore().getCore_number()]++; //TODO check for correctness!
		this.containingMemSys.getCore().powerCounters.incrementIcacheAccess(1); //TODO check for correctness!
		//IF HIT
		if (cl != null)
		{
			OMREntry omrEntry = null;
			if(requestingElement.getClass() == FetchUnitIn.class)
			{
				 omrEntry = ((FetchUnitIn)requestingElement).getMissStatusHoldingRegister().remove(address);
			}
			else if(requestingElement.getClass() == FetchLogic.class)
			{
				 omrEntry = ((FetchLogic)requestingElement).getMissStatusHoldingRegister().remove(address);
			}
			while(omrEntry !=null && omrEntry.outStandingEvents.size()>0)
			//Schedule the requesting element to receive the block TODO (for LSQ)
			{
				
				Event tempEvent = omrEntry.outStandingEvents.remove(0);
				if (requestType == RequestType.Cache_Read)
				{
					//Just return the read block
						requestingElement.getPort().put(
								tempEvent.update(
										eventQ,
										requestingElement.getLatencyDelay(),
										this,
										requestingElement,
										RequestType.Mem_Response));
				}
				
				else if (requestType == RequestType.Cache_Write)
				{
					//Write the data to the cache block (Do Nothing)	
					System.out.println(" iCache got 'write' operation : Not possible");
					System.exit(1);
				}
			}
		}
		
		//IF MISS
		else
		{			
			//Add the request to the outstanding request buffer
			int alreadyRequested = this.addOutstandingRequest(event, address);
			
			if (alreadyRequested==0)
			{		
				if(requestingElement.getClass() == FetchUnitIn.class)
				{
					((FetchUnitIn)requestingElement).getMissStatusHoldingRegister().remove(address);
				}
				else if(requestingElement.getClass() == FetchLogic.class)
				{
					((FetchLogic)requestingElement).getMissStatusHoldingRegister().remove(address);
				}
				// access the next level
				if (this.isLastLevel)
				{
					MemorySystem.mainMemory.getPort().put(
							new AddressCarryingEvent(
									eventQ,
									MemorySystem.mainMemory.getLatencyDelay(),
									this, 
									MemorySystem.mainMemory,
									RequestType.Main_Mem_Read,
									address,
									((AddressCarryingEvent)event).coreId));
					return;
				}
				else
				{
					AddressCarryingEvent addressEvent = new AddressCarryingEvent(eventQ,
																				this.nextLevel.getLatencyDelay(),
																				this, 
																				this.nextLevel,
																				RequestType.Cache_Read_from_iCache, 
																				address,
																				((AddressCarryingEvent)event).coreId);
					missStatusHoldingRegister.get((address >> blockSizeBits)).eventToForward = addressEvent;
					this.nextLevel.getPort().put(addressEvent);
					return;
				}
				
			}
			else if(alreadyRequested == 1)
			{
				if(requestingElement.getClass() == FetchUnitIn.class)
				{
					((FetchUnitIn)requestingElement).getMissStatusHoldingRegister().remove(address);
				}
				else if(requestingElement.getClass() == FetchLogic.class)
				{
					((FetchLogic)requestingElement).getMissStatusHoldingRegister().remove(address);
				}
			}
			else if (alreadyRequested ==2)
			{
				if(requestingElement.getClass() == FetchUnitIn.class){
					if(!this.connectedMSHR.contains(((FetchUnitIn)requestingElement).getMissStatusHoldingRegister()))
					this.connectedMSHR.add(((FetchUnitIn)requestingElement).getMissStatusHoldingRegister());
				}
				else if(requestingElement.getClass() == FetchLogic.class){
					if(!this.connectedMSHR.contains(((FetchLogic)requestingElement).getMissStatusHoldingRegister()))
					this.connectedMSHR.add(((FetchLogic)requestingElement).getMissStatusHoldingRegister());
				}
			}
		}
	}
	
	@Override
	protected void handleMemResponse(EventQueue eventQ, Event event)
	{
		long addr = ((AddressCarryingEvent)(event)).getAddress();
		
		CacheLine evictedLine = this.fill(addr, MESI.EXCLUSIVE);
		if (evictedLine != null)
		{
			if (this.isLastLevel)
				MemorySystem.mainMemory.getPort().put(
						new AddressCarryingEvent(
								eventQ,
								MemorySystem.mainMemory.getLatencyDelay(),
								this, 
								MemorySystem.mainMemory,
								RequestType.Main_Mem_Write,
								evictedLine.getTag() << this.blockSizeBits,
								((AddressCarryingEvent)event).coreId));
			else
				this.nextLevel.getPort().put(
						new AddressCarryingEvent(
								eventQ,
								this.nextLevel.getLatencyDelay(),
								this,
								this.nextLevel,
								RequestType.Cache_Write,
{'fraction_non_alphanumeric': 0.10582157025555863, 'fraction_numerical': 0.0014761509364332502, 'mean_word_length': 3.392220421393841, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6195331', 'n_tokens_mistral': 4081, 'n_tokens_neox': 3130, 'n_words': 551}