I was implementing the ALU from the specs given in my The Elements of Computing systems book. I am stuck on only one problem. How do I find if a given number is zero or not. One thing I can do is or every bit in the bus, and then apply a not gate on that. But there has to be some other elegant solution.
There's simply no way around ORing all the bits, as unsatisfying as that may seem. However, you are not restricted to two input gates in silicon either. You can build a 4-input NOR gate in CMOS logic by putting 4 series p-type transistors in the pullup network and 4 parallel n-type transistors in the pulldown network. That reduces the depth of your tree topology and therefore your propagation delay. You can only take that theory so far though before the cumulative voltage drop across the series transistors makes the pull-up not pull-up enough to be a "1"... four is a good rule of thumb if I remember correctly.
The typical solution with 8 bit machines was that the ALU would produce a number of 'flag' bits that would represent the outcome of the most recent operation. While it would be possible to have any number of flag bits around (i.e., you could have a 'Z' flag for every register in your CPU), it's usually the thing you've just computed that you're most interesting in, so it makes a certain degree of sense to do it that way.
Some of those old CPUs would automatically set flag bits for almost every data move, while others would require you to stick a specific 'compare' instruction in your code if you just suddenly need to know if a certain register was zero. And whether you provide a zero check for every register or just for what's just been computed, there really is no simpler way to check for "is this word zero" than to just OR all the bits together.
I found this post for the same reason as the OP - trying to implement zr for the ALU in The Elements of Computing course. zr is 1 if the ALU output is 0, 0 otherwise
The course provides a hardware simulator and a range of built-in predefined chips.
One of the built-in chips is an 8-way OR gate. An 8-way NOR gate is not provided. The ALU is 16-bit. I split the 16-bit signal into two 8-bit buses using a multiplexer. Each of these go to a separate 8-way Or gate. The outputs from each of the 8-way Or gates goes to a separate Not gate. The outputs from the two Not gates goes to an And gate. The output of the And gate is the function zr.
I tested this using the course Hardware Simulator v2.5.
We need to check if our output Array contains only 0 bits. If number that Array is representing is 0 then it's not Negative nor Positive in a math sense. So you can check last bit of output Array if it's equal to 0. Because in 2's compliment all negative numbers will have 1 as a last MSB if MSB==0 then it's not negative.
To check if it's not positive either we can NEGATE output Array and ADD it to itself that will get us array full of 1's. Now we will add output Array to this full of 1's array. If output Array did contain any 1 bit it will generate carry that eventually will cause overflow and set MSB of the result to 0. If output Array did contain only 0's result will remain array full of 1's. And MSB will remain 1 too.
So now we
AND (NOT(output Array[MSB]), ADD[MSB](output Array, ADD(output Array,NEGATE(output Array)))
Do that to check if number represented by output Array is nor positive nor negative. Mb tho to use multiway OR for all 16 bits is easier and better.