/// <summary> /// Inputs used by the device in the active instruction /// </summary> /// <param name="bankID">BankID of the device</param> /// <param name="cycle">Zero-based program cycle number</param> /// <param name="acuAddrPortOut_Stat"></param> /// <param name="ramACUPortIn_Stat"></param> /// <param name="mux1PortOut_Stat"></param> /// <param name="ramMux1PortIn_Stat"></param> private static void InputsUsed( Bank bankID, int cycle, out PortStatus acuAddrPortOut_Stat, out PortStatus mux1PortOut_Stat, out PortStatus ramACUPortIn_Stat, out PortStatus ramMux1PortIn_Stat) { ramMux1PortIn_Stat = PortStatus.Inactive; // acu addr out, ram addr, and mux1 out in are always active acuAddrPortOut_Stat = PortStatus.Active; ramACUPortIn_Stat = PortStatus.Active; mux1PortOut_Stat = PortStatus.Active; // mux1in and is active if a ram write operation is in progress if (cycle < 0) { return; } var instr = CodeStoreModel.Instruction(cycle); if (instr == null) { return; } // ram write instruction? if ((bankID == Bank.Bank_A && instr.Da == 1) || (bankID == Bank.Bank_B && instr.Db == 1)) { ramMux1PortIn_Stat = PortStatus.Active; } }
/// <summary> /// Inputs used by the device in the active instruction /// </summary> /// <param name="cycle">Zero-based program cycle number</param> /// <param name="mux2APortOut_Stat"></param> /// <param name="mux2BPortOut_Stat"></param> /// <param name="shifterPortOut_Stat"></param> /// <param name="macMux2APortIn_Stat"></param> /// <param name="macMux2BPortIn_Stat"></param> /// <param name="macShifterPortIn_Stat"></param> private static void InputsUsed( int cycle, out PortStatus mux2APortOut_Stat, out PortStatus mux2BPortOut_Stat, out PortStatus shifterPortOut_Stat, out PortStatus macMux2APortIn_Stat, out PortStatus macMux2BPortIn_Stat, out PortStatus macShifterPortIn_Stat) { // Mux 2 and shifter outputs are always active mux2APortOut_Stat = PortStatus.Active; mux2BPortOut_Stat = PortStatus.Active; shifterPortOut_Stat = PortStatus.Active; // Default macMux2APortIn_Stat = PortStatus.Inactive; macMux2BPortIn_Stat = PortStatus.Inactive; macShifterPortIn_Stat = PortStatus.Inactive; var instr = CodeStoreModel.Instruction(cycle - 1); if (instr == null) { return; } var instMAC = instr.Mac; switch (instMAC ?? "") { case "loadalu": // Adds the previous ALU output (from the shifter) to the product and // starts a new accumulation. macMux2APortIn_Stat = PortStatus.Active; macMux2BPortIn_Stat = PortStatus.Active; macShifterPortIn_Stat = PortStatus.Active; break; case "clra": // Clears the accumulator and stores the current product macMux2APortIn_Stat = PortStatus.Active; macMux2BPortIn_Stat = PortStatus.Active; break; case "hold": // Holds the value in the accumulator from the previous cycle. // No multiply break; case "macc": // Multiplies the values on mux2 of side A and side B. // Adds the product to the current value of the accumulator. macMux2APortIn_Stat = PortStatus.Active; macMux2BPortIn_Stat = PortStatus.Active; break; } }
/// <summary> /// Instruction for the cycle /// Returns null if the instruction doesn't apply to this device /// </summary> /// <param name="cycle">Zero-based program cycle number</param> /// <returns></returns> private static string Instr(int cycle) { if (cycle < 0) { return(""); } var instr = CodeStoreModel.Instruction(cycle); return(instr.Alu); }
/// <summary> /// Address of instruction for cycle /// </summary> /// <param name="cycle">Zero-based program cycle number</param> /// <returns></returns> private static string AddrCalc(int cycle) { if (cycle < 0) { return(""); } var instr = CodeStoreModel.Instruction(cycle); return(string.Format("addr({0})", instr.AddrOp)); }
/// <summary> /// Instruction for the cycle /// </summary> /// <param name="cycle">Zero-based program cycle number</param> /// <returns></returns> public static string ActiveInstr(int cycle) { if (cycle < 0) { return(""); } var instr = CodeStoreModel.Instruction(cycle); string activeInstr = null; switch (instr.Alu ?? "") { case "set0": case "set1": case "seta": case "setb": case "nega": case "negb": case "passrama": case "passramb": case "add": case "tdeca": case "suba": case "subb": case "absa": case "absb": case "addabsa": case "addabsb": case "hold": break; case "englobals": case "ensatrnd": case "ensem": case "setsem": case "clearsem": activeInstr = instr.Alu; break; case "tsuba": case "tsubb": case "taddabsa": case "taddabsb": case "sqlcmp": case "sqlcnt": case "sqa": case "sqb": break; } return(activeInstr); }
/// <summary> /// Instruction for the cycle /// Returns null if the instruction doesn't apply to this device /// </summary> /// <param name="bankID">BankID of the device</param> /// <param name="cycle">Zero-based program cycle number</param> /// <returns></returns> private static string ActiveInstr(Bank bankID, int cycle) { if (cycle < 0) { return(""); } string ramWriteOp = null; string ramALUReadOp = null; if (bankID == Bank.Bank_A && CodeStoreModel.Instruction(cycle).Da == 1) { ramWriteOp = "da"; } if (bankID == Bank.Bank_A && CodeStoreModel.Instruction(cycle).Db == 1) { ramWriteOp = "db"; } if (bankID == Bank.Bank_A && CodeStoreModel.Instruction(cycle).Equals("passrama")) { ramALUReadOp = "passrama"; } if (bankID == Bank.Bank_B && CodeStoreModel.Instruction(cycle).Equals("passramb")) { ramALUReadOp = "passramb"; } var sb = new StringBuilder(); if (ramWriteOp != null) { sb.AppendFormat("write({0})", ramWriteOp); } if (ramWriteOp != null && ramALUReadOp != null) { sb.Append(", "); } if (ramALUReadOp != null) { sb.AppendFormat("alu({0})", ramALUReadOp); } return(sb.ToString()); }
/// <summary> /// Inputs used by the device in the active instruction /// </summary> /// <param name="bankID">BankID of the device</param> /// <param name="cycle">Zero-based program cycle number</param> /// <param name="mux2PortOut_Stat">Port status</param> /// <param name="macPortOut_Stat">Port status</param> /// <param name="mux3Mux2PortIn_Stat">Port status</param> /// <param name="mux2MacRamPortIn_Stat">Port status</param> private static void InputsUsed( Bank bankID, int cycle, out PortStatus mux2PortOut_Stat, out PortStatus macPortOut_Stat, out PortStatus mux3Mux2PortIn_Stat, out PortStatus mux2MacRamPortIn_Stat) { mux2PortOut_Stat = PortStatus.Inactive; macPortOut_Stat = PortStatus.Inactive; mux3Mux2PortIn_Stat = PortStatus.Inactive; mux2MacRamPortIn_Stat = PortStatus.Inactive; // source port var instrWord = CodeStoreModel.Instruction(cycle - PIPELINE_DELAY); if (instrWord != null) { var instr = bankID == Bank.Bank_A ? instrWord.MuxA : instrWord.MuxB; switch (instr) { case "ba": // Bus to ALU case "sa": // Shifter to ALU case "bra": // Bus to RAM, RAM to ALU case "sra": // Shifter to RAM, RAM to ALU mux2PortOut_Stat = PortStatus.Active; mux3Mux2PortIn_Stat = PortStatus.Active; break; case "bm": // Bus to MAC, MAC to ALU case "sm": // Shifter to MAC, MAC to ALU case "brm": // Bus to RAM, to MAC case "srm": // Shifter to RAM to MAC macPortOut_Stat = PortStatus.Active; mux2MacRamPortIn_Stat = PortStatus.Active; break; default: break; } } }
/// <summary> /// Instruction for the cycle /// Returns null if the instruction doesn't apply to this device /// </summary> /// <param name="cycle">Zero-based program cycle number</param> /// <returns></returns> private static string ActiveInstr(int cycle) { if (cycle < 0) { return(""); } var instr = CodeStoreModel.Instruction(cycle); if (instr.Mac == null) { return(""); } else { return(instr.Mac.Replace("holdmac", "hold")); } }
/// <summary> /// Constructor /// </summary> /// <param name="cycle">Cycle number</param> public CodeStateCycle(int cycle) { var instr = CodeStoreModel.Instruction(cycle); var state = CodeStoreModel.State(cycle); if (instr == null || state == null) { return; } Cycle = cycle; Label = state.Label; Instruction = new CodeInstruction(instr); IsJumpInstruction = Convert.ToBoolean(Instruction.Instruction.Eob); CodeState = new CodeState(state); GroupName = Label; UniqueName = string.Format("{0}_{1}", GroupName, Cycle); }
/// <summary> /// Instruction for the cycle /// Returns null if the instruction doesn't apply to this device /// </summary> /// <param name="bankID">BankID of the device</param> /// <param name="cycle">Zero-based program cycle number</param> /// <returns></returns> private static string InstrForCycle(Bank bankID, int cycle) { if (cycle < 0) { return(""); } // "ba": // bus to alu // "bra": // bus to ram, ram to alu // "bm": // bus to mac, mac to alu // "brm": // bus to ram, to mac var instrWord = CodeStoreModel.Instruction(cycle); var muxInstr = bankID == Bank.Bank_A ? CodeStoreModel.Instruction(cycle).MuxA : CodeStoreModel.Instruction(cycle).MuxB; return(muxInstr); }
/// <summary> /// Instruction text for the cycle /// </summary> /// <param name="cycle">Zero-based program cycle number</param> /// <returns></returns> private static string ActiveInstr(int cycle) { if (cycle < 0) { return(""); } var instr = CodeStoreModel.Instruction(cycle); if (instr.ShiftOp != 0) { switch (instr.ShiftOp) { case 1: return("shift >> 1"); case 2: return("shift >> 2"); case 3: return("shift >> 3"); case 4: return("shift >> 4"); case 5: return("shift >> 8"); case 6: return("shift << 1"); case 7: return("shift << 2"); default: return("unknown"); } } else { return(""); } }
/// <summary> /// Instruction for the cycle given /// Returns null if the instruction doesn't apply to this device /// </summary> /// <param name="cycle">Zero-based program cycle number</param> /// <returns></returns> private static CyControlWord ActiveInstrWord(int cycle) { // "ba": // bus to alu // "bra": // bus to ram, ram to alu // "bm": // bus to mac, mac to alu // "brm": // bus to ram, to mac var instr = CodeStoreModel.Instruction(cycle); if (instr == null || instr.MuxA == null || instr.MuxB == null) { return(null); } if ((!instr.MuxA.StartsWith("b") && !instr.MuxB.StartsWith("b"))) { return(null); } return(instr); }
/// <summary> /// Instruction for the cycle /// Returns null if the instruction doesn't apply to this device /// </summary> /// <param name="cycle">Zero-based program cycle number</param> /// <returns></returns> private static string ActiveInstr(int cycle) { if (cycle < 0) { return(""); } // "ba": // bus to alu // "bra": // bus to ram, ram to alu // "bm": // bus to mac, mac to alu // "brm": // bus to ram, to mac var instr = CodeStoreModel.Instruction(cycle); if (instr != null) { return(string.Format("({0},{1})", instr.MuxA, instr.MuxB)); } else { return(""); } }
/// <summary> /// Inputs used by the device in the active instruction /// </summary> /// <param name="bankID">BankID of the device</param> /// <param name="cycle">Zero-based program cycle number</param> /// <param name="mux1PortOut_Stat">Port status</param> /// <param name="dataRamPortOut_Stat">Port status</param> /// <param name="mux2Mux1PortIn_Stat">Port status</param> /// <param name="mux2DataRamPortIn_Stat">Port status</param> private static void InputsUsed( Bank bankID, int cycle, out PortStatus mux1PortOut_Stat, out PortStatus dataRamPortOut_Stat, out PortStatus mux2Mux1PortIn_Stat, out PortStatus mux2DataRamPortIn_Stat) { mux1PortOut_Stat = PortStatus.Inactive; dataRamPortOut_Stat = PortStatus.Inactive; mux2Mux1PortIn_Stat = PortStatus.Inactive; mux2DataRamPortIn_Stat = PortStatus.Inactive; // active instruction (pipeline delayed) var instrWord = CodeStoreModel.Instruction(cycle - PIPELINE_DELAY); if (instrWord != null) { var instr = bankID == Bank.Bank_A ? instrWord.MuxA : instrWord.MuxB; switch (instr) { case "ba": // Bus to ALU case "sa": // Shifter to ALU case "bm": // Bus to MAC, MAC to ALU case "sm": // Shifter to MAC, MAC to ALU mux1PortOut_Stat = PortStatus.Active; mux2Mux1PortIn_Stat = PortStatus.Active; break; case "bra": // Bus to RAM, RAM to ALU case "sra": // Shifter to RAM, RAM to ALU case "brm": // Bus to RAM, to MAC case "srm": // Shifter to RAM to MAC dataRamPortOut_Stat = PortStatus.Active; mux2DataRamPortIn_Stat = PortStatus.Active; break; default: break; } } // current instruction instrWord = CodeStoreModel.Instruction(cycle); if (instrWord != null) { var instr = bankID == Bank.Bank_A ? instrWord.MuxA : instrWord.MuxB; switch (instr) { // ignore - not latched in until [cycle - PIPELINE_DELAY] case "ba": // Bus to ALU case "sa": // Shifter to ALU case "bm": // Bus to MAC, MAC to ALU case "sm": // Shifter to MAC, MAC to ALU break; // latched in now case "bra": // Bus to RAM, RAM to ALU case "sra": // Shifter to RAM, RAM to ALU case "brm": // Bus to RAM, to MAC case "srm": // Shifter to RAM to MAC dataRamPortOut_Stat = PortStatus.Active; mux2DataRamPortIn_Stat = PortStatus.Active; break; default: break; } } }
/// <summary> /// Create a new instance of this device for the given cycle /// </summary> /// <param name="bankID">BankID of the device</param> /// <param name="cycle">Zero-based program cycle number</param> /// <param name="code">Data area section string from the assembly code file</param> public ACUModel(Bank bankID, int cycle, string code) : base(bankID, cycle, VALUE_WIDTH, ADDR_WIDTH, PIPELINE_DELAY) { // ACU values update during simulator makestep(), so properties must be read from previous cycle //cycle -= 1; if (cycle < 0) { return; } // name name = bankID == Bank.Bank_A ? DevicePort.ACU_A.ToString() : DevicePort.ACU_B.ToString(); // instructions var instr = bankID == Bank.Bank_A ? CodeStoreModel.Instruction(cycle).AcuA : CodeStoreModel.Instruction(cycle).AcuB; instructions.Add(instr); // ACU has no connectionInputs // connectionInputs // output output = OutputCalc(bankID, cycle); // reg var field = bankID == Bank.Bank_A ? "Aacc" : "Bacc"; reg_reg = DFBState.GetCySimulatorPrivateField <int?>(cycle, field); // freg field = bankID == Bank.Bank_A ? "Afreg" : "Bfreg"; reg_freg = DFBState.GetCySimulatorPrivateField <int?>(cycle, field); // mreg field = bankID == Bank.Bank_A ? "Amreg" : "Bmreg"; reg_mreg = DFBState.GetCySimulatorPrivateField <int?>(cycle, field); // lreg field = bankID == Bank.Bank_A ? "Alreg" : "Blreg"; reg_lreg = DFBState.GetCySimulatorPrivateField <int?>(cycle, field); // flag_mod field = bankID == Bank.Bank_A ? "Amodflag" : "Bmodflag"; reg_flag_mod = DFBState.GetCySimulatorPrivateField <int?>(cycle, field); // ram field = bankID == Bank.Bank_A ? "aacuram" : "bacuram"; ram = DFBState.GetCySimulatorPrivateField <int[]>(cycle, field); // address field = "acuaddr"; address = DFBState.GetCySimulatorPrivateField <int?>(cycle - 0, field); // addressPrev field = "acuaddr"; addressPrev = DFBState.GetCySimulatorPrivateField <int?>(cycle - 1, field); ramItems = BuildRamItems(bankID, this.ram, code); var sb = new StringBuilder(); foreach (var ramItem in RamItems) { sb.AppendFormat("{0,4} {1,4} {2,3} {3}\n", "[" + ramItem.Address + "]", ramItem.ValHex, ramItem.ValInt, ramItem.Comment); } ramString = sb.ToString().TrimEnd('\n'); }
/// <summary> /// Instruction for the cycle given /// Returns null if the instruction doesn't apply to this device /// </summary> /// <param name="cycle">Zero-based program cycle number</param> /// <returns></returns> public static CyControlWord ActiveInstrWord(int cycle) { return(CodeStoreModel.Instruction(cycle)); }