首页 > 解决方案 > 如何模拟逻辑门和触发器的电路

问题描述

我目前正在学习 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 型触发器工作正常)


这里是解决方案的链接:GitHub 上的解决方案

谢谢你!

标签: c#wpfcircuitflip-flop

解决方案


在 while 循环中,您的 switch 案例没有中断,所以如果案例是Model.Type.AND,它将一直下降到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;
        }
    }
}

您可以在此处阅读有关传统开关的更多信息: 来自 Micrsoft 的 switch C# 参考


推荐阅读