As you, my dear reader, may have already noticed from my previous posts, I am currently teaching a course on how computers work for first year students. Very high level, simplified stuff since there’s only ten hours of lectures and ten hours of exercises for this.
One course exercise is about logic gates. After the lectures on the topic, students use the Digital Logic Sim tool to design some simple logic gates. Starting from AND and NOT gates, they build a NAND (the universal) gate and then OR, NOR and XOR gates using these gates in the project of theirs.

After this, students design two gates handling a byte (eight bits). Logic gate (or chip) ISZERO, checking if a byte has a zero eight bit integer value. ISEVEN gate checks if a byte is an even number.
Finally, they combine these two gates to check if the value in the byte is an even number and greater than zero. In the end they will meet the question whether the byte is actually signed or unsigned. Since then they need to take into account if the most significant bit (msb) is zero or one. In a signed byte, the msb value of 1 means the value of the byte is actually a negative integer.
Anyhows, in one of the lectures I mention that:
Anything that can be implement in hardware, can also be implement in software. And anything that is implementable in software, can also be implemented in hardware.
So a thought popped in my head out of nowhere: “Should I implement a demonstration in C that actually does implement these gates in software, starting from the boolean operators && and !, not using the ones already in the language?”
Of course I had to do that. Useless and fun. Suits me just fine.
Logic gates AND and NOT are quite simple to implement using boolean operators of C:
bool and(bool x, bool y) {
return x && y;
}
bool not(bool x) {
return !x;
}
Then implementing the NAND gate using NOT and AND:
bool nand(bool x, bool y) {
return not(and(x, y));
}
And the final example here, the OR operator implemented using three NANDS (compare this to the image of the OR gate above):
bool or(bool x, bool y) {
return nand(nand(x, x), nand(y, y));
}
The rest you can find following the link above, including a demo app in gates.c and an output file from the app.
What I would like to change in the implementation is to have two implementations of the ISZERO gate, since signed and unsigned bytes should implement this gate differently.
But enough of these uselessnesses. For today, at least.





