|
|
|
@ -1,12 +1,16 @@
|
|
|
|
|
package processor.pipeline;
|
|
|
|
|
import processor.Processor;
|
|
|
|
|
|
|
|
|
|
import configuration.Configuration;
|
|
|
|
|
import generic.Element;
|
|
|
|
|
import generic.Event;
|
|
|
|
|
import generic.ExecutionCompleteEvent;
|
|
|
|
|
import generic.Instruction;
|
|
|
|
|
import generic.Simulator;
|
|
|
|
|
import generic.Statistics;
|
|
|
|
|
import generic.Instruction.OperationType;
|
|
|
|
|
import generic.Operand.OperandType;
|
|
|
|
|
|
|
|
|
|
public class Execute {
|
|
|
|
|
public class Execute implements Element{
|
|
|
|
|
Processor containingProcessor;
|
|
|
|
|
OF_EX_LatchType OF_EX_Latch;
|
|
|
|
|
EX_MA_LatchType EX_MA_Latch;
|
|
|
|
@ -24,161 +28,186 @@ public class Execute {
|
|
|
|
|
{
|
|
|
|
|
// storing x31 here itself to not to complicate.
|
|
|
|
|
// TODO:remove this later in pipeline
|
|
|
|
|
if(OF_EX_Latch.isEX_enable())
|
|
|
|
|
if(OF_EX_Latch.isEX_enable()&& !OF_EX_Latch.isEX_busy())
|
|
|
|
|
{
|
|
|
|
|
int op1 = OF_EX_Latch.getOp1();
|
|
|
|
|
int op2 = OF_EX_Latch.getOp2();
|
|
|
|
|
int imm = OF_EX_Latch.getImm();
|
|
|
|
|
System.out.println("op1: "+op1+" op2: "+op2+" imm: "+imm);
|
|
|
|
|
Instruction instruction = OF_EX_Latch.getInstruction();
|
|
|
|
|
int cur_pc = containingProcessor.getRegisterFile().getProgramCounter();
|
|
|
|
|
int alu_result = 0;
|
|
|
|
|
System.out.println("EX: " + instruction);
|
|
|
|
|
OperationType alu_op = OF_EX_Latch.getInstruction().getOperationType();
|
|
|
|
|
System.out.println("ALU OP: " + alu_op);
|
|
|
|
|
boolean noma = false;
|
|
|
|
|
Statistics.setNumberOfInstructions(Statistics.getNumberOfInstructions() + 1);
|
|
|
|
|
switch(alu_op)
|
|
|
|
|
{
|
|
|
|
|
case add: alu_result = op1 + op2; break;
|
|
|
|
|
case addi: alu_result = op1 + imm; break;
|
|
|
|
|
case sub: alu_result = op1 - op2; break;
|
|
|
|
|
case subi: alu_result = op1 - imm; break;
|
|
|
|
|
case mul: alu_result = op1 * op2; break;
|
|
|
|
|
case muli: alu_result = op1 * imm; break;
|
|
|
|
|
case div:
|
|
|
|
|
alu_result = op1 / op2;
|
|
|
|
|
containingProcessor.getRegisterFile().setValue(31, op1 % op2);
|
|
|
|
|
break;
|
|
|
|
|
case divi:
|
|
|
|
|
alu_result = op1 / imm;
|
|
|
|
|
containingProcessor.getRegisterFile().setValue(31, op1 % imm);
|
|
|
|
|
break;
|
|
|
|
|
case and: alu_result = op1 & op2; break;
|
|
|
|
|
case andi: alu_result = op1 & imm; break;
|
|
|
|
|
case or: alu_result = op1 | op2; break;
|
|
|
|
|
case ori: alu_result = op1 | imm; break;
|
|
|
|
|
case xor: alu_result = op1 ^ op2; break;
|
|
|
|
|
case xori: alu_result = op1 ^ imm; break;
|
|
|
|
|
case slt: alu_result= (op1 < op2) ? 1 : 0; break;
|
|
|
|
|
case slti: alu_result= (op1 < imm) ? 1 : 0; break;
|
|
|
|
|
case sll:
|
|
|
|
|
containingProcessor.getRegisterFile().setValue(31, (int) Math.pow(2, op2));
|
|
|
|
|
alu_result = op1 << op2;
|
|
|
|
|
break;
|
|
|
|
|
case slli:
|
|
|
|
|
containingProcessor.getRegisterFile().setValue(31, (int) Math.pow(2, imm));
|
|
|
|
|
alu_result = op1 << imm;
|
|
|
|
|
break;
|
|
|
|
|
case srl:
|
|
|
|
|
containingProcessor.getRegisterFile().setValue(31, op1 & (1 << (op2 - 1)));
|
|
|
|
|
alu_result = op1 >>> op2;
|
|
|
|
|
break;
|
|
|
|
|
case srli:
|
|
|
|
|
containingProcessor.getRegisterFile().setValue(31, op1 & (1 << (imm - 1)));
|
|
|
|
|
alu_result = op1 >>> imm;
|
|
|
|
|
break;
|
|
|
|
|
case sra:
|
|
|
|
|
containingProcessor.getRegisterFile().setValue(31, op1 & (1 << (op2 - 1)));
|
|
|
|
|
alu_result = op1 >> op2;
|
|
|
|
|
break;
|
|
|
|
|
case srai:
|
|
|
|
|
containingProcessor.getRegisterFile().setValue(31, op1 & (1 << (imm - 1)));
|
|
|
|
|
alu_result = op1 >> imm;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case load: alu_result = op1 + imm; break;
|
|
|
|
|
case store: alu_result = op2 + imm; break;
|
|
|
|
|
case jmp:
|
|
|
|
|
OperationType alu_op = OF_EX_Latch.getInstruction().getOperationType();
|
|
|
|
|
long latency = 0;
|
|
|
|
|
switch (alu_op) {
|
|
|
|
|
case mul:
|
|
|
|
|
case muli:
|
|
|
|
|
latency = Configuration.multiplier_latency;
|
|
|
|
|
break;
|
|
|
|
|
case div:
|
|
|
|
|
case divi:
|
|
|
|
|
latency = Configuration.divider_latency;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
latency = Configuration.ALU_latency;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Simulator.getEventQueue().addEvent(new ExecutionCompleteEvent(latency, this, this));
|
|
|
|
|
OF_EX_Latch.setEX_busy(true);
|
|
|
|
|
EX_MA_Latch.setMA_enable(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void handleEvent(Event e) {
|
|
|
|
|
int op1 = OF_EX_Latch.getOp1();
|
|
|
|
|
int op2 = OF_EX_Latch.getOp2();
|
|
|
|
|
int imm = OF_EX_Latch.getImm();
|
|
|
|
|
System.out.println("op1: "+op1+" op2: "+op2+" imm: "+imm);
|
|
|
|
|
Instruction instruction = OF_EX_Latch.getInstruction();
|
|
|
|
|
int cur_pc = containingProcessor.getRegisterFile().getProgramCounter();
|
|
|
|
|
int alu_result = 0;
|
|
|
|
|
System.out.println("EX: " + instruction);
|
|
|
|
|
OperationType alu_op = OF_EX_Latch.getInstruction().getOperationType();
|
|
|
|
|
System.out.println("ALU OP: " + alu_op);
|
|
|
|
|
boolean noma = false;
|
|
|
|
|
Statistics.setNumberOfInstructions(Statistics.getNumberOfInstructions() + 1);
|
|
|
|
|
switch(alu_op)
|
|
|
|
|
{
|
|
|
|
|
case add: alu_result = op1 + op2; break;
|
|
|
|
|
case addi: alu_result = op1 + imm; break;
|
|
|
|
|
case sub: alu_result = op1 - op2; break;
|
|
|
|
|
case subi: alu_result = op1 - imm; break;
|
|
|
|
|
case mul: alu_result = op1 * op2; break;
|
|
|
|
|
case muli: alu_result = op1 * imm; break;
|
|
|
|
|
case div:
|
|
|
|
|
alu_result = op1 / op2;
|
|
|
|
|
containingProcessor.getRegisterFile().setValue(31, op1 % op2);
|
|
|
|
|
break;
|
|
|
|
|
case divi:
|
|
|
|
|
alu_result = op1 / imm;
|
|
|
|
|
containingProcessor.getRegisterFile().setValue(31, op1 % imm);
|
|
|
|
|
break;
|
|
|
|
|
case and: alu_result = op1 & op2; break;
|
|
|
|
|
case andi: alu_result = op1 & imm; break;
|
|
|
|
|
case or: alu_result = op1 | op2; break;
|
|
|
|
|
case ori: alu_result = op1 | imm; break;
|
|
|
|
|
case xor: alu_result = op1 ^ op2; break;
|
|
|
|
|
case xori: alu_result = op1 ^ imm; break;
|
|
|
|
|
case slt: alu_result= (op1 < op2) ? 1 : 0; break;
|
|
|
|
|
case slti: alu_result= (op1 < imm) ? 1 : 0; break;
|
|
|
|
|
case sll:
|
|
|
|
|
containingProcessor.getRegisterFile().setValue(31, (int) Math.pow(2, op2));
|
|
|
|
|
alu_result = op1 << op2;
|
|
|
|
|
break;
|
|
|
|
|
case slli:
|
|
|
|
|
containingProcessor.getRegisterFile().setValue(31, (int) Math.pow(2, imm));
|
|
|
|
|
alu_result = op1 << imm;
|
|
|
|
|
break;
|
|
|
|
|
case srl:
|
|
|
|
|
containingProcessor.getRegisterFile().setValue(31, op1 & (1 << (op2 - 1)));
|
|
|
|
|
alu_result = op1 >>> op2;
|
|
|
|
|
break;
|
|
|
|
|
case srli:
|
|
|
|
|
containingProcessor.getRegisterFile().setValue(31, op1 & (1 << (imm - 1)));
|
|
|
|
|
alu_result = op1 >>> imm;
|
|
|
|
|
break;
|
|
|
|
|
case sra:
|
|
|
|
|
containingProcessor.getRegisterFile().setValue(31, op1 & (1 << (op2 - 1)));
|
|
|
|
|
alu_result = op1 >> op2;
|
|
|
|
|
break;
|
|
|
|
|
case srai:
|
|
|
|
|
containingProcessor.getRegisterFile().setValue(31, op1 & (1 << (imm - 1)));
|
|
|
|
|
alu_result = op1 >> imm;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case load: alu_result = op1 + imm; break;
|
|
|
|
|
case store: alu_result = op2 + imm; break;
|
|
|
|
|
case jmp:
|
|
|
|
|
{
|
|
|
|
|
OperandType optype = instruction.getSourceOperand1().getOperandType();
|
|
|
|
|
if (optype == OperandType.Register){
|
|
|
|
|
imm = containingProcessor.getRegisterFile().getValue(
|
|
|
|
|
instruction.getSourceOperand1().getValue());
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
imm = OF_EX_Latch.getImm();
|
|
|
|
|
}
|
|
|
|
|
alu_result = cur_pc + imm ;
|
|
|
|
|
EX_IF_Latch.setIF_enable(true);
|
|
|
|
|
|
|
|
|
|
EX_IF_Latch.setPC(alu_result-1);
|
|
|
|
|
noma = true;
|
|
|
|
|
containingProcessor.getOFUnit().setProceed(false);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case beq:
|
|
|
|
|
{
|
|
|
|
|
if(op1 == op2)
|
|
|
|
|
{
|
|
|
|
|
OperandType optype = instruction.getSourceOperand1().getOperandType();
|
|
|
|
|
if (optype == OperandType.Register){
|
|
|
|
|
imm = containingProcessor.getRegisterFile().getValue(
|
|
|
|
|
instruction.getSourceOperand1().getValue());
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
imm = OF_EX_Latch.getImm();
|
|
|
|
|
}
|
|
|
|
|
alu_result = cur_pc + imm ;
|
|
|
|
|
EX_IF_Latch.setIF_enable(true);
|
|
|
|
|
|
|
|
|
|
alu_result = cur_pc + imm;
|
|
|
|
|
EX_IF_Latch.setPC(alu_result-1);
|
|
|
|
|
noma = true;
|
|
|
|
|
containingProcessor.getOFUnit().setProceed(false);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case beq:
|
|
|
|
|
{
|
|
|
|
|
if(op1 == op2)
|
|
|
|
|
{
|
|
|
|
|
EX_IF_Latch.setIF_enable(true);
|
|
|
|
|
alu_result = cur_pc + imm;
|
|
|
|
|
EX_IF_Latch.setPC(alu_result-1);
|
|
|
|
|
noma = true;
|
|
|
|
|
containingProcessor.getOFUnit().setProceed(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case bne:
|
|
|
|
|
{
|
|
|
|
|
if(op1 != op2)
|
|
|
|
|
{
|
|
|
|
|
alu_result = cur_pc + imm;
|
|
|
|
|
EX_IF_Latch.setIF_enable(true);
|
|
|
|
|
EX_IF_Latch.setPC(alu_result-1);
|
|
|
|
|
noma = true;
|
|
|
|
|
containingProcessor.getOFUnit().setProceed(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case blt:
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if(op1 < op2)
|
|
|
|
|
{
|
|
|
|
|
alu_result = cur_pc + imm;
|
|
|
|
|
EX_IF_Latch.setIF_enable(true);
|
|
|
|
|
EX_IF_Latch.setPC(alu_result-1);
|
|
|
|
|
noma = true;
|
|
|
|
|
containingProcessor.getOFUnit().setProceed(false);
|
|
|
|
|
// System.out.println("hello world");
|
|
|
|
|
}
|
|
|
|
|
// System.out.println("hello world2");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case bgt:
|
|
|
|
|
{
|
|
|
|
|
if(op1 > op2)
|
|
|
|
|
{
|
|
|
|
|
alu_result = cur_pc + imm;
|
|
|
|
|
EX_IF_Latch.setIF_enable(true);
|
|
|
|
|
EX_IF_Latch.setPC(alu_result-1);
|
|
|
|
|
noma = true;
|
|
|
|
|
containingProcessor.getOFUnit().setProceed(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case end:
|
|
|
|
|
{
|
|
|
|
|
// containingProcessor.getRegisterFile().setProgramCounter(containingProcessor.getRegisterFile().getProgramCounter()-1);
|
|
|
|
|
containingProcessor.getOFUnit().setisEnd(true);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
System.out.println("ALU RESULT: " + alu_result+"\n\n");
|
|
|
|
|
|
|
|
|
|
EX_MA_Latch.setALUResult(alu_result);
|
|
|
|
|
EX_MA_Latch.setInstruction(OF_EX_Latch.getInstruction());
|
|
|
|
|
if(!noma)
|
|
|
|
|
break;
|
|
|
|
|
case bne:
|
|
|
|
|
{
|
|
|
|
|
EX_MA_Latch.setMA_enable(true);
|
|
|
|
|
}else{
|
|
|
|
|
Statistics.setControlhazards(Statistics.getControlhazards()+2); // stall 2 cycles
|
|
|
|
|
if(op1 != op2)
|
|
|
|
|
{
|
|
|
|
|
alu_result = cur_pc + imm;
|
|
|
|
|
EX_IF_Latch.setIF_enable(true);
|
|
|
|
|
EX_IF_Latch.setPC(alu_result-1);
|
|
|
|
|
noma = true;
|
|
|
|
|
containingProcessor.getOFUnit().setProceed(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case blt:
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if(op1 < op2)
|
|
|
|
|
{
|
|
|
|
|
alu_result = cur_pc + imm;
|
|
|
|
|
EX_IF_Latch.setIF_enable(true);
|
|
|
|
|
EX_IF_Latch.setPC(alu_result-1);
|
|
|
|
|
noma = true;
|
|
|
|
|
containingProcessor.getOFUnit().setProceed(false);
|
|
|
|
|
// System.out.println("hello world");
|
|
|
|
|
}
|
|
|
|
|
// System.out.println("hello world2");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case bgt:
|
|
|
|
|
{
|
|
|
|
|
if(op1 > op2)
|
|
|
|
|
{
|
|
|
|
|
alu_result = cur_pc + imm;
|
|
|
|
|
EX_IF_Latch.setIF_enable(true);
|
|
|
|
|
EX_IF_Latch.setPC(alu_result-1);
|
|
|
|
|
noma = true;
|
|
|
|
|
containingProcessor.getOFUnit().setProceed(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case end:
|
|
|
|
|
{
|
|
|
|
|
// containingProcessor.getRegisterFile().setProgramCounter(containingProcessor.getRegisterFile().getProgramCounter()-1);
|
|
|
|
|
containingProcessor.getOFUnit().setisEnd(true);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
System.out.println("ALU RESULT: " + alu_result+"\n\n");
|
|
|
|
|
|
|
|
|
|
EX_MA_Latch.setALUResult(alu_result);
|
|
|
|
|
EX_MA_Latch.setInstruction(OF_EX_Latch.getInstruction());
|
|
|
|
|
if(!noma)
|
|
|
|
|
{
|
|
|
|
|
EX_MA_Latch.setMA_enable(true);
|
|
|
|
|
}else{
|
|
|
|
|
Statistics.setControlhazards(Statistics.getControlhazards()+2); // stall 2 cycles
|
|
|
|
|
}
|
|
|
|
|
OF_EX_Latch.setEX_busy(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|