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

197 lines
5.4 KiB
Java
Executable File

package pipeline.outoforder;
import java.io.FileWriter;
import java.io.IOException;
import config.EnergyConfig;
import config.SimulationConfig;
import pipeline.outoforder.ReorderBufferEntry;
import generic.Core;
import generic.Event;
import generic.EventQueue;
import generic.GenericCircularQueue;
import generic.GlobalClock;
import generic.Instruction;
import generic.OperationType;
import generic.PortType;
import generic.SimulationElement;
public class DecodeLogic extends SimulationElement {
Core core;
OutOrderExecutionEngine containingExecutionEngine;
GenericCircularQueue<Instruction> fetchBuffer;
GenericCircularQueue<ReorderBufferEntry> decodeBuffer;
int decodeWidth;
long numAccesses;
int invalidCount;
public DecodeLogic(Core core, OutOrderExecutionEngine execEngine)
{
super(PortType.Unlimited, -1, -1 , -1, -1);
this.core = core;
this.containingExecutionEngine = execEngine;
fetchBuffer = execEngine.getFetchBuffer();
decodeBuffer = execEngine.getDecodeBuffer();
decodeWidth = core.getDecodeWidth();
}
public void performDecode()
{
if(containingExecutionEngine.isToStall5() == true /*pipeline stalled due to branch mis-prediction*/
|| containingExecutionEngine.isToStall1() == true /*IW full*/
|| containingExecutionEngine.isToStall2() == true /*rename stall*/)
{
return;
}
ReorderBuffer ROB = containingExecutionEngine.getReorderBuffer();
ReorderBufferEntry newROBEntry;
for(int i = 0; i < decodeWidth; i++)
{
if(decodeBuffer.isFull() == true)
{
break;
}
Instruction headInstruction = fetchBuffer.peek(0);
if(headInstruction != null)
{
if(ROB.isFull())
{
containingExecutionEngine.setToStall4(true);
break;
}
if(constrainedBySerialization(headInstruction) == true)
{
containingExecutionEngine.setToStall6(true);
break;
}
if(headInstruction.getOperationType() == OperationType.load ||
headInstruction.getOperationType() == OperationType.store)
{
boolean isLoad = (headInstruction.getOperationType() == OperationType.load) ? true : false;
if(containingExecutionEngine.getCoreMemorySystem().getLsqueue().isFull(isLoad))
{
containingExecutionEngine.setToStall3(true);
break;
}
}
newROBEntry = makeROBEntries(headInstruction);
decodeBuffer.enqueue(newROBEntry);
fetchBuffer.dequeue();
incrementNumAccesses(1);
if(SimulationConfig.debugMode)
{
System.out.println("decoded : " + GlobalClock.getCurrentTime()/core.getStepSize() + " : " + headInstruction);
}
}
else
{
break;
}
containingExecutionEngine.setToStall3(false);
containingExecutionEngine.setToStall4(false);
containingExecutionEngine.setToStall6(false);
}
}
private boolean constrainedBySerialization(Instruction headInstruction) {
if(containingExecutionEngine.getReorderBuffer().getNumCPUIDsInBuffer() > 0)
return true;
if(containingExecutionEngine.getReorderBuffer().getNumMFencesInBuffer() > 0
&& (headInstruction.getOperationType() == OperationType.load
|| headInstruction.getOperationType() == OperationType.store))
return true;
if(containingExecutionEngine.getReorderBuffer().getNumSFencesInBuffer() > 0
&& (headInstruction.getOperationType() == OperationType.store))
return true;
if(containingExecutionEngine.getReorderBuffer().getNumLFencesInBuffer() > 0
&& (headInstruction.getOperationType() == OperationType.load))
return true;
return false;
}
ReorderBufferEntry makeROBEntries(Instruction newInstruction)
{
if(newInstruction != null)
{
ReorderBufferEntry newROBEntry = containingExecutionEngine.getReorderBuffer()
.addInstructionToROB(
newInstruction,
newInstruction.getThreadID());
//if load or store, make entry in LSQ
if(newInstruction.getOperationType() == OperationType.load ||
newInstruction.getOperationType() == OperationType.store)
{
boolean isLoad;
if (newInstruction.getOperationType() == OperationType.load)
isLoad = true;
else
isLoad = false;
containingExecutionEngine.getCoreMemorySystem().allocateLSQEntry(isLoad,
newROBEntry.getInstruction().getSourceOperand1MemValue(),
newROBEntry);
}
if(newInstruction.getOperationType() == OperationType.cpuid)
{
containingExecutionEngine.getReorderBuffer().incrementNumCPUIDsInBuffer();
}
if(newInstruction.getOperationType() == OperationType.mfence)
{
containingExecutionEngine.getReorderBuffer().incrementNumMFencesInBuffer();
}
if(newInstruction.getOperationType() == OperationType.sfence)
{
containingExecutionEngine.getReorderBuffer().incrementNumSFencesInBuffer();
}
if(newInstruction.getOperationType() == OperationType.lfence)
{
containingExecutionEngine.getReorderBuffer().incrementNumLFencesInBuffer();
}
return newROBEntry;
}
return null;
}
@Override
public void handleEvent(EventQueue eventQ, Event event) {
}
void incrementNumAccesses(int incrementBy)
{
numAccesses += incrementBy;
}
public EnergyConfig calculateAndPrintEnergy(FileWriter outputFileWriter, String componentName) throws IOException
{
EnergyConfig power = new EnergyConfig(containingExecutionEngine.getContainingCore().getDecodePower(), numAccesses);
power.printEnergyStats(outputFileWriter, componentName);
return power;
}
}