package processor.pipeline; import java.util.Arrays; import java.util.LinkedList; import java.util.Queue; import generic.Instruction; import processor.Processor; import generic.Instruction.OperationType; import generic.Operand.OperandType; import generic.Operand; public class OperandFetch { Processor containingProcessor; IF_OF_LatchType IF_OF_Latch; OF_EX_LatchType OF_EX_Latch; IF_EnableLatchType IF_EnableLatch; static OperationType[] opTypes = OperationType.values(); boolean Proceed; Queue queue; boolean isEnd; public OperandFetch(Processor containingProcessor, IF_OF_LatchType iF_OF_Latch, OF_EX_LatchType oF_EX_Latch, IF_EnableLatchType iF_EnableLatch) { this.containingProcessor = containingProcessor; this.IF_OF_Latch = iF_OF_Latch; this.OF_EX_Latch = oF_EX_Latch; this.IF_EnableLatch = iF_EnableLatch; isEnd = false; Proceed = true; queue = new LinkedList<>(); queue.add(-1); queue.add(-1); queue.add(-1); } boolean checkdatahazard(int[] operands) { for(int i=0;i x == opcode)) { Operand rs1 = new Operand(); Operand rs2 = new Operand(); Operand rd = new Operand(); rs1.setOperandType(Operand.OperandType.Register); rs2.setOperandType(Operand.OperandType.Register); rd.setOperandType(Operand.OperandType.Register); rs1.setValue(Integer.parseInt(bin_instr.substring(5, 10), 2)); rs2.setValue(Integer.parseInt(bin_instr.substring(10, 15), 2)); rd.setValue(Integer.parseInt(bin_instr.substring(15, 20), 2)); int op1 = containingProcessor.getRegisterFile().getValue(rs1.getValue()); int op2 = containingProcessor.getRegisterFile().getValue(rs2.getValue()); if (checkdatahazard(new int[] { rs1.getValue(), rs2.getValue() })) { noDataHazard = false; }else{ addtoqueue = rd.getValue(); OF_EX_Latch.setInstruction(instr); OF_EX_Latch.setOp1(op1); OF_EX_Latch.setOp2(op2); instr.setDestinationOperand(rd); instr.setSourceOperand1(rs1); instr.setSourceOperand2(rs2); } } else if (Arrays.stream(R2I_type_operators).anyMatch(x -> x == opcode)) { Operand rs1 = new Operand(); Operand rd = new Operand(); rs1.setOperandType(Operand.OperandType.Register); rd.setOperandType(Operand.OperandType.Register); rs1.setValue(Integer.parseInt(bin_instr.substring(5, 10), 2)); rd.setValue(Integer.parseInt(bin_instr.substring(10, 15), 2)); // check 15th bit to see if it is negative int imm = Integer.parseInt(bin_instr.substring(15, 32), 2); if (bin_instr.charAt(15)=='1'){ imm = -1*twoscompliment(bin_instr.substring(15, 32)); System.out.println(bin_instr); } int op1 = containingProcessor.getRegisterFile().getValue(rs1.getValue()); int op2 = containingProcessor.getRegisterFile().getValue(rd.getValue()); // System.out.println("imm: " + imm); if (checkdatahazard(new int[] { rs1.getValue(), rd.getValue()})){ noDataHazard = false; }else{ if(opcode <= 22) { // > 21 means it is a branch instruction so no need to update queue addtoqueue = rd.getValue(); } OF_EX_Latch.setInstruction(instr); OF_EX_Latch.setImm(imm); OF_EX_Latch.setOp1(op1); OF_EX_Latch.setOp2(op2); instr.setDestinationOperand(rd); instr.setSourceOperand1(rs1); } } else if (Arrays.stream(R1I_type_operators).anyMatch(x -> x == opcode)) { if(opcode != 24){ Operand rd = new Operand(); rd.setOperandType(Operand.OperandType.Register); rd.setValue(Integer.parseInt(bin_instr.substring(5, 10), 2)); instr.setDestinationOperand(rd); int imm = Integer.parseInt(bin_instr.substring(10, 32), 2); if (bin_instr.charAt(10)=='1'){ imm = -1*twoscompliment(bin_instr.substring(10, 32)); System.out.println(bin_instr); } // if (checkdatahazard(new int[] { rd.getValue() })) { // noDataHazard = false; // }else{ // containingProcessor.getRegisterFile().setProgramCounter(containingProcessor.getRegisterFile().getProgramCounter()-1); OF_EX_Latch.setInstruction(instr); // OF_EX_Latch.setImm(imm); // isEnd = true; // } } else{ // opcode == 24 jmp Operand op = new Operand(); String imm = bin_instr.substring(10, 32); int imm_val = Integer.parseInt(imm, 2); if (imm.charAt(0) == '1'){ imm_val = -1*twoscompliment(imm); } if (imm_val != 0){ op.setOperandType(OperandType.Immediate); op.setValue(imm_val); instr.setSourceOperand1(op); } else{ op.setOperandType(OperandType.Register); op.setValue(Integer.parseInt(bin_instr.substring(5, 10), 2)); instr.setSourceOperand1(op); } if (checkdatahazard(new int[] { op.getValue() })) { noDataHazard = false; }else{ OF_EX_Latch.setInstruction(instr); OF_EX_Latch.setImm(imm_val); } } } OF_EX_Latch.setEX_enable(noDataHazard); if(!noDataHazard){ IF_EnableLatch.setFreeze(true); System.out.println("\n\nData Hazard - Interlock\n\n"); } } else if (!Proceed) { Proceed = true; System.out.println("\n\nControl Hazard - Interlock\n\n"); } updateQueue(addtoqueue); } public void setisEnd(boolean isEnd) { this.isEnd = isEnd; } public void setProceed(boolean proceed) { Proceed = proceed; if (!Proceed) { OF_EX_Latch.setEX_enable(false); } } }