/// <summary> /// Output value of the device for the given cycle /// </summary> /// <param name="bankID">BankID of the device</param> /// <param name="cycle">Zero-based program cycle number</param> /// <returns></returns> public static LabeledValue <long?> OutputCalc(Bank bankID, int cycle) { var label = "Out:"; // ram var field = bankID == Bank.Bank_A ? "DAram" : "DBram"; var ram = DFBState.GetCySimulatorPrivateField <long[]>(cycle, field); // address field = bankID == Bank.Bank_A ? "Aaddrnext" : "Baddrnext"; var address = DFBState.GetCySimulatorPrivateField <int?>(cycle, field); // ramVal / output if (address != null && address.HasValue && ram != null) { var r = new LabeledValue <long?>(label); r.Value = (int?)ram[address.Value]; r.FormattedValue = r.Value.HasValue ? FormatValue(VALUE_WIDTH, r.Value) : ""; return(r); } else { return(NullLabeledValue <long?>(label)); } }
/// <summary> /// Output value of the device for the given cycle /// </summary> /// <param name="bankID">BankID of the device</param> /// <param name="cycle">Zero-based program cycle number</param> /// <returns></returns> public static LabeledValue <long?> OutputCalc(Bank bankID, int cycle) { var label = "Out:"; var busWritten = BusWritten(cycle); if (busWritten == null) { return(NullLabeledValue <long?>(label)); } if (bankID == Bank.Bank_A && busWritten.Equals("A") || bankID == Bank.Bank_B && busWritten.Equals("B")) { // Value var shift = DFBState.GetCySimulatorPrivateField <long>(cycle, "shift"); var r = new LabeledValue <long?>("Out:"); r.Value = shift; r.FormattedValue = r.Value.HasValue ? FormatValue(VALUE_WIDTH, (int)r.Value) : ""; return(r); } else { return(NullLabeledValue <long?>(label)); } }
/// <summary> /// Output value of the device for the given cycle /// </summary> /// <param name="bankID">BankID of the device</param> /// <param name="cycle">Zero-based program cycle number</param> /// <returns></returns> public static LabeledValue <long?> OutputCalc(Bank bankID, int cycle) { var label = "Out:"; int?val = null; bool busRead_A; bool busRead_B; BusRead(cycle, out busRead_A, out busRead_B); if (bankID == Bank.Bank_A && !busRead_A) { return(NullLabeledValue <long?>(label)); } else if (bankID == Bank.Bank_B && !busRead_B) { return(NullLabeledValue <long?>(label)); } val = DFBState.GetCySimulatorPrivateField <int?>(cycle, "p3bus"); if (val == null || !val.HasValue) { return(NullLabeledValue <long?>(label)); } var r = new LabeledValue <long?>("Out:"); r.Value = Convert.ToInt32(val.Value); r.FormattedValue = r.Value.HasValue ? FormatValue(VALUE_WIDTH, (int)r.Value) : ""; return(r); }
/// <summary> /// Returns a labeled value for a nullable type /// </summary> /// <typeparam name="T"></typeparam> /// <param name="label"></param> /// <returns></returns> public static LabeledValue <T> NullLabeledValue <T>(string label) { var r = new LabeledValue <T>(label); r.Value = default(T); r.FormattedValue = ""; return(r); }
/// <summary> /// Create a new instance of this device for the given cycle /// </summary> /// <param name="cycle">Zero-based program cycle number</param> public ShifterModel(int cycle) : base(Bank.NotApplicable, cycle, VALUE_WIDTH, ADDR_WIDTH, PIPELINE_DELAY) { // name name = DevicePort.Shifter.ToString(); // instructions instructions.Add(ActiveInstr(cycle)); instructions.Add(ActiveInstr(cycle - 1)); // connectionInputs connectionInputs = Connections(cycle); // output output = OutputCalc(cycle); // input input = InputCalc(cycle); }
/// <summary> /// Input to the device for the given cycle /// </summary> /// <param name="cycle">Zero-based program cycle number</param> /// <returns></returns> private static LabeledValue <long?> InputCalc(int cycle) { var label = "In:"; var val = ALUModel.OutputCalc(cycle); if (val != null) { var r = new LabeledValue <long?>(label); r.Value = val.Value; r.FormattedValue = r.Value.HasValue ? FormatValue(VALUE_WIDTH, r.Value) : ""; return(r); } else { return(NullLabeledValue <long?>(label)); } }
/// <summary> /// Output value of the device for the given cycle /// </summary> /// <param name="cycle">Zero-based program cycle number</param> /// <returns></returns> public static LabeledValue <long?> OutputCalc(int cycle) { var label = "Out:"; var aluout = DFBState.GetCySimulatorPrivateField <long?>(cycle, "aluout"); if (aluout != null) { var r = new LabeledValue <long?>(label); r.Value = aluout; r.FormattedValue = r.Value.HasValue ? FormatValue(VALUE_WIDTH, (int)r.Value) : ""; return(r); } else { return(NullLabeledValue <long?>(label)); } }
/// <summary> /// Output value of the device for the given cycle /// </summary> /// <param name="cycle">Zero-based program cycle number</param> /// <returns></returns> public static LabeledValue <long?> OutputCalc(int cycle) { var label = "Out:"; var macacc = DFBState.GetCySimulatorPrivateField <long?>(cycle, "MACacc"); if (macacc != null) { int maclower = Convert.ToInt32(macacc >> 23); var r = new LabeledValue <long?>("Out:"); r.Value = maclower; r.FormattedValue = r.Value.HasValue ? FormatValue(VALUE_WIDTH, r.Value) : ""; return(r); } else { return(NullLabeledValue <long?>(label)); } }
/// <summary> /// Output value of the device for the given cycle /// </summary> /// <param name="bankID">BankID of the device</param> /// <param name="cycle">Zero-based program cycle number</param> /// <returns></returns> public static LabeledValue <long?> OutputCalc(Bank bankID, int cycle) { var label = "Out:"; // reg var field = bankID == Bank.Bank_A ? "Aacc" : "Bacc"; var reg_reg = DFBState.GetCySimulatorPrivateField <int?>(cycle, field); if (reg_reg != null) { var r = new LabeledValue <long?>(label); r.Value = reg_reg.Value; r.FormattedValue = r.Value.HasValue ? FormatHex(VALUE_WIDTH, r.Value) : ""; return(r); } else { return(NullLabeledValue <long?>(label)); } }
/// <summary> /// Output value of the device for the given cycle /// </summary> /// <param name="bankID">BankID of the device</param> /// <param name="cycle">Zero-based program cycle number</param> /// <returns></returns> public static LabeledValue <long?> OutputCalc(Bank bankID, int cycle) { var label = "Out:"; var field = bankID == DFBStateModel.Bank.Bank_A ? "a1mux" : "b1mux"; var val = DFBState.GetCySimulatorPrivateField <long?>(cycle, field); if (val != null && val.HasValue) { var r = new LabeledValue <long?>(label); r.Value = val.Value; r.FormattedValue = r.Value.HasValue ? FormatValue(VALUE_WIDTH, r.Value) : ""; return(r); } else { return(NullLabeledValue <long?>(label)); } }
/// <summary> /// Output value of the device for the given cycle /// </summary> /// <param name="cycle">Zero-based program cycle number</param> /// <returns></returns> public static LabeledValue <long?> OutputCalc(int cycle) { var label = "Out:"; if (cycle - PIPELINE_DELAY < 0) { return(NullLabeledValue <long?>(label)); } var val = DFBState.GetCySimulatorPrivateField <long?>(cycle, "shift"); if (val != null && val.HasValue) { var r = new LabeledValue <long?>(label); r.Value = val.Value; r.FormattedValue = r.Value.HasValue ? FormatValue(VALUE_WIDTH, r.Value) : ""; return(r); } else { return(NullLabeledValue <long?>(label)); } }
/// <summary> /// Create a new instance of this device for the given cycle /// </summary> /// <param name="cycle">Zero-based program cycle number</param> public MACModel(int cycle) : base(Bank.NotApplicable, cycle, VALUE_WIDTH, 0, PIPELINE_DELAY) { // name name = DevicePort.MAC.ToString(); // instructions instructions.Add(ActiveInstr(cycle)); // [t-2] instructions.Add(ActiveInstr(cycle - 1)); // [t-1] instructions.Add(ActiveInstr(cycle - 2)); // [now] // connectionInputs connectionInputs = Connections(cycle); // output output = OutputCalc(cycle); // pipelineItems pipelineItems = new List <PipelineItem>(); for (int i = 0; i < instructions.Count; i++) { var instr = instructions[i]; long? aluValue = null; long? a = null; long? b = null; string outputFormula = null; int? accum = null; switch (instr) { case "loadalu": if (i > 0) { // Adds the previous ALU output (from the shifter) to the product and starts a new accumulation. aluValue = DFBState.GetCySimulatorPrivateField <long?>(cycle - i + 1, "aluout"); a = DFBState.GetCySimulatorPrivateField <long?>(cycle - i + 1, "a2mux"); b = DFBState.GetCySimulatorPrivateField <long?>(cycle - i + 1, "b2mux"); if (i == PIPELINE_DELAY) { outputFormula = "a * b + [Prev ALU]"; } } break; case "clra": if (i > 0) { // Clears the accumulator and stores the current product a = DFBState.GetCySimulatorPrivateField <long?>(cycle - i + 1, "a2mux"); b = DFBState.GetCySimulatorPrivateField <long?>(cycle - i + 1, "b2mux"); if (i == PIPELINE_DELAY) { accum = 0; outputFormula = "a * b"; } } break; case "hold": if (i > 0) { // Holds the value in the accumulator from the previous cycle. No multiply if (i == PIPELINE_DELAY) { accum = Convert.ToInt32(OutputCalc(cycle - i + 1).Value); outputFormula = "Accum"; } } break; case "macc": if (i > 0) { // Multiplies the values on mux2 of side A and side B. // Adds the product to the current value of the accumulator. a = DFBState.GetCySimulatorPrivateField <long?>(cycle - i + 1, "a2mux"); b = DFBState.GetCySimulatorPrivateField <long?>(cycle - i + 1, "b2mux"); if (i == PIPELINE_DELAY) { accum = Convert.ToInt32(OutputCalc(cycle - i + 1).Value); outputFormula = "a * b + Accum"; } } break; } var pipelineItem = new PipelineItem(); var lvAluValue = new LabeledValue <long?>("Prev ALU:"); lvAluValue.Value = aluValue.HasValue ? aluValue.Value : (long?)null; lvAluValue.FormattedValue = FormatValue(VALUE_WIDTH, lvAluValue.Value); pipelineItem.AluValue = lvAluValue; var lvA = new LabeledValue <long?>("a:"); lvA.Value = a.HasValue ? a.Value : (long?)null; lvA.FormattedValue = FormatValue(VALUE_WIDTH, lvA.Value); pipelineItem.A = lvA; var lvB = new LabeledValue <long?>("b:"); lvB.Value = b.HasValue ? b.Value : (long?)null; lvB.FormattedValue = FormatValue(VALUE_WIDTH, lvB.Value); pipelineItem.B = lvB; var lvOutputFormula = new LabeledValue <string>("Formula:"); lvOutputFormula.Value = outputFormula; lvOutputFormula.FormattedValue = outputFormula; pipelineItem.OutputFormula = lvOutputFormula; var lvAccum = new LabeledValue <int?>("Accum:"); lvAccum.Value = accum.HasValue ? accum.Value : (int?)null; lvAccum.FormattedValue = FormatValue(VALUE_WIDTH, lvAccum.Value); pipelineItem.Accumulator = lvAccum; pipelineItems.Add(pipelineItem); } }
/// <summary> /// Builds a list of PipelineItems /// </summary> /// <param name="cycle">Zero-based program cycle number</param> /// <param name="instructions">Instructions for pipeline</param> /// <returns></returns> private static List <PipelineItem> BuildPipelineItems(int cycle, List <string> instructions) { var pipelineItems = new List <PipelineItem>(); for (int i = 0; i < instructions.Count; i++) { var instr = instructions[i]; long? inputA = null; long? inputB = null; DevicePort?inputASource = null; DevicePort?inputBSource = null; string outputFormula = null; if (i > 0) { switch (instr ?? "") { case "set0": outputFormula = "0"; break; case "set1": outputFormula = "1"; break; case "seta": inputA = Mux3Model.OutputCalc(Bank.Bank_A, cycle - i + 1).Value; inputASource = DevicePort.Mux_3A; outputFormula = "A"; break; case "setb": inputB = Mux3Model.OutputCalc(Bank.Bank_B, cycle - i + 1).Value; inputBSource = DevicePort.Mux_3B; outputFormula = "B"; break; case "nega": inputA = Mux3Model.OutputCalc(Bank.Bank_A, cycle - i + 1).Value; inputASource = DevicePort.Mux_3A; outputFormula = "-A"; break; case "negb": inputB = Mux3Model.OutputCalc(Bank.Bank_B, cycle - i + 1).Value; inputBSource = DevicePort.Mux_3B; outputFormula = "-B"; break; case "passrama": inputA = DataRamModel.OutputCalc(Bank.Bank_A, cycle - i + 1).Value; inputASource = DevicePort.DataRam_A; outputFormula = "Ram A"; break; case "passramb": inputB = DataRamModel.OutputCalc(Bank.Bank_B, cycle - i + 1).Value; inputBSource = DevicePort.DataRam_B; outputFormula = "Ram B"; break; case "add": inputA = Mux3Model.OutputCalc(Bank.Bank_A, cycle - i + 1).Value; inputASource = DevicePort.Mux_3A; inputB = Mux3Model.OutputCalc(Bank.Bank_B, cycle - i + 1).Value; inputBSource = DevicePort.Mux_3B; outputFormula = "A+B"; break; case "tdeca": inputA = Mux3Model.OutputCalc(Bank.Bank_A, cycle - i + 1).Value; inputASource = DevicePort.Mux_3A; outputFormula = "A-1"; break; case "suba": inputA = Mux3Model.OutputCalc(Bank.Bank_A, cycle - i + 1).Value; inputASource = DevicePort.Mux_3A; inputB = Mux3Model.OutputCalc(Bank.Bank_B, cycle - i + 1).Value; inputBSource = DevicePort.Mux_3B; outputFormula = "B-A"; break; case "subb": inputA = Mux3Model.OutputCalc(Bank.Bank_A, cycle - i + 1).Value; inputASource = DevicePort.Mux_3A; inputB = Mux3Model.OutputCalc(Bank.Bank_B, cycle - i + 1).Value; inputBSource = DevicePort.Mux_3B; outputFormula = "A-B"; break; case "absa": inputA = Mux3Model.OutputCalc(Bank.Bank_A, cycle - i + 1).Value; inputASource = DevicePort.Mux_3A; outputFormula = "abs(A)"; break; case "absb": inputB = Mux3Model.OutputCalc(Bank.Bank_B, cycle - i + 1).Value; inputBSource = DevicePort.Mux_3B; outputFormula = "abs(B)"; break; case "addabsa": inputA = Mux3Model.OutputCalc(Bank.Bank_A, cycle - i + 1).Value; inputASource = DevicePort.Mux_3A; inputB = Mux3Model.OutputCalc(Bank.Bank_B, cycle - i + 1).Value; inputBSource = DevicePort.Mux_3B; outputFormula = "abs(A)+B"; break; case "addabsb": inputA = Mux3Model.OutputCalc(Bank.Bank_A, cycle - i + 1).Value; inputASource = DevicePort.Mux_3A; inputB = Mux3Model.OutputCalc(Bank.Bank_B, cycle - i + 1).Value; inputBSource = DevicePort.Mux_3B; outputFormula = "A+abs(B)"; break; case "hold": outputFormula = "ALU Hold"; break; case "englobals": outputFormula = ""; break; case "ensatrnd": outputFormula = ""; break; case "ensem": outputFormula = ""; break; case "setsem": outputFormula = ""; break; case "clearsem": outputFormula = ""; break; case "tsuba": inputA = Mux3Model.OutputCalc(Bank.Bank_A, cycle - i + 1).Value; inputASource = DevicePort.Mux_3A; inputB = Mux3Model.OutputCalc(Bank.Bank_B, cycle - i + 1).Value; inputBSource = DevicePort.Mux_3B; outputFormula = "B-A thr"; break; case "tsubb": inputA = Mux3Model.OutputCalc(Bank.Bank_A, cycle - i + 1).Value; inputASource = DevicePort.Mux_3A; inputB = Mux3Model.OutputCalc(Bank.Bank_B, cycle - i + 1).Value; inputBSource = DevicePort.Mux_3B; outputFormula = "A-B thr"; break; case "taddabsa": inputA = Mux3Model.OutputCalc(Bank.Bank_A, cycle - i + 1).Value; inputASource = DevicePort.Mux_3A; inputB = Mux3Model.OutputCalc(Bank.Bank_B, cycle - i + 1).Value; inputBSource = DevicePort.Mux_3B; outputFormula = "A+abs(B) thr"; break; case "taddabsb": inputA = Mux3Model.OutputCalc(Bank.Bank_A, cycle - i + 1).Value; inputASource = DevicePort.Mux_3A; inputB = Mux3Model.OutputCalc(Bank.Bank_B, cycle - i + 1).Value; inputBSource = DevicePort.Mux_3B; outputFormula = "A+abs(B) thr"; break; case "sqlcmp": inputA = Mux3Model.OutputCalc(Bank.Bank_A, cycle - i + 1).Value; inputASource = DevicePort.Mux_3A; outputFormula = "A -> sqlcmp"; break; case "sqlcnt": inputA = Mux3Model.OutputCalc(Bank.Bank_A, cycle - i + 1).Value; inputASource = DevicePort.Mux_3A; outputFormula = "A>>16 -> sqcval"; break; case "sqa": inputA = Mux3Model.OutputCalc(Bank.Bank_A, cycle - i + 1).Value; inputASource = DevicePort.Mux_3A; outputFormula = "Squelch(A)"; break; case "sqb": inputB = Mux3Model.OutputCalc(Bank.Bank_B, cycle - i + 1).Value; inputBSource = DevicePort.Mux_3B; outputFormula = "Squelch(B)"; break; } } var pipelineItem = new PipelineItem(); var lvA = new LabeledValue <long?>("In A:"); lvA.Value = inputA.HasValue ? inputA.Value : (long?)null; lvA.FormattedValue = FormatValue(VALUE_WIDTH, lvA.Value); pipelineItem.InputA = lvA; var lvB = new LabeledValue <long?>("In B:"); lvB.Value = inputB.HasValue ? inputB.Value : (long?)null; lvB.FormattedValue = FormatValue(VALUE_WIDTH, lvB.Value); pipelineItem.InputB = lvB; var lvASrc = new LabeledValue <DevicePort?>("Src A:"); lvASrc.Value = inputASource == DevicePort.Default ? (DevicePort?)null : inputASource; lvASrc.FormattedValue = lvASrc.Value.ToString(); pipelineItem.InputASource = lvASrc; var lvBSrc = new LabeledValue <DevicePort?>("Src B:"); lvBSrc.Value = inputBSource == DevicePort.Default ? (DevicePort?)null : inputBSource; lvBSrc.FormattedValue = lvBSrc.Value.ToString(); pipelineItem.InputBSource = lvBSrc; var lvOutputFormula = new LabeledValue <string>("Equation:"); lvOutputFormula.Value = outputFormula; lvOutputFormula.FormattedValue = outputFormula; pipelineItem.OutputFormula = lvOutputFormula; pipelineItems.Add(pipelineItem); } return(pipelineItems); }
/// <summary> /// Input to the 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="input0">First input</param> /// <param name="input0src">First input source</param> /// <param name="input1">Second input</param> /// <param name="input1src">Second input source</param> private static void InputCalc(Bank bankID, int cycle, out LabeledValue <long?> input0, out LabeledValue <DevicePort?> input0src, out LabeledValue <long?> input1, out LabeledValue <DevicePort?> input1src) { var valLabel = "In:"; var srcLabel = "Src:"; input0 = new LabeledValue <long?>(valLabel); input1 = new LabeledValue <long?>(valLabel); input0src = new LabeledValue <DevicePort?>(srcLabel); input1src = new LabeledValue <DevicePort?>(srcLabel); // Input latching occurs as follows (variant pipeline): // Pipeline [t-1] [now] // Cycle cycle cycle-1 // dmux(_r_, _r_) ->ram in output-> // dmux(__, __) ->mux1in & output-> var ramSource = bankID == Bank.Bank_A ? DevicePort.DataRam_A : DevicePort.DataRam_B; var mux1Source = bankID == Bank.Bank_A ? DevicePort.Mux_1A : DevicePort.Mux_1B; // Get [now] / cycle-1 input values var instr1 = InstrForCycle(bankID, cycle - 1); switch (instr1) { // These inputs latched from data ram in [t-1] case "bra": case "sra": case "brm": case "srm": input1.Value = DataRamModel.OutputCalc(bankID, cycle - 1).Value; input1.FormattedValue = FormatValue(VALUE_WIDTH, input1.Value); input1src.Value = ramSource; input1src.FormattedValue = input1src.Value.ToString(); break; // These inputs latch from mux1 [now] case "ba": case "sa": case "bm": case "sm": input1.Value = Mux1Model.OutputCalc(bankID, cycle).Value; input1.FormattedValue = FormatValue(VALUE_WIDTH, input1.Value); input1src.Value = mux1Source; input1src.FormattedValue = input1src.Value.ToString(); break; } // Get [t-1] / cycle input values var instr0 = InstrForCycle(bankID, cycle); switch (instr0) { case "bra": case "sra": case "brm": case "srm": input0.Value = DataRamModel.OutputCalc(bankID, cycle).Value; input0.FormattedValue = FormatValue(VALUE_WIDTH, input0.Value); input0src.Value = ramSource; input0src.FormattedValue = input0src.Value.ToString(); break; // no op: case "ba": case "sa": case "bm": case "sm": 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> public Mux3Model(Bank bankID, int cycle) : base(bankID, cycle, VALUE_WIDTH, 0, PIPELINE_DELAY) { // name name = bankID == Bank.Bank_A ? DevicePort.Mux_3A.ToString() : DevicePort.Mux_3B.ToString(); // instructions instructions.Add(InstrForCycle(bankID, cycle)); instructions.Add(InstrForCycle(bankID, cycle - 1)); // connectionInputs connectionInputs = Connections(bankID, cycle); // output output = OutputCalc(bankID, cycle); // pipelineItems pipelineItems = new List <PipelineItem>(); for (int i = 0; i < instructions.Count; i++) { var instr = instructions[i]; DevicePort activeInput = DevicePort.Default; long? activeValue = null; if (i == 1) { 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 activeInput = bankID == Bank.Bank_A ? DevicePort.Mux_2A : DevicePort.Mux_2B; activeValue = Mux2Model.OutputCalc(bankID, cycle).Value; break; case "brm": // Bus to RAM, to MAC case "srm": // Shifter to RAM to MAC activeInput = DevicePort.MAC; activeValue = MACModel.OutputCalc(cycle).Value; break; default: break; } } var pipelineItem = new PipelineItem(); var lvValue = new LabeledValue <long?>("In:"); lvValue.Value = activeValue.HasValue ? activeValue.Value : (long?)null; lvValue.FormattedValue = FormatValue(VALUE_WIDTH, lvValue.Value); pipelineItem.Input = lvValue; var lvValueSrc = new LabeledValue <DevicePort?>("Src:"); lvValueSrc.Value = activeInput == DevicePort.Default ? (DevicePort?)null : activeInput; lvValueSrc.FormattedValue = lvValueSrc.Value.ToString(); pipelineItem.InputSource = lvValueSrc; PipelineItems.Add(pipelineItem); } }