This repository has been archived on 2026-05-02. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
CompuLogic/Assets/Scripts/Workspace/Gates/GateDefinitionList.cs
T
2020-12-22 19:11:55 +01:00

615 lines
15 KiB
C#
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
namespace CompuLogic.Workspace.Gates
{
#region 000 - Technical
internal class NoneGate : StatelessGateDefinition
{
public override string[] Inputs { get; } = new string[] { };
public override string[] Outputs { get; } = new string[] { };
internal override Func<InputState, OutputState> Function => (input) => new OutputState(0);
}
#endregion
#region 100 - I/O
internal class INGate : NoneGate { }
internal class OUTGate : NoneGate { }
internal class CLK1Gate : NoneGate { }
internal class CLK2Gate : NoneGate { }
internal class CLK3Gate : NoneGate { }
internal class CLK4Gate : NoneGate { }
#endregion
#region 200 - Basic
internal class BUFGate : StatelessGateDefinition
{
public override string[] Inputs { get; } = new string[] { "A" };
public override string[] Outputs { get; } = new string[] { "Q" };
internal override Func<InputState, OutputState> Function => (input) => new OutputState(input[0]);
}
internal class ANDGate : StatelessGateDefinition
{
public override string[] Inputs { get; } = new string[] { "A", "B" };
public override string[] Outputs { get; } = new string[] { "Q" };
internal override Func<InputState, OutputState> Function => (input) => new OutputState(input[0] && input[1]);
}
internal class ORGate : StatelessGateDefinition
{
public override string[] Inputs { get; } = new string[] { "A", "B" };
public override string[] Outputs { get; } = new string[] { "Q" };
internal override Func<InputState, OutputState> Function => (input) => new OutputState(input[0] || input[1]);
}
internal class XORGate : StatelessGateDefinition
{
public override string[] Inputs { get; } = new string[] { "A", "B" };
public override string[] Outputs { get; } = new string[] { "Q" };
internal override Func<InputState, OutputState> Function => (input) => new OutputState(input[0] ^ input[1]);
}
internal class NOTGate : StatelessGateDefinition
{
public override string[] Inputs { get; } = new string[] { "A" };
public override string[] Outputs { get; } = new string[] { "Q" };
internal override Func<InputState, OutputState> Function => (input) => new OutputState(!input[0]);
}
internal class NANDGate : StatelessGateDefinition
{
public override string[] Inputs { get; } = new string[] { "A", "B" };
public override string[] Outputs { get; } = new string[] { "Q" };
internal override Func<InputState, OutputState> Function => (input) => new OutputState(!(input[0] && input[1]));
}
internal class NORGate : StatelessGateDefinition
{
public override string[] Inputs { get; } = new string[] { "A", "B" };
public override string[] Outputs { get; } = new string[] { "Q" };
internal override Func<InputState, OutputState> Function => (input) => new OutputState(!(input[0] || input[1]));
}
internal class XNORGate : StatelessGateDefinition
{
public override string[] Inputs { get; } = new string[] { "A", "B" };
public override string[] Outputs { get; } = new string[] { "Q" };
internal override Func<InputState, OutputState> Function => (input) => new OutputState(!(input[0] ^ input[1]));
}
#endregion
#region 300 - Latches
internal class SRLatchGate : StatefulGateDefinition
{
public override string[] Inputs { get; } = new string[] { "S", "R" };
public override string[] Outputs { get; } = new string[] { "Q", "Q̅" };
private bool _q;
internal override Func<InputState, OutputState> Function => (input) =>
{
var s = input[0];
var r = input[1];
if (r) // reset
_q = false;
else if (s) // set
_q = true;
return new OutputState(_q, !_q);
};
}
internal class JKLatchGate : StatefulGateDefinition
{
public override string[] Inputs { get; } = new string[] { "J", "K" };
public override string[] Outputs { get; } = new string[] { "Q", "Q̅" };
private bool _q;
internal override Func<InputState, OutputState> Function => (input) =>
{
var j = input[0];
var k = input[1];
if (k && j) // flip
_q = !_q;
else if (k) // reset
_q = false;
else if (j) // set
_q = true;
return new OutputState(_q, !_q);
};
}
internal class DLatchGate : StatefulGateDefinition
{
public override string[] Inputs { get; } = new string[] { "D", "E" };
public override string[] Outputs { get; } = new string[] { "Q", "Q̅" };
private bool _q;
internal override Func<InputState, OutputState> Function => (input) =>
{
var d = input[0];
var e = input[1];
if (e) // set
_q = d;
return new OutputState(_q, !_q);
};
}
#endregion
#region 400 - Flip-Flops
internal class SRFlipFlopGate : StatefulGateDefinition
{
public override string[] Inputs { get; } = new string[] { "CLK", "S", "R" };
public override string[] Outputs { get; } = new string[] { "Q", "Q̅" };
private bool _q;
private bool _lastClk;
internal override Func<InputState, OutputState> Function => (input) =>
{
var clk = input[0];
var s = input[1];
var r = input[2];
if (clk && !_lastClk) // rising edge
if (r) // reset
_q = false;
else if (s) // set
_q = true;
_lastClk = clk;
return new OutputState(_q, !_q);
};
}
internal class JKFlipFlopGate : StatefulGateDefinition
{
public override string[] Inputs { get; } = new string[] { "CLK", "J", "K" };
public override string[] Outputs { get; } = new string[] { "Q", "Q̅" };
private bool _q;
private bool _lastClk;
internal override Func<InputState, OutputState> Function => (input) =>
{
var clk = input[0];
var j = input[1];
var k = input[2];
if (clk && !_lastClk) // rising edge
if (k && j) // flip
_q = !_q;
else if (k) // reset
_q = false;
else if (j) // set
_q = true;
_lastClk = clk;
return new OutputState(_q, !_q);
};
}
internal class DFlipFlopGate : StatefulGateDefinition
{
public override string[] Inputs { get; } = new string[] { "CLK", "D" };
public override string[] Outputs { get; } = new string[] { "Q", "Q̅" };
private bool _q;
private bool _lastClk;
internal override Func<InputState, OutputState> Function => (input) =>
{
var clk = input[0];
var d = input[1];
if (clk && !_lastClk) // rising edge
_q = d;
_lastClk = clk;
return new OutputState(_q, !_q);
};
}
internal class TFlipFlopGate : StatefulGateDefinition
{
public override string[] Inputs { get; } = new string[] { "CLK", "T" };
public override string[] Outputs { get; } = new string[] { "Q", "Q̅" };
private bool _q;
private bool _lastClk;
internal override Func<InputState, OutputState> Function => (input) =>
{
var clk = input[0];
var t = input[1];
if (clk && !_lastClk) // rising edge
if (t) // flip
_q = !_q;
_lastClk = clk;
return new OutputState(_q, !_q);
};
}
#endregion
#region 500 - Arithmetic
internal class HalfAddGate : StatelessGateDefinition
{
public override string[] Inputs { get; } = new string[] { "A", "B" };
public override string[] Outputs { get; } = new string[] { "S", "C" };
internal override Func<InputState, OutputState> Function => (input) =>
{
var a = input[0];
var b = input[1];
var s = a || b;
var c = a && b;
return new OutputState(s, c);
};
}
internal class FullAddGate : StatelessGateDefinition
{
public override string[] Inputs { get; } = new string[] { "A", "B", "Cɪ" };
public override string[] Outputs { get; } = new string[] { "S", "C" };
internal override Func<InputState, OutputState> Function => (input) =>
{
var a = input[0];
var b = input[1];
var ci = input[2];
var s = a || b || ci;
var co = a && b || a && ci || b && ci;
return new OutputState(s, co);
};
}
internal class HalfSubGate : StatelessGateDefinition
{
public override string[] Inputs { get; } = new string[] { "A", "B" };
public override string[] Outputs { get; } = new string[] { "S", "C" };
internal override Func<InputState, OutputState> Function => (input) =>
{
var a = input[0];
var b = input[1];
var s = a || b;
var c = !a && b;
return new OutputState(s, c);
};
}
internal class FullSubGate : StatelessGateDefinition
{
public override string[] Inputs { get; } = new string[] { "A", "B", "Cɪ" };
public override string[] Outputs { get; } = new string[] { "S", "C" };
internal override Func<InputState, OutputState> Function => (input) =>
{
var a = input[0];
var b = input[1];
var ci = input[2];
var s = a || b || ci;
var co = a && !b || a && !ci || b && ci;
return new OutputState(s, co);
};
}
#endregion
#region 600 - Data
internal class MuxGate : StatelessGateDefinition
{
public override string[] Inputs { get; } = new string[] { "E", "S", "D0", "D1" };
public override string[] Outputs { get; } = new string[] { "Y" };
internal override Func<InputState, OutputState> Function => (input) =>
{
var e = input[0];
var s = input[1];
var d0 = input[2];
var d1 = input[3];
var y = e && (!s && d0 || s && d1);
return new OutputState(y);
};
}
internal class DemuxGate : StatelessGateDefinition
{
public override string[] Inputs { get; } = new string[] { "E", "S", "D" };
public override string[] Outputs { get; } = new string[] { "Y0", "Y1" };
internal override Func<InputState, OutputState> Function => (input) =>
{
var e = input[0];
var s = input[1];
var d = input[2];
var y0 = e && !s && d;
var y1 = e && s && d;
return new OutputState(y0, y1);
};
}
internal class Mux2bGate : StatelessGateDefinition
{
public override string[] Inputs { get; } = new string[] { "E", "S0", "S1", "D0", "D1", "D2", "D3" };
public override string[] Outputs { get; } = new string[] { "Y" };
internal override Func<InputState, OutputState> Function => (input) =>
{
var e = input[0];
var s0 = input[1];
var s1 = input[2];
var d0 = input[3];
var d1 = input[4];
var d2 = input[5];
var d3 = input[6];
var y = e && (
!s0 && !s1 && d0 ||
s0 && !s1 && d1 ||
!s0 && s1 && d2 ||
s0 && s1 && d3
);
return new OutputState(y);
};
}
internal class Demux2bGate : StatelessGateDefinition
{
public override string[] Inputs { get; } = new string[] { "E", "S0", "S1", "D" };
public override string[] Outputs { get; } = new string[] { "Y0", "Y1", "Y2", "Y3" };
internal override Func<InputState, OutputState> Function => (input) =>
{
var e = input[0];
var s0 = input[1];
var s1 = input[2];
var d = input[3];
var y0 = e && !s0 && !s1 && d;
var y1 = e && s0 && !s1 && d;
var y2 = e && !s0 && s1 && d;
var y3 = e && s0 && s1 && d;
return new OutputState(y0, y1, y2, y3);
};
}
internal class Enc2b4bGate : StatelessGateDefinition
{
public override string[] Inputs { get; } = new string[] { "D0", "D1" };
public override string[] Outputs { get; } = new string[] { "Y0", "Y1", "Y2", "Y3" };
internal override Func<InputState, OutputState> Function => (input) =>
{
var d0 = input[0];
var d1 = input[1];
var y0 = !d0 && !d1;
var y1 = d0 && !d1;
var y2 = !d0 && d1;
var y3 = d0 && d1;
return new OutputState(y0, y1, y2, y3);
};
}
internal class Dec4b2bGate : StatelessGateDefinition
{
public override string[] Inputs { get; } = new string[] { "D0", "D1", "D2", "D3"};
public override string[] Outputs { get; } = new string[] { "Y0", "Y1" };
internal override Func<InputState, OutputState> Function => (input) =>
{
var d0 = input[0];
var d1 = input[1];
var d2 = input[2];
var d3 = input[3];
var y0 = d1 && !d2 || d3;
var y1 = d2 || d3;
return new OutputState(y0, y1);
};
}
#endregion
#region 700 - Registers
internal class SISO4bGate : StatefulGateDefinition
{
public override string[] Inputs { get; } = new string[] { "CLK", "D" };
public override string[] Outputs { get; } = new string[] { "Q" };
private bool _q0;
private bool _q1;
private bool _q2;
private bool _q3;
private bool _lastClk;
internal override Func<InputState, OutputState> Function => (input) =>
{
var clk = input[0];
var d = input[1];
if (clk && !_lastClk) // rising edge
{
_q3 = _q2;
_q2 = _q1;
_q1 = _q0;
_q0 = d;
}
_lastClk = clk;
return new OutputState(_q3);
};
}
internal class SIPO4bGate : StatefulGateDefinition
{
public override string[] Inputs { get; } = new string[] { "CLK", "D" };
public override string[] Outputs { get; } = new string[] { "Q0", "Q1", "Q2", "Q3" };
private bool _q0;
private bool _q1;
private bool _q2;
private bool _q3;
private bool _lastClk;
internal override Func<InputState, OutputState> Function => (input) =>
{
var clk = input[0];
var d = input[1];
if (clk && !_lastClk) // rising edge
{
_q3 = _q2;
_q2 = _q1;
_q1 = _q0;
_q0 = d;
}
_lastClk = clk;
return new OutputState(_q0, _q1, _q2, _q3);
};
}
internal class PIPO4bGate : StatefulGateDefinition
{
public override string[] Inputs { get; } = new string[] { "CLK", "D0", "D1", "D2", "D3" };
public override string[] Outputs { get; } = new string[] { "Q0", "Q1", "Q2", "Q3" };
private bool _q0;
private bool _q1;
private bool _q2;
private bool _q3;
private bool _lastClk;
internal override Func<InputState, OutputState> Function => (input) =>
{
var clk = input[0];
var d0 = input[1];
var d1 = input[2];
var d2 = input[3];
var d3 = input[4];
if (clk && !_lastClk) // rising edge
{
_q3 = d3;
_q2 = d2;
_q1 = d1;
_q0 = d0;
}
_lastClk = clk;
return new OutputState(_q0, _q1, _q2, _q3);
};
}
#endregion
#region 800 - Counters
internal class Counter2bGate : StatefulGateDefinition
{
public override string[] Inputs { get; } = new string[] { "CLK", "RST" };
public override string[] Outputs { get; } = new string[] { "Q0", "Q1" };
private bool _q0;
private bool _q1;
private bool _lastClk;
internal override Func<InputState, OutputState> Function => (input) =>
{
var clk = input[0];
var rst = input[1];
if (clk && !_lastClk) // rising edge
{
if (rst)
{
_q0 = false;
_q1 = false;
}
else
{
_q1 = _q0 ^ _q1;
_q0 = !_q0;
}
}
_lastClk = clk;
return new OutputState(_q0, _q1);
};
}
internal class Counter4bGate : StatefulGateDefinition
{
public override string[] Inputs { get; } = new string[] { "CLK", "RST" };
public override string[] Outputs { get; } = new string[] { "Q0", "Q1", "Q2", "Q3" };
private bool _q0;
private bool _q1;
private bool _q2;
private bool _q3;
private bool _lastClk;
internal override Func<InputState, OutputState> Function => (input) =>
{
var clk = input[0];
var rst = input[1];
if (clk && !_lastClk) // rising edge
{
if (rst)
{
_q0 = false;
_q1 = false;
_q2 = false;
_q3 = false;
}
else
{
_q3 = (_q3 || _q2 && _q1 && _q0) && !(_q3 && _q2 && _q1 && _q0);
_q2 = (_q2 || _q1 && _q0) && !(_q2 && _q1 && _q0);
_q1 = _q0 ^ _q1;
_q0 = !_q0;
}
}
_lastClk = clk;
return new OutputState(_q0, _q1, _q2, _q3);
};
}
#endregion
}