Tejas/src/simulator/pipeline/outoforder/IWEntry.java

351 lines
9.2 KiB
Java
Executable File

package pipeline.outoforder;
import pipeline.FunctionalUnitType;
import pipeline.OpTypeToFUTypeMapping;
import config.SimulationConfig;
import generic.Core;
import generic.ExecCompleteEvent;
import generic.GlobalClock;
import generic.Instruction;
import generic.OperationType;
import generic.RequestType;
import memorysystem.AddressCarryingEvent;
import memorysystem.Cache;
/**
* represents an entry in the instruction window
*/
public class IWEntry {
Core core;
OutOrderExecutionEngine execEngine;
InstructionWindow instructionWindow;
Instruction instruction;
ReorderBufferEntry associatedROBEntry;
OperationType opType;
boolean isValid;
int pos;
public IWEntry(Core core, int pos,
OutOrderExecutionEngine execEngine, InstructionWindow instructionWindow)
{
this.core = core;
this.execEngine = execEngine;
this.instructionWindow = instructionWindow;
this.pos = pos;
isValid = false;
}
public boolean issueInstruction()
{
if(associatedROBEntry.isRenameDone() == false ||
associatedROBEntry.getExecuted() == true)
{
misc.Error.showErrorAndExit("cannot issue this instruction");
}
if(associatedROBEntry.getIssued() == true)
{
misc.Error.showErrorAndExit("already issued!");
}
if(associatedROBEntry.isOperand1Available() && associatedROBEntry.isOperand2Available())
{
boolean issued = issueOthers();
if(issued == true &&
(opType == OperationType.load || opType == OperationType.store))
{
issueLoadStore();
}
return issued;
}
return false;
}
void issueLoadStore()
{
//assertions
if(associatedROBEntry.getLsqEntry().isValid() == true)
{
misc.Error.showErrorAndExit("attempting to issue a load/store.. address is already valid");
}
if(associatedROBEntry.getLsqEntry().isForwarded() == true)
{
misc.Error.showErrorAndExit("attempting to issue a load/store.. value forwarded is already valid");
}
associatedROBEntry.setIssued(true);
if(opType == OperationType.store)
{
//stores are issued at commit stage
associatedROBEntry.setExecuted(true);
associatedROBEntry.setWriteBackDone1(true);
associatedROBEntry.setWriteBackDone2(true);
}
//remove IW entry
instructionWindow.removeFromWindow(this);
//tell LSQ that address is available
execEngine.getCoreMemorySystem().issueRequestToLSQ(
null,
associatedROBEntry);
if(SimulationConfig.debugMode)
{
System.out.println("issue : " + GlobalClock.getCurrentTime()/core.getStepSize() + " : " + associatedROBEntry.getInstruction());
}
}
boolean issueOthers()
{
FunctionalUnitType[] FUType = OpTypeToFUTypeMapping.getFUType(opType);
if(FUType[0] == FunctionalUnitType.inValid)
{
associatedROBEntry.setIssued(true);
associatedROBEntry.setFUInstance(0);
//remove IW entry
instructionWindow.removeFromWindow(this);
return true;
}
long FURequest = 0; //will be <= 0 if an FU was obtained
//will be > 0 otherwise, indicating how long before
// an FU of the type will be available
FunctionalUnitType assignedFUType = FunctionalUnitType.no_of_types;
for(int i = 0; i < FUType.length; i++)
{
FURequest = execEngine.getExecutionCore().requestFU(FUType[i], 0);
if(FURequest <= 0)
{
assignedFUType = FUType[i];
break;
}
}
if(FURequest <= 0)
{
if(opType != OperationType.load
&& opType != OperationType.store
&& opType != OperationType.read_prefetch
&& opType != OperationType.write_prefetch)
{
associatedROBEntry.setIssued(true);
associatedROBEntry.setFUInstance((int) ((-1) * FURequest));
//remove IW entry
instructionWindow.removeFromWindow(this);
core.getEventQueue().addEvent(
new BroadCastEvent(
GlobalClock.getCurrentTime() + (execEngine.getExecutionCore().getFULatency(
assignedFUType, 0) - 1) * core.getStepSize(),
null,
execEngine.getExecuter(),
RequestType.BROADCAST,
associatedROBEntry));
core.getEventQueue().addEvent(
new ExecCompleteEvent(
null,
GlobalClock.getCurrentTime() + execEngine.getExecutionCore().getFULatency(
assignedFUType, 0) * core.getStepSize(),
null,
execEngine.getExecuter(),
RequestType.EXEC_COMPLETE,
associatedROBEntry));
}
else if(opType == OperationType.read_prefetch)
{
Cache cacheToPrefetchTo = execEngine.getCoreMemorySystem().getL1Cache();
for(int i = 2; i <= associatedROBEntry.getInstruction().getSourceOperand2().getValue(); i++)
{
cacheToPrefetchTo = cacheToPrefetchTo.nextLevel;
}
long addr = associatedROBEntry.getInstruction().getSourceOperand1MemValue();
if(cacheToPrefetchTo.isBusy(addr))
return false;
AddressCarryingEvent addressEvent = new AddressCarryingEvent(execEngine.getCore().getEventQueue(),
0, execEngine.getCoreMemorySystem(), cacheToPrefetchTo, RequestType.Cache_Read, addr);
cacheToPrefetchTo.getPort().put(addressEvent);
associatedROBEntry.setIssued(true);
associatedROBEntry.setExecuted(true);
associatedROBEntry.setWriteBackDone1(true);
associatedROBEntry.setWriteBackDone2(true);
associatedROBEntry.setFUInstance((int) ((-1) * FURequest));
//remove IW entry
instructionWindow.removeFromWindow(this);
((OutOrderCoreMemorySystem)execEngine.getCoreMemorySystem()).getLsqueue().NoOfSoftwareReadPrefetch++;
return true;
}
else if(opType == OperationType.write_prefetch)
{
Cache cacheToPrefetchTo = execEngine.getCoreMemorySystem().getL1Cache();
long addr = associatedROBEntry.getInstruction().getSourceOperand1MemValue();
if(cacheToPrefetchTo.isBusy(addr))
return false;
AddressCarryingEvent addressEvent = new AddressCarryingEvent(execEngine.getCore().getEventQueue(),
0, execEngine.getCoreMemorySystem(), cacheToPrefetchTo, RequestType.Cache_Write, addr);
/*
* setting as cache write is an approximation
* this would dirty the cache line, and that should actually not happen
*/
cacheToPrefetchTo.getPort().put(addressEvent);
associatedROBEntry.setIssued(true);
associatedROBEntry.setExecuted(true);
associatedROBEntry.setWriteBackDone1(true);
associatedROBEntry.setWriteBackDone2(true);
associatedROBEntry.setFUInstance((int) ((-1) * FURequest));
//remove IW entry
instructionWindow.removeFromWindow(this);
((OutOrderCoreMemorySystem)execEngine.getCoreMemorySystem()).getLsqueue().NoOfSoftwareWritePrefetch++;
return true;
}
/*
int functionality = 6;
FunctionalUnitType assignedFUType = FunctionalUnitType.no_of_types;
for(int i = 0; i < FUType.length; i++)
{
if(FUType[i].compareTo(FunctionalUnitType.FMA) != 0)
{
functionality = 0;
}
else
{
switch(opType)
{
case floatALU: {
functionality = 0;
break;
}
case floatMul: {
functionality = 1;
break;
}
case floatVectorALU: {
functionality = 2;
break;
}
case floatVectorMul: {
functionality = 3;
break;
}
case FMA: {
functionality = 4;
break;
}
case vectorFMA: {
functionality = 5;
break;
}
default : {
misc.Error.showErrorAndExit("requesting unsupported operation " + opType + " from an FMA");
}
}
}
FURequest = execEngine.getExecutionCore().requestFU(FUType[i], functionality);
if(FURequest <= 0)
{
assignedFUType = FUType[i];
break;
}
}
if(FURequest <= 0)
{
if(opType != OperationType.load && opType != OperationType.store)
{
associatedROBEntry.setIssued(true);
associatedROBEntry.setFUInstance((int) ((-1) * FURequest));
//remove IW entry
instructionWindow.removeFromWindow(this);
core.getEventQueue().addEvent(
new BroadCastEvent(
GlobalClock.getCurrentTime() + (execEngine.getExecutionCore().getFULatency(
assignedFUType, functionality) - 1) * core.getStepSize(),
null,
execEngine.getExecuter(),
RequestType.BROADCAST,
associatedROBEntry));
core.getEventQueue().addEvent(
new ExecCompleteEvent(
null,
GlobalClock.getCurrentTime() + execEngine.getExecutionCore().getFULatency(
assignedFUType, functionality) * core.getStepSize(),
null,
execEngine.getExecuter(),
RequestType.EXEC_COMPLETE,
associatedROBEntry));
}
*/
if(SimulationConfig.debugMode)
{
System.out.println("issue : " + GlobalClock.getCurrentTime()/core.getStepSize() + " : " + associatedROBEntry.getInstruction());
}
return true;
}
return false;
}
public ReorderBufferEntry getAssociatedROBEntry() {
return associatedROBEntry;
}
public void setAssociatedROBEntry(ReorderBufferEntry associatedROBEntry) {
this.associatedROBEntry = associatedROBEntry;
}
public boolean isValid() {
return isValid;
}
public void setValid(boolean isValid) {
this.isValid = isValid;
}
public Instruction getInstruction() {
return instruction;
}
public void setInstruction(Instruction instruction) {
this.instruction = instruction;
opType = instruction.getOperationType();
}
}