如何模拟逻辑门和触发器电路

问题描述

我目前正在学习 C# 和 WPF,我正在尝试模拟逻辑门和触发器电路,但它不起作用。

有人可以告诉我一种可能的方法来实现这一目标吗? (也许是一个简单的类似应用程序?)

到目前为止我尝试过的:


班级:

    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();
                }
            }
        }
    }

循环:

  • 更新所有逻辑门
  • 更新所有触发器并取消评估每个触发器的输出(如果它们不是触发器)
     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;

                        }
                    }
                }
            }

问题:

如果我使用的是 JK 触发器,则结果与预期不同。 (但 T 型触发器工作正常)


这里是解决方案的链接Solution on GitHub

谢谢!

解决方法

while 循环内的 switch case 没有中断,因此如果 case 是 Model.Type.AND,它将一直下降到 Model.Type.AND em>Model.Type.XNOR 我认为这不是故意的。这可能是您的问题(或至少是其中的一部分)。

只是给你一个想法,这个小例子将输出“no break”。 x = 3 将输出默认字符串。

using System;

public class Program
{
    public static void Main()
    {
        int x = 1;
        switch(x){
            case 0:
                Console.WriteLine("Break");
                break;
            case 1:
            case 2:
                Console.WriteLine("no break");
                break;
            case 3:
            default:
                Console.WriteLine("End!");
                break;
        }
    }
}

您可以在此处阅读有关传统开关的更多信息: switch C# reference from Micrsoft

,

现在我解决了一个问题,它比以前工作得更好。 (我在更新所有触发器之前重置门)

但它仍然没有 100% 正确...

循环中的变化:

// new list
List<Gate> gatesToResetOutputs = new List<Gate>();

while(loop)
{
    while(evaluating gates)
    {
        ...
    }

    while(evaluating flipflops)
    {
        ...
        // instead of
        gate.ResetOutputs();
    
        // replace with
        gatesToResetOutputs.Add(gate);
        ...
    }

    // and at the end of the loop
    foreach(Gate gate in gatesToResetOutputs)
    {
        gate.ResetOutputs();
    }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...