/// <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 connections to device /// </summary> /// <param name="bankID">BankID of the device</param> /// <param name="cycle">Zero-based program cycle number</param> /// <returns></returns> private static List <Connection> Connections(Bank bankID, int cycle) { var conns = new List <Connection>(); DevicePort mux1PortOut = DevicePort.Default; DevicePort dataRamPortOut = DevicePort.Default; DevicePort mux2Mux1PortIn = DevicePort.Default; DevicePort mux2DataRamPortIn = DevicePort.Default; PortStatus mux1PortOut_Stat; PortStatus dataRamPortOut_Stat; PortStatus mux2Mux1PortIn_Stat; PortStatus mux2DataRamPortIn_Stat; var mux1_label = Mux1Model.OutputCalc(bankID, cycle).FormattedValue; var dataRam_label = DataRamModel.OutputCalc(bankID, cycle).FormattedValue; InputsUsed(bankID, cycle, out mux1PortOut_Stat, out dataRamPortOut_Stat, out mux2Mux1PortIn_Stat, out mux2DataRamPortIn_Stat); switch (bankID) { case Bank.Bank_A: mux1PortOut = DevicePort.Mux_1A; dataRamPortOut = DevicePort.DataRam_A; mux2Mux1PortIn = DevicePort.Mux_2A; mux2DataRamPortIn = DevicePort.Mux_2A; break; case Bank.Bank_B: mux1PortOut = DevicePort.Mux_1B; dataRamPortOut = DevicePort.DataRam_B; mux2Mux1PortIn = DevicePort.Mux_2B; mux2DataRamPortIn = DevicePort.Mux_2B; break; default: break; } conns.Add(new Connection( BusType.Data, mux1PortOut, mux1PortOut_Stat, mux1_label, null, mux2Mux1PortIn, mux2Mux1PortIn_Stat)); conns.Add(new Connection( BusType.Data, dataRamPortOut, dataRamPortOut_Stat, dataRam_label, null, mux2DataRamPortIn, mux2DataRamPortIn_Stat)); return(conns); }
/// <summary> /// Input connections to device /// </summary> /// <param name="cycle">Zero-based program cycle number</param> /// <param name="pipelineItems"></param> /// <returns></returns> private static List <Connection> Connections(int cycle, List <PipelineItem> pipelineItems) { var conns = new List <Connection>(); var instr = Instr(cycle - PIPELINE_DELAY); PortStatus statMux3A_ALUIn; PortStatus statMux3B_ALUIn; PortStatus statRamA_ALUIn; PortStatus statRamB_ALUIn; statMux3A_ALUIn = pipelineItems[1].InputASource.Value == DevicePort.Mux_3A ? PortStatus.Active : PortStatus.Inactive; statMux3B_ALUIn = pipelineItems[1].InputBSource.Value == DevicePort.Mux_3B ? PortStatus.Active : PortStatus.Inactive; statRamA_ALUIn = pipelineItems[1].InputASource.Value == DevicePort.DataRam_A ? PortStatus.Active : PortStatus.Inactive; statRamB_ALUIn = pipelineItems[1].InputBSource.Value == DevicePort.DataRam_B ? PortStatus.Active : PortStatus.Inactive; var activeLabel_Mux_3A = Mux3Model.OutputCalc(Bank.Bank_A, cycle).FormattedValue; var activeLabel_Mux_3B = Mux3Model.OutputCalc(Bank.Bank_B, cycle).FormattedValue; var activeLabel_Ram_A = DataRamModel.OutputCalc(Bank.Bank_A, cycle).FormattedValue; var activeLabel_Ram_B = DataRamModel.OutputCalc(Bank.Bank_B, cycle).FormattedValue; // Show ALU inputs based on connection // non-banked conns.Add(new Connection( BusType.Data, DevicePort.Mux_3A, PortStatus.Active, activeLabel_Mux_3A, null, DevicePort.ALU, statMux3A_ALUIn)); conns.Add(new Connection( BusType.Data, DevicePort.Mux_3B, PortStatus.Active, activeLabel_Mux_3B, null, DevicePort.ALU, statMux3B_ALUIn)); conns.Add(new Connection( BusType.Data, DevicePort.DataRam_A, PortStatus.Active, activeLabel_Ram_A, null, DevicePort.ALU, statRamA_ALUIn)); conns.Add(new Connection( BusType.Data, DevicePort.DataRam_B, PortStatus.Active, activeLabel_Ram_B, null, DevicePort.ALU, statRamB_ALUIn)); return(conns); }
/// <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; } }