A binary and ternary logic simulation library in C++
I've always had a passing interest in ternary logic, but never the drive to do so since there I didn't have a practical reason for it.
I still don't.
But upon learning the binary and ternary combinatorial circuits work in similar ways I was curious.
And curiousity is a good enough reason to break out the C++ compiler, build some obtuse-looking templates, and start building!
It's simple enough, with all the logic held in gates/gate.h. TBH, as much work went into the test suite as went into the logic. The meant I was able to improve the library, utilising C++ features like operator overloads, implicit conversions, etc, and re-test after each build. Not so much a time saver, but a great safety net.
You can create gates with:
using namespace Gate;
TernaryGateNand2 nand(PinTernary::TrueState, PinTernary::UndeterminedState);
std::cout << nand.getResult().asString();
Implicit conversions exist for the basic gates so the line:
std::cout << nand.getResult().asString();
can be written:
std::cout << nand;
More complex gates and circuits can be generated by chaining, as you'd expected. One example can be found in the Xor2 code:
Xor2(const pintype &a, const pintype &b) {
Nand2<pintype> nand1(a, b);
Nand2<pintype> nand2(a, nand1);
Nand2<pintype> nand3(nand1, b);
m_Result = Nand2<pintype>(nand2, nand3);
}
and full adder:
FullAdder(const pintype &a, const pintype &b, const pintype &carry) {
HalfAdder<pintype> ha1(a, b);
HalfAdder<pintype> ha2(ha1.getSum(), carry);
m_Result = ha2;
Or2<pintype> or(ha1.getCarry(), ha2.getCarry());
m_Carry = or;
}
In addition to the test suite, it also features methods to display truth tables.
There are two main parts: pins and gates.
Pins indicate the number of states that an interconnect has. 2 for binary, 3 for ternary.
Gates have a number of pin inputs, and (potentially) a different number of pin outputs.