コード例 #1
0
ファイル: Scheme.cs プロジェクト: just806me/logicsim
        public ElementValue[,] CalculateTable()
        {
#if DEBUG
            Log.Method(
                new MethodInfo {
                Name = "Scheme::CalculateTable", Type = typeof(ElementValue[, ])
            }
                );
#endif

            var inputs_count_pow2         = Convert.ToInt32(Math.Pow(2, _inputs.Count));
            var inputs_plus_outputs_count = _inputs.Count + _outputs.Count;
            var table = new ElementValue[inputs_count_pow2, inputs_plus_outputs_count];

            for (int i = 0; i < inputs_count_pow2; i++)
            {
                SetCurrentState(i);
                CalculateForCurrentState();

                for (int j = 0; j < inputs_plus_outputs_count; j++)
                {
                    if (j < _inputs.Count)
                    {
                        table[i, j] = _inputs[j].Value;
                    }
                    else
                    {
                        table[i, j] = _outputs[j - _inputs.Count].Value;
                    }
                }
            }

            return(table);
        }
コード例 #2
0
ファイル: Scheme.cs プロジェクト: just806me/logicsim
        public void CalculateForCurrentState()
        {
#if DEBUG
            Log.Method(
                new MethodInfo {
                Name = "Scheme::CalculateForCurrentState", Type = typeof(void)
            }
                );
#endif

            foreach (var layer in _componentLayers)
            {
                foreach (var component in layer)
                {
                    var values = new ElementValue[component.Input.Count];
                    for (int i = 0; i < component.Input.Count; i++)
                    {
                        values[i] = GetElementValue(component.Input.ElementAt(i));
                    }

                    component.Calculate(values);
                }
            }

            foreach (var output in _outputs)
            {
                output.Value = GetElementValue(output.Input);
            }
        }
コード例 #3
0
        public Component(string name, ComponentType type, IEnumerable <string> input)
        {
#if DEBUG
            Log.Method(
                new MethodInfo {
                Name = "Component::ctor", Type = typeof(Component)
            },
                new ArgumentInfo {
                Name = nameof(name), Type = name.GetType(), Data = name
            },
                new ArgumentInfo {
                Name = nameof(type), Type = type.GetType(), Data = type
            },
                new ArgumentInfo {
                Name = nameof(input), Type = input.GetType(), Data = input
            }
                );
#endif

            Name   = name;
            Type   = type;
            _input = input.ToList();
            Value  = new ElementValue();
        }
コード例 #4
0
ファイル: Scheme.cs プロジェクト: just806me/logicsim
        public void SetCurrentState(int stateNumber)
        {
#if DEBUG
            Log.Method(
                new MethodInfo {
                Name = "Scheme::SetCurrentState", Type = typeof(void)
            },
                new ArgumentInfo {
                Name = nameof(stateNumber), Type = stateNumber.GetType(), Data = stateNumber
            }
                );
#endif

            #region arguments check

            if (stateNumber >= Convert.ToInt32(Math.Pow(2, _inputs.Count)) || stateNumber < 0)
            {
                throw new ArgumentOutOfRangeException(
                          nameof(stateNumber),
                          $"The state number must be greater than or equal to 0 and less than 2 in power of the count of the inputs ({Convert.ToInt32(Math.Pow(2, _inputs.Count))})."
                          );
            }

            #endregion

            var state = new ElementValue[_inputs.Count];

            for (int i = 0; i < state.Length; i++)
            {
                state[state.Length - i - 1]       = new ElementValue();
                state[state.Length - i - 1].Value = ((stateNumber >> i) & 1) == 1;
                state[state.Length - i - 1].Delay = 0;
            }

            SetCurrentState(state);
        }
コード例 #5
0
        public void Calculate(ElementValue[] inputValues)
        {
#if DEBUG
            Log.Method(
                new MethodInfo {
                Name = "Component::Calculate", Type = typeof(void)
            },
                new ArgumentInfo {
                Name = nameof(inputValues), Type = inputValues.GetType(), Data = inputValues
            }
                );
#endif

            #region arguments check

            if (inputValues == null)
            {
                throw new ArgumentNullException(nameof(inputValues));
            }

            #endregion

            ElementValue tmp = new ElementValue();
            switch (Type)
            {
            case ComponentType.And:
                tmp.Value = true;
                foreach (var inputValue in inputValues)
                {
                    tmp.Value = tmp.Value.Value && inputValue.Value.Value;
                }

                if (tmp.Value == true)
                {
                    tmp.Delay = inputValues.Max(x => x.Delay) + 1;
                }
                else
                {
                    tmp.Delay = inputValues.Where(x => x.Value == false).Min(y => y.Delay) + 1;
                }
                break;

            case ComponentType.AndNot:
                tmp.Value = true;
                foreach (var inputValue in inputValues)
                {
                    tmp.Value = tmp.Value.Value && inputValue.Value.Value;
                }

                if (tmp.Value == true)
                {
                    tmp.Delay = inputValues.Max(x => x.Delay) + 1;
                }
                else
                {
                    tmp.Delay = inputValues.Where(x => x.Value == false).Min(y => y.Delay) + 1;
                }

                tmp.Value = !tmp.Value;
                break;

            case ComponentType.Or:
                tmp.Value = false;
                foreach (var inputValue in inputValues)
                {
                    tmp.Value = tmp.Value.Value || inputValue.Value.Value;
                }

                if (tmp.Value == true)
                {
                    tmp.Delay = inputValues.Where(x => x.Value == true).Min(x => x.Delay) + 1;
                }
                else
                {
                    tmp.Delay = inputValues.Max(y => y.Delay) + 1;
                }
                break;

            case ComponentType.OrNot:
                tmp.Value = false;
                foreach (var inputValue in inputValues)
                {
                    tmp.Value = tmp.Value.Value || inputValue.Value.Value;
                }

                if (tmp.Value == true)
                {
                    tmp.Delay = inputValues.Where(x => x.Value == true).Min(x => x.Delay) + 1;
                }
                else
                {
                    tmp.Delay = inputValues.Max(y => y.Delay) + 1;
                }

                tmp.Value = !tmp.Value;
                break;

            case ComponentType.Xor:
                tmp.Value = false;
                foreach (var inputValue in inputValues)
                {
                    tmp.Value = tmp.Value.Value ^ inputValue.Value.Value;
                }

                tmp.Delay = inputValues.Max(y => y.Delay) + 1;
                break;

            case ComponentType.XorNot:
                tmp.Value = false;
                foreach (var inputValue in inputValues)
                {
                    tmp.Value = tmp.Value.Value ^ inputValue.Value.Value;
                }

                tmp.Delay = inputValues.Max(y => y.Delay) + 1;

                tmp.Value = !tmp.Value;
                break;

            case ComponentType.Not:
                tmp.Value = !inputValues[0].Value.Value;
                tmp.Delay = inputValues[0].Delay + 1;
                break;

            default:
                break;
            }
            Value = tmp;
        }
コード例 #6
0
ファイル: Scheme.cs プロジェクト: just806me/logicsim
        public Bitmap DrawTimeDiagram(uint[,] InputDelays, uint TimeLimit)
        {
#if DEBUG
            Log.Method(
                new MethodInfo {
                Name = "Scheme::DrawTimeDiagram", Type = typeof(Bitmap)
            },
                new ArgumentInfo {
                Name = nameof(InputDelays), Type = InputDelays.GetType(), Data = InputDelays
            },
                new ArgumentInfo {
                Name = nameof(TimeLimit), Type = InputDelays.GetType(), Data = TimeLimit
            }
                );
#endif

            var rows = _inputs.Select(x => x.Name).Concat(_outputs.Select(x => x.Name)).ToArray();

            int ImgRows        = _inputs.Count + _outputs.Count;
            int ImgStepColumns = (int)(TimeLimit);
            int ImgWidth       = fieldFirstWidth + ImgStepColumns * fieldStepWidth;
            int ImgHeight      = fieldHeight * ImgRows;

            var bt = new Bitmap(ImgWidth, ImgHeight);
            var gr = Graphics.FromImage(bt);

            gr.FillRectangle(Brushes.White, 0, 0, ImgWidth, ImgHeight);

            Pen gridPen = new Pen(Color.Black);
            gridPen.DashStyle = DashStyle.Solid;

            for (int gor = 1; gor <= ImgRows; gor++)
            {
                gr.DrawLine(gridPen, 0, gor * fieldHeight, ImgWidth, gor * fieldHeight);
                gr.DrawString(rows[gor - 1], new Font("Arial", 10), Brushes.Black,
                              new RectangleF(5, gor * fieldHeight - 20, fieldFirstWidth, 20));
            }

            gridPen.Width = 2;
            gr.DrawLine(gridPen, fieldFirstWidth, 0, fieldFirstWidth, ImgHeight);
            gridPen.Width = 1;

            gridPen.Color     = Color.Gray;
            gridPen.DashStyle = DashStyle.Dot;
            for (int ver = 0; ver <= ImgStepColumns; ver++)
            {
                gr.DrawLine(gridPen, fieldFirstWidth + ver * fieldStepWidth, 0,
                            fieldFirstWidth + ver * fieldStepWidth, ImgHeight);
            }

            gridPen.Color     = Color.Red;
            gridPen.Width     = 2;
            gridPen.DashStyle = DashStyle.Solid;


            uint[]         LastInputChangeTick = new uint[_inputs.Count];
            ElementValue[] state = new ElementValue[_inputs.Count];
            for (int i = 0; i < _inputs.Count; i++)
            {
                state[i] = new ElementValue()
                {
                    Delay = 0, Value = false
                }
            }
            ;

            bool[,] inputValues         = new bool[_inputs.Count, TimeLimit];
            ElementValue[,] outputValue = new ElementValue[_outputs.Count, TimeLimit];

            for (uint CurrentTick = 0; CurrentTick < TimeLimit; CurrentTick++)
            {
                for (int i = 0; i < _inputs.Count; i++)
                {
                    if (CurrentTick - LastInputChangeTick[i] >= InputDelays[i, state[i].Value.Value ? 1 : 0])
                    {
                        LastInputChangeTick[i] = CurrentTick;
                        state[i].Value         = !state[i].Value;
                    }

                    inputValues[i, CurrentTick] = state[i].Value.Value;
                }

                SetCurrentState(state);
                CalculateForCurrentState();

                for (int i = 0; i < _outputs.Count; i++)
                {
                    outputValue[i, CurrentTick] = _outputs[i].Value;
                }
            }

            for (int rw = 0; rw < ImgRows; rw++)
            {
                List <Point> sigLv = new List <Point>();
                if (rw < _inputs.Count)
                {
                    sigLv.Add(new Point(fieldFirstWidth,
                                        (int)((rw + (inputValues[rw, 0] ? .3f : 1f)) * fieldHeight)));
                    sigLv.Add(new Point(fieldFirstWidth + fieldStepWidth,
                                        (int)((rw + (inputValues[rw, 0] ? .3f : 1f)) * fieldHeight)));
                }
                else
                {
                    sigLv.Add(new Point(fieldFirstWidth,
                                        (int)((rw + (outputValue[rw - _inputs.Count, 0].Value.Value ? .3f : 1f)) * fieldHeight)));
                    sigLv.Add(new Point(fieldFirstWidth + fieldStepWidth,
                                        (int)((rw + (outputValue[rw - _inputs.Count, 0].Value.Value ? .3f : 1f)) * fieldHeight)));
                }

                for (int tick = 1; tick < TimeLimit; tick++)
                {
                    if (rw < _inputs.Count)
                    {
                        sigLv.Add(new Point(fieldFirstWidth + tick * fieldStepWidth,
                                            (int)((rw + (inputValues[rw, tick] ? .3f : 1f)) * fieldHeight)));
                        sigLv.Add(new Point(fieldFirstWidth + (tick + 1) * fieldStepWidth,
                                            (int)((rw + (inputValues[rw, tick] ? .3f : 1f)) * fieldHeight)));
                    }
                    else
                    {
                        if (outputValue[rw - _inputs.Count, tick - 1].Value.Value ^ outputValue[rw - _inputs.Count, tick].Value.Value)
                        {
                            int dx = (int)(fieldStepWidth * outputValue[rw - _inputs.Count, tick].Delay.Value / (_componentLayers.Count + 1));
                            sigLv.Add(new Point(fieldFirstWidth + tick * fieldStepWidth + dx,
                                                (int)((rw + (outputValue[rw - _inputs.Count, tick - 1].Value.Value ? .3f : 1f)) * fieldHeight)));                 // last

                            sigLv.Add(new Point(dx + fieldFirstWidth + tick * fieldStepWidth,
                                                (int)((rw + (outputValue[rw - _inputs.Count, tick].Value.Value ? .3f : 1f)) * fieldHeight)));
                            sigLv.Add(new Point(fieldFirstWidth + (tick + 1) * fieldStepWidth,
                                                (int)((rw + (outputValue[rw - _inputs.Count, tick].Value.Value ? .3f : 1f)) * fieldHeight)));
                        }
                        else
                        {
                            sigLv.Add(new Point(fieldFirstWidth + tick * fieldStepWidth,
                                                (int)((rw + (outputValue[rw - _inputs.Count, tick].Value.Value ? .3f : 1f)) * fieldHeight)));
                            sigLv.Add(new Point(fieldFirstWidth + (tick + 1) * fieldStepWidth,
                                                (int)((rw + (outputValue[rw - _inputs.Count, tick].Value.Value ? .3f : 1f)) * fieldHeight)));
                        }
                    }
                }

                gr.DrawLines(gridPen, sigLv.ToArray());
            }

            gr.Dispose();
            return(bt);
        }