protected virtual void GetOutput(bool forceUpdate) { int loops = 0; UniqueQueue <Guid> queue = new UniqueQueue <Guid>(); UniqueQueue <Guid> outputQueue = new UniqueQueue <Guid>(); // This is a new update loops so make sure gates and chips are not dirty foreach (Chip chip in Chips) { chip.Dirty.SetAll(false); } foreach (Gate gate in Gates) { gate.SetClean(); } // Update input wires foreach (Wire wire in WireDict[ID]) { if (forceUpdate || FirstRun || (OldInput[wire.FromIndex] != Input[wire.FromIndex])) { if (wire.IsChip) { Chip chip = Chips[wire.CircuitIndex]; chip.SetInputBit(wire.ToIndex, Input[wire.FromIndex] ^ wire.InvertValue); chip.Update(forceUpdate); if (forceUpdate || FirstRun || chip.IsDirty()) { queue.Enqueue(chip.ID); } } else { Gate gate = Gates[wire.CircuitIndex]; gate.SetInputBit(wire.ToIndex, Input[wire.FromIndex] ^ wire.InvertValue); gate.Update(ScrubOutput); if (forceUpdate || FirstRun || gate.IsDirty()) { queue.Enqueue(gate.ID); } } } } //Update internal components while (queue.Count > 0) { //Stop infinite loops from continuing loops++; if (loops >= 100) { Debug.Log("Infinite loop, breaking"); return; } Guid guid = queue.Dequeue(); BitArray FromValues; BitArray FromDirty; // The output of the previous gate Gate previousGate = FindGate(guid); if (previousGate != null) { FromValues = new BitArray(1, previousGate.Output); FromDirty = new BitArray(1, previousGate.IsDirty()); } else { Chip c = FindChip(guid); FromValues = c.Output; FromDirty = c.Dirty; } foreach (Wire wire in WireDict[guid]) { if (wire.IsChip) { if (wire.CircuitIndex == -1) { outputQueue.Enqueue(guid); Output[wire.ToIndex] = FromValues[wire.FromIndex] ^ wire.InvertValue; //Debug.Log("Updated output: " + wire.ToIndex); } else if (FromDirty[wire.FromIndex]) { Chip chip = Chips[wire.CircuitIndex]; chip.SetInputBit(wire.ToIndex, FromValues[wire.FromIndex] ^ wire.InvertValue); chip.Update(false); //Debug.Log("Updated chip: " + (char)(Chips.FindIndex(x => x.ID == guid) + 65) + "->" + (char)(wire.CircuitIndex + 65)); if (chip.IsDirty()) { queue.Enqueue(chip.ID); } } } else if (FromDirty[wire.FromIndex]) { Gate gate = Gates[wire.CircuitIndex]; gate.SetInputBit(wire.ToIndex, FromValues[wire.FromIndex] ^ wire.InvertValue); gate.Update(ScrubOutput); //Debug.Log("Updated gate: " + (char)(wire.CircuitIndex + 65)); if (forceUpdate || FirstRun || gate.IsDirty()) { queue.Enqueue(gate.ID); } } } } //Update output wires while (outputQueue.Count > 0) { Guid guid = outputQueue.Dequeue(); BitArray FromValues; Gate gate = FindGate(guid); if (gate != null) { FromValues = new BitArray(1, gate.Output); } else { FromValues = FindChip(guid).Output; } foreach (Wire wire in WireDict[guid]) { if (wire.IsChip && wire.CircuitIndex == -1) { Output[wire.ToIndex] = FromValues[wire.FromIndex] ^ wire.InvertValue; } } } }
public D_Register_4Bit() : base(10, 4) { // Output control Gate gateA = AddGateIndexed(new ANDGate()); // Data Enable Gate gateB = AddGateIndexed(new ANDGate()); Gate gateC = AddGateIndexed(new NotGate()); Gate gateD = AddGateIndexed(new NotGate()); Gate gateE = AddGateIndexed(new NotGate()); // Q1 Gate gateF = AddGateIndexed(new ANDGate()); Gate gateG = AddGateIndexed(new ANDGate()); Gate gateR = AddGateIndexed(new ORGate()); Chip chipH = AddChipIndexed(new D_FlipFlop_Re()); Gate gateV = AddGateIndexed(new TriBufferGate()); // Q2 Gate gateI = AddGateIndexed(new ANDGate()); Gate gateJ = AddGateIndexed(new ANDGate()); Gate gateS = AddGateIndexed(new ORGate()); Chip chipK = AddChipIndexed(new D_FlipFlop_Re()); Gate gateW = AddGateIndexed(new TriBufferGate()); // Q3 Gate gateL = AddGateIndexed(new ANDGate()); Gate gateM = AddGateIndexed(new ANDGate()); Gate gateT = AddGateIndexed(new ORGate()); Chip chipN = AddChipIndexed(new D_FlipFlop_Re()); Gate gateX = AddGateIndexed(new TriBufferGate()); // Q4 Gate gateO = AddGateIndexed(new ANDGate()); Gate gateP = AddGateIndexed(new ANDGate()); Gate gateU = AddGateIndexed(new ORGate()); Chip chipQ = AddChipIndexed(new D_FlipFlop_Re()); Gate gateY = AddGateIndexed(new TriBufferGate()); // Output control AddInputWire(new Wire(0, 0, gateA, true)); AddInputWire(new Wire(1, 1, gateA, true)); AddWire(gateA.ID, new Wire(0, 1, gateV)); AddWire(gateA.ID, new Wire(0, 1, gateW)); AddWire(gateA.ID, new Wire(0, 1, gateX)); AddWire(gateA.ID, new Wire(0, 1, gateY)); // Data Enable AddInputWire(new Wire(3, 0, gateB, true)); AddInputWire(new Wire(4, 1, gateB, true)); AddWire(gateB, new Wire(0, 0, gateC)); AddWire(gateB, new Wire(0, 1, gateG)); AddWire(gateB, new Wire(0, 1, gateJ)); AddWire(gateB, new Wire(0, 1, gateM)); AddWire(gateB, new Wire(0, 1, gateP)); AddWire(gateC, new Wire(0, 1, gateF)); AddWire(gateC, new Wire(0, 1, gateI)); AddWire(gateC, new Wire(0, 1, gateL)); AddWire(gateC, new Wire(0, 1, gateO)); // CLK AddInputWire(new Wire(6, 0, gateD)); AddWire(gateD, new Wire(0, 0, chipH, true)); AddWire(gateD, new Wire(0, 0, chipK, true)); AddWire(gateD, new Wire(0, 0, chipN, true)); AddWire(gateD, new Wire(0, 0, chipQ, true)); // CLR AddInputWire(new Wire(9, 0, gateE)); AddWire(gateE, new Wire(0, 2, chipH, true)); AddWire(gateE, new Wire(0, 2, chipK, true)); AddWire(gateE, new Wire(0, 2, chipN, true)); AddWire(gateE, new Wire(0, 2, chipQ, true)); // Q1 AddInputWire(new Wire(2, 0, gateG)); AddWire(gateF, new Wire(0, 0, gateR)); AddWire(gateG, new Wire(0, 1, gateR)); AddWire(gateR, new Wire(0, 1, chipH)); AddWire(chipH, new Wire(0, 0, gateF)); AddWire(chipH, new Wire(0, 0, gateV)); AddWire(gateV, new Wire(0, 0, -1, true)); // Q2 AddInputWire(new Wire(5, 0, gateJ)); AddWire(gateI, new Wire(0, 0, gateS)); AddWire(gateJ, new Wire(0, 1, gateS)); AddWire(gateS, new Wire(0, 1, chipK)); AddWire(chipK, new Wire(0, 0, gateI)); AddWire(chipK, new Wire(0, 0, gateW)); AddWire(gateW, new Wire(0, 1, -1, true)); // Q3 AddInputWire(new Wire(7, 0, gateM)); AddWire(gateL, new Wire(0, 0, gateT)); AddWire(gateM, new Wire(0, 1, gateT)); AddWire(gateT, new Wire(0, 1, chipN)); AddWire(chipN, new Wire(0, 0, gateL)); AddWire(chipN, new Wire(0, 0, gateX)); AddWire(gateX, new Wire(0, 2, -1, true)); // Q4 AddInputWire(new Wire(8, 0, gateP)); AddWire(gateO, new Wire(0, 0, gateU)); AddWire(gateP, new Wire(0, 1, gateU)); AddWire(gateU, new Wire(0, 1, chipQ)); AddWire(chipQ, new Wire(0, 0, gateO)); AddWire(chipQ, new Wire(0, 0, gateY)); AddWire(gateY, new Wire(0, 3, -1, true)); }
protected void AddWire(Chip chip, Wire wire) { AddWire(chip.ID, wire); }
protected void AddWires(Chip chip, Wire[] wires) { AddWires(chip.ID, wires); }
protected int AddChip(Chip chip) { return(AddChipIndexed(chip).index); }
/// <summary> /// OE = 0, /// RCLK = 1, /// SRCLR = 2, /// SRCLK = 3, /// SER = 4 /// </summary> public Shift_Register_8Bit() : base(6, 9) { KeepDirty = true; // Shift Latches Chip S1 = AddChipIndexed(new D_FlipFlop_Re()); Chip S2 = AddChipIndexed(new D_FlipFlop_Re()); Chip S3 = AddChipIndexed(new D_FlipFlop_Re()); Chip S4 = AddChipIndexed(new D_FlipFlop_Re()); Chip S5 = AddChipIndexed(new D_FlipFlop_Re()); Chip S6 = AddChipIndexed(new D_FlipFlop_Re()); Chip S7 = AddChipIndexed(new D_FlipFlop_Re()); Chip S8 = AddChipIndexed(new D_FlipFlop_Re()); // Register Latches Chip R1 = AddChipIndexed(new D_FlipFlop_Re()); Chip R2 = AddChipIndexed(new D_FlipFlop_Re()); Chip R3 = AddChipIndexed(new D_FlipFlop_Re()); Chip R4 = AddChipIndexed(new D_FlipFlop_Re()); Chip R5 = AddChipIndexed(new D_FlipFlop_Re()); Chip R6 = AddChipIndexed(new D_FlipFlop_Re()); Chip R7 = AddChipIndexed(new D_FlipFlop_Re()); Chip R8 = AddChipIndexed(new D_FlipFlop_Re()); // Output Enables Gate O1 = AddGateIndexed(new ANDGate()); Gate O2 = AddGateIndexed(new ANDGate()); Gate O3 = AddGateIndexed(new ANDGate()); Gate O4 = AddGateIndexed(new ANDGate()); Gate O5 = AddGateIndexed(new ANDGate()); Gate O6 = AddGateIndexed(new ANDGate()); Gate O7 = AddGateIndexed(new ANDGate()); Gate O8 = AddGateIndexed(new ANDGate()); // INs Gate OE = AddGateIndexed(new NotGate()); Gate RCLK = AddGateIndexed(new BufferGate()); // SER AddInputWire(new Wire(4, 1, S1)); // SRCLR AddInputWires(Wire.Create(2, 2, true, S1, S2, S3, S4, S5, S6, S7, S8)); AddInputWires(Wire.Create(5, 3, false, S1, S2, S3, S4, S5, S6, S7, S8, R1, R2, R3, R4, R5, R6, R7, R8)); // SRCLK AddInputWires(Wire.Create(3, 0, false, S1, S2, S3, S4, S5, S6, S7, S8)); // RCLK AddInputWire(new Wire(1, 0, RCLK)); AddWires(RCLK, Wire.Create(0, 0, false, R1, R2, R3, R4, R5, R6, R7, R8)); // OE AddInputWire(new Wire(0, 0, OE)); AddWires(OE, Wire.Create(0, 1, false, O1, O2, O3, O4, O5, O6, O7, O8)); // OEs AddWire(O1, new Wire(0, 0, -1, true)); AddWire(O2, new Wire(0, 1, -1, true)); AddWire(O3, new Wire(0, 2, -1, true)); AddWire(O4, new Wire(0, 3, -1, true)); AddWire(O5, new Wire(0, 4, -1, true)); AddWire(O6, new Wire(0, 5, -1, true)); AddWire(O7, new Wire(0, 6, -1, true)); AddWire(O8, new Wire(0, 7, -1, true)); //AddWire(S1, new Wire(0, 0, -1, true)); //AddWire(S2, new Wire(0, 1, -1, true)); //AddWire(S3, new Wire(0, 2, -1, true)); //AddWire(S4, new Wire(0, 3, -1, true)); //AddWire(S5, new Wire(0, 4, -1, true)); //AddWire(S6, new Wire(0, 5, -1, true)); //AddWire(S7, new Wire(0, 6, -1, true)); //AddWire(S8, new Wire(0, 7, -1, true)); //SR->R AddWires(S1, Wire.Create(0, 1, false, R1, S2)); AddWires(S2, Wire.Create(0, 1, false, R2, S3)); AddWires(S3, Wire.Create(0, 1, false, R3, S4)); AddWires(S4, Wire.Create(0, 1, false, R4, S5)); AddWires(S5, Wire.Create(0, 1, false, R5, S6)); AddWires(S6, Wire.Create(0, 1, false, R6, S7)); AddWires(S7, Wire.Create(0, 1, false, R7, S8)); AddWire(S8, new Wire(0, 1, R8)); AddWire(S8, new Wire(1, 8, -1, true)); //R->OE AddWire(R1, new Wire(0, 0, O1)); AddWire(R2, new Wire(0, 0, O2)); AddWire(R3, new Wire(0, 0, O3)); AddWire(R4, new Wire(0, 0, O4)); AddWire(R5, new Wire(0, 0, O5)); AddWire(R6, new Wire(0, 0, O6)); AddWire(R7, new Wire(0, 0, O7)); AddWire(R8, new Wire(0, 0, O8)); }
protected int AddChip(Chip chip) { Chips.Add(chip); return(Chips.Count - 1); }
protected virtual void GetOutput(bool forceUpdate) { int loops = 0; Queue <Guid> queue = new Queue <Guid>(); foreach (Chip chip in Chips) { chip.Dirty.SetAll(false); } foreach (Wire wire in WireDict[ID]) { if (wire.IsChip) { Chip chip = Chips[wire.CircuitIndex]; chip.SetInputBit(wire.ToIndex, Input[wire.FromIndex]); chip.Update(forceUpdate); if (forceUpdate || GetCardinality(chip.Dirty) > 0) { if (!queue.Contains(chip.ID)) { queue.Enqueue(chip.ID); } } } else { Gate gate = Gates[wire.CircuitIndex]; gate.SetInputBit(wire.ToIndex, Input[wire.FromIndex]); gate.Update(); if (forceUpdate || gate.IsDirty()) { if (!queue.Contains(gate.ID)) { queue.Enqueue(gate.ID); } } } } while (queue.Count > 0) { //Stop infinite loops from continuing loops++; if (loops >= 1000) { Console.WriteLine("Infinite loop, breaking"); return; } Guid guid = queue.Dequeue(); BitArray FromValues; int findIndex = Gates.FindIndex(x => x.ID == guid); if (findIndex != -1) { FromValues = new BitArray(1, Gates[findIndex].Output); } else { FromValues = Chips.Find(x => x.ID == guid).Output; } foreach (Wire wire in WireDict[guid]) { if (wire.IsChip) { if (wire.CircuitIndex == -1) { Output[wire.ToIndex] = FromValues[wire.FromIndex]; } else { Chip chip = Chips[wire.CircuitIndex]; if (chip.Dirty[wire.FromIndex]) { chip.SetInputBit(wire.ToIndex, FromValues[wire.FromIndex]); chip.Update(forceUpdate); if (forceUpdate || GetCardinality(Dirty) > 0) { if (!queue.Contains(chip.ID)) { queue.Enqueue(chip.ID); } } } } } else { Gate gate = Gates[wire.CircuitIndex]; gate.SetInputBit(wire.ToIndex, FromValues[wire.FromIndex]); gate.Update(); if (forceUpdate || gate.IsDirty()) { if (!queue.Contains(gate.ID)) { queue.Enqueue(gate.ID); } } } } } }
protected virtual void GetOutput(bool forceUpdate) { int loops = 0; Queue <Guid> queue = new Queue <Guid>(); Queue <Guid> outputQueue = new Queue <Guid>(); foreach (Chip chip in Chips) { chip.Dirty.SetAll(false); } foreach (Gate gate in Gates) { gate.SetClean(); } // Update input wires foreach (Wire wire in WireDict[ID]) { if (forceUpdate || FirstRun || (OldInput[wire.FromIndex] != Input[wire.FromIndex])) { if (wire.IsChip) { Chip chip = Chips[wire.CircuitIndex]; chip.SetInputBit(wire.ToIndex, Input[wire.FromIndex] ^ wire.invertValue); chip.Update(forceUpdate); //Debug.Log("Updated chip: " + (char)(wire.CircuitIndex + 65)); if (forceUpdate || FirstRun || GetCardinality(chip.Dirty) > 0) { if (!queue.Contains(chip.ID)) { queue.Enqueue(chip.ID); } } } else { Gate gate = Gates[wire.CircuitIndex]; gate.SetInputBit(wire.ToIndex, Input[wire.FromIndex] ^ wire.invertValue); gate.Update(ScrubOutput); //Debug.Log("Updated gate: " + (char)(wire.CircuitIndex + 65)); if (forceUpdate || FirstRun || gate.IsDirty()) { if (!queue.Contains(gate.ID)) { queue.Enqueue(gate.ID); } } } } } //Update internal components while (queue.Count > 0) { //Stop infinite loops from continuing loops++; if (loops >= 100) { Debug.Log("Infinite loop, breaking"); return; } Guid guid = queue.Dequeue(); BitArray FromValues; BitArray FromDirty; // Find a better way to get values int findIndex = Gates.FindIndex(x => x.ID == guid); if (findIndex != -1) { FromValues = new BitArray(1, Gates[findIndex].Output); FromDirty = new BitArray(1, Gates[findIndex].IsDirty()); } else { Chip c = Chips.Find(x => x.ID == guid); FromValues = c.Output; FromDirty = c.Dirty; } foreach (Wire wire in WireDict[guid]) { if (wire.IsChip) { if (wire.CircuitIndex == -1) { if (!outputQueue.Contains(guid)) { outputQueue.Enqueue(guid); } Output[wire.ToIndex] = FromValues[wire.FromIndex] ^ wire.invertValue; //Debug.Log("Updated output: " + wire.ToIndex); } else if (FromDirty[wire.FromIndex]) { Chip chip = Chips[wire.CircuitIndex]; chip.SetInputBit(wire.ToIndex, FromValues[wire.FromIndex] ^ wire.invertValue); chip.Update(false); //Debug.Log("Updated chip: " + (char)(Chips.FindIndex(x => x.ID == guid) + 65) + "->" + (char)(wire.CircuitIndex + 65)); if (GetCardinality(chip.Dirty) > 0) { if (!queue.Contains(chip.ID)) { queue.Enqueue(chip.ID); } } } } else if (FromDirty[wire.FromIndex]) { Gate gate = Gates[wire.CircuitIndex]; gate.SetInputBit(wire.ToIndex, FromValues[wire.FromIndex] ^ wire.invertValue); gate.Update(ScrubOutput); //Debug.Log("Updated gate: " + (char)(wire.CircuitIndex + 65)); if (forceUpdate || FirstRun || gate.IsDirty()) { if (!queue.Contains(gate.ID)) { queue.Enqueue(gate.ID); } } } } } //Update output wires while (outputQueue.Count > 0) { Guid guid = outputQueue.Dequeue(); BitArray FromValues; int findIndex = Gates.FindIndex(x => x.ID == guid); if (findIndex != -1) { FromValues = new BitArray(1, Gates[findIndex].Output); } else { Chip c = Chips.Find(x => x.ID == guid); FromValues = c.Output; } foreach (Wire wire in WireDict[guid]) { if (wire.IsChip && wire.CircuitIndex == -1) { Output[wire.ToIndex] = FromValues[wire.FromIndex] ^ wire.invertValue; } } } }