I'm currently learning C# and WPF, and i'm trying to simulate a circuit of logic gates and flipflops, but it won't work.
Could someone please show me a possible way to achive this? (maybe a simple similar application?)
What i have tried so far:
Class:
public class GateBase
{
public Type Type { get; set; }
public GateBase Input1 { get; set; }
public GateBase Input2 { get; set; }
public List<GateBase> Outputs { get; set; }
public bool Evaluated { get; set; }
public bool Value { get; set; }
public bool FlipFlop { get; set; }
public GateBase(Type type = Type.OFF, Gate input1 = null, Gate input2 = null)
{
Type = type;
Input1 = input1;
Input2 = input2;
Outputs = new List<GateBase>();
Evaluated = false;
Value = false;
FlipFlop = false;
switch (Type)
{
case Type.T:
case Type.D:
case Type.SR:
case Type.JK: FlipFlop = true; break;
}
}
public bool Evaluate()
{
if (!Evaluated)
{
bool input1 = false;
bool input2 = false;
if (Input1 != null)
{
if (Input1.FlipFlop)
input1 = Input1.Value;
else
input1 = Input1.Evaluate();
}
if (Input2 != null)
{
if (Input2.FlipFlop)
input2 = Input2.Value;
else
input2 = Input2.Evaluate();
}
switch (Type)
{
case Type.OFF:
Value = false; break;
case Type.ON:
Value = true; break;
case Type.OUT:
Value = input1; break;
case Type.CON:
Value = input1; break;
case Type.NOT:
Value = input1; break;
case Type.AND:
Value = input1 & input2; break;
case Type.OR:
Value = input1 | input2; break;
case Type.XOR:
Value = input1 ^ input2; break;
case Type.NAND:
Value = !(input1 & input2); break;
case Type.NOR:
Value = !(input1 | input2); break;
case Type.XNOR:
Value = !(input1 ^ input2); break;
case Type.D:
Value = input1; break;
case Type.T:
Value = input1 ? Value : !Value; break;
case Type.SR:
Value = (input1 ^ input2) ? Value : Value; break;
case Type.JK:
Value = (input1 ^ input2) ? input1 : (input1 & input2) ? !Value : Value; break;
default: Value = false; break;
}
}
Evaluated = true;
return Value;
}
public void ResetOutputs()
{
Evaluated = false;
foreach (Gate gate in Outputs)
{
if(!gate.FlipFlop)
{
gate.ResetOutputs();
}
}
}
}
Loop:
- Update all logic gates
- Update all flipflops and unevaluate outputs of each flipflop (if they are not a flipflop)
public List<GateBase> Gates { get; set; }
while (loop)
{
bool evaluating = true;
while (evaluating)
{
evaluating = false;
foreach (Gate gate in Gates)
{
switch (gate.Type)
{
case Model.Type.ON:
case Model.Type.OFF:
gate.Value = gate.Evaluate();
break;
case Model.Type.OUT:
case Model.Type.CON:
case Model.Type.NOT:
if (gate.Input1 != null && (gate.Input1.Evaluated || gate.Input1.FlipFlop))
{
gate.Value = gate.Evaluate();
}
break;
case Model.Type.AND:
case Model.Type.OR:
case Model.Type.XOR:
case Model.Type.NAND:
case Model.Type.NOR:
case Model.Type.XNOR:
if (gate.Input1 != null && gate.Input2 != null)
{
if ((gate.Input1.Evaluated || gate.Input1.FlipFlop) && (gate.Input2.Evaluated || gate.Input2.FlipFlop))
{
gate.Value = gate.Evaluate();
}
}
else
{
evaluating = true;
}
break;
}
}
}
evaluating = true;
while (evaluating)
{
evaluating = false;
foreach (Gate gate in Gates)
{
switch (gate.Type)
{
case Model.Type.D:
case Model.Type.T:
if (gate.Input1 != null && (gate.Input1.Evaluated || gate.Input1.FlipFlop))
{
gate.Value = gate.Evaluate();
gate.ResetOutputs();
}
else
{
evaluating = true;
}
break;
case Model.Type.SR:
case Model.Type.JK:
if (gate.Input1 != null && gate.Input2 != null)
{
if ((gate.Input1.Evaluated || gate.Input1.FlipFlop) && (gate.Input2.Evaluated || gate.Input2.FlipFlop))
{
gate.Value = gate.Evaluate();
gate.ResetOutputs();
}
}
else
{
evaluating = true;
}
break;
}
}
}
}
Problem:
If i'm using the JK-flipflop the results are not as expected. (but the T-flipflop works fine)
Here a link to the solution: Solution on GitHub
Thank You!
You have no break for your switch cases inside the while loop, so if the case is Model.Type.AND it will fall all the way down to the Model.Type.XNOR and I assume this isn't intended. This might be your problem (or at least a part of it).
Just to give you an idea, this small example will output "no break". x = 3 will output the string from default.
You can read more about the traditional switch here: switch C# reference from Micrsoft