351 lines
9.2 KiB
Java
Executable File
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();
|
|
}
|
|
|
|
} |