Thoughts on comparison circuits?

WBahn

Joined Mar 31, 2012
32,844
(A*B)' comes out to A'+B'
Combined with the other A we get:
A*(A' or B') => A*B'
(A*B')' => A' or B
(A' or B)' => A*B'
That's the first AAB expression. Took less than 5 minutes.
To get the hole thing, replace the first A in the first step with B and repeat.
If we did that for the ABB expression we'd get a simillar result:
(A*B)'*B => A'*B
(A'*B)' => A or B'
(A or B')' => A'*B

now together:
(A*B'*A'*B)' => A'or B or A or B'

A'or B or A or B' => true

So the logic circuit could be just a wire connected to +Vcc, or the fastest CMOS would be an inverter with the input tied to ground (only a pdelay at power on).

The whole thing took about 10 minutes but I haven't done this in a long time.
These days I would use software though to help avoid mistakes, and also check it before programming a ROM.

I actually had to do this in one project I had done for a company. We were developing a static switch and there were a lot of measurements to check before switching from one input to another. I did it all by hand with pen and paper (yikes) but that was many years ago. Now we have software.
I did use a program to generate the ROM programming though and we sent it to a service that programs the ROM's.

Since this resulted in a static output there would be nothing to program. If it resulted in say just A*B' we would have run through all the combinations with a program (Basic, C, etc.) and the output would be programmed into the associated address location.
Do it again, but this time spent fifteen minutes. ;)

It's easy to mess up Boolean manipulations, but that wasn't the point.

HINT: You inverted something and then, for some reason, went and inverted it again, yielding what you already had as a prior partial result.

Also, a LUT-based solution is off the table -- You said, "then choose the gates that those expressions represent."

My response is that this is easier said than done.

The reason is that Boolean expressions using AND, OR, and NOT are not good fits for expressions that represent minimal logic circuit implementations.

If you are just going to do a LUT, there's no reason to do the prior step of your suggested approach, which was, "you can then go on to simplify those expressions." Why bother to simply the expressions? Just write a program to walk through all of the combinations and generate the table that needs to be programmed into the LUT.

Plus, if the goal is to get the smallest and/or fastest possible implementation, the access time for a LUT has to be considered as well as the physical size that is going to be required to hold it. That might or might not result in the fasted implementation, but it is virtually guaranteed that it won't result in the smallest.
 

Thread Starter

xox

Joined Sep 8, 2017
936
This is far easier said than done in practice.

For instance, consider the following expression:

\(
Y = \overline{ \left( \overline{ \left( A \cdot \overline{ \left( A \cdot B \right) } \right) } \cdot \overline{ \left( \overline{ \left( A \cdot B \right) } \cdot B \right) } \right) }
\)

What would the simplified expression be and what gates does that simplified expression suggest for the smallest and fastest CMOS circuit?
I got:

\(

Y = \overline{A} \cdot B + A \cdot \overline{B}

\)

Which I believe is a simple XOR gate. Not sure what kind of CMOS circuit might be used though (I've only ever worked with PNP/NPM).

On a side note I do like the idea of using a custom Programmable Array Logic circuit for making an efficient 4-bit comparator. It would require a lot of transistors but each of those signals would just pass through a single AND gate followed by an OR gate, so it would likely be blazing fast. Of course the boolean expression for each output is absolutely horrendous:

\(\overline{A} \cdot \overline{B} \cdot \overline{C} \cdot D \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot \overline{H}\)
\( + \overline{A} \cdot \overline{B} \cdot C \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot \overline{H}\)
\( + \overline{A} \cdot \overline{B} \cdot C \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot H\)
\( + \overline{A} \cdot \overline{B} \cdot C \cdot D \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot \overline{H}\)
\( + \overline{A} \cdot \overline{B} \cdot C \cdot D \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot H\)
\( + \overline{A} \cdot \overline{B} \cdot C \cdot D \cdot \overline{E} \cdot \overline{F} \cdot G \cdot \overline{H}\)
\( + \overline{A} \cdot B \cdot \overline{C} \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot \overline{H}\)
\( + \overline{A} \cdot B \cdot \overline{C} \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot H\)
\( + \overline{A} \cdot B \cdot \overline{C} \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot G \cdot \overline{H}\)
\( + \overline{A} \cdot B \cdot \overline{C} \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot G \cdot H\)
\( + \overline{A} \cdot B \cdot \overline{C} \cdot D \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot \overline{H}\)
\( + \overline{A} \cdot B \cdot \overline{C} \cdot D \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot H\)
\( + \overline{A} \cdot B \cdot \overline{C} \cdot D \cdot \overline{E} \cdot \overline{F} \cdot G \cdot \overline{H}\)
\( + \overline{A} \cdot B \cdot \overline{C} \cdot D \cdot \overline{E} \cdot \overline{F} \cdot G \cdot H\)
\( + \overline{A} \cdot B \cdot \overline{C} \cdot D \cdot \overline{E} \cdot F \cdot \overline{G} \cdot \overline{H}\)
\( + \overline{A} \cdot B \cdot C \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot \overline{H}\)
\( + \overline{A} \cdot B \cdot C \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot H\)
\( + \overline{A} \cdot B \cdot C \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot G \cdot \overline{H}\)
\( + \overline{A} \cdot B \cdot C \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot G \cdot H\)
\( + \overline{A} \cdot B \cdot C \cdot \overline{D} \cdot \overline{E} \cdot F \cdot \overline{G} \cdot \overline{H}\)
\( + \overline{A} \cdot B \cdot C \cdot \overline{D} \cdot \overline{E} \cdot F \cdot \overline{G} \cdot H\)
\( + \overline{A} \cdot B \cdot C \cdot D \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot \overline{H}\)
\( + \overline{A} \cdot B \cdot C \cdot D \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot H\)
\( + \overline{A} \cdot B \cdot C \cdot D \cdot \overline{E} \cdot \overline{F} \cdot G \cdot \overline{H}\)
\( + \overline{A} \cdot B \cdot C \cdot D \cdot \overline{E} \cdot \overline{F} \cdot G \cdot H\)
\( + \overline{A} \cdot B \cdot C \cdot D \cdot \overline{E} \cdot F \cdot \overline{G} \cdot \overline{H}\)
\( + \overline{A} \cdot B \cdot C \cdot D \cdot \overline{E} \cdot F \cdot \overline{G} \cdot H\)
\( + \overline{A} \cdot B \cdot C \cdot D \cdot \overline{E} \cdot F \cdot G \cdot \overline{H}\)
\( + A \cdot \overline{B} \cdot \overline{C} \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot \overline{B} \cdot \overline{C} \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot H\)
\( + A \cdot \overline{B} \cdot \overline{C} \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot G \cdot \overline{H}\)
\( + A \cdot \overline{B} \cdot \overline{C} \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot G \cdot H\)
\( + A \cdot \overline{B} \cdot \overline{C} \cdot \overline{D} \cdot \overline{E} \cdot F \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot \overline{B} \cdot \overline{C} \cdot \overline{D} \cdot \overline{E} \cdot F \cdot \overline{G} \cdot H\)
\( + A \cdot \overline{B} \cdot \overline{C} \cdot \overline{D} \cdot \overline{E} \cdot F \cdot G \cdot \overline{H}\)
\( + A \cdot \overline{B} \cdot \overline{C} \cdot \overline{D} \cdot \overline{E} \cdot F \cdot G \cdot H\)
\( + A \cdot \overline{B} \cdot \overline{C} \cdot D \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot \overline{B} \cdot \overline{C} \cdot D \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot H\)
\( + A \cdot \overline{B} \cdot \overline{C} \cdot D \cdot \overline{E} \cdot \overline{F} \cdot G \cdot \overline{H}\)
\( + A \cdot \overline{B} \cdot \overline{C} \cdot D \cdot \overline{E} \cdot \overline{F} \cdot G \cdot H\)
\( + A \cdot \overline{B} \cdot \overline{C} \cdot D \cdot \overline{E} \cdot F \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot \overline{B} \cdot \overline{C} \cdot D \cdot \overline{E} \cdot F \cdot \overline{G} \cdot H\)
\( + A \cdot \overline{B} \cdot \overline{C} \cdot D \cdot \overline{E} \cdot F \cdot G \cdot \overline{H}\)
\( + A \cdot \overline{B} \cdot \overline{C} \cdot D \cdot \overline{E} \cdot F \cdot G \cdot H\)
\( + A \cdot \overline{B} \cdot \overline{C} \cdot D \cdot E \cdot \overline{F} \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot \overline{B} \cdot C \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot \overline{B} \cdot C \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot H\)
\( + A \cdot \overline{B} \cdot C \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot G \cdot \overline{H}\)
\( + A \cdot \overline{B} \cdot C \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot G \cdot H\)
\( + A \cdot \overline{B} \cdot C \cdot \overline{D} \cdot \overline{E} \cdot F \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot \overline{B} \cdot C \cdot \overline{D} \cdot \overline{E} \cdot F \cdot \overline{G} \cdot H\)
\( + A \cdot \overline{B} \cdot C \cdot \overline{D} \cdot \overline{E} \cdot F \cdot G \cdot \overline{H}\)
\( + A \cdot \overline{B} \cdot C \cdot \overline{D} \cdot \overline{E} \cdot F \cdot G \cdot H\)
\( + A \cdot \overline{B} \cdot C \cdot \overline{D} \cdot E \cdot \overline{F} \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot \overline{B} \cdot C \cdot \overline{D} \cdot E \cdot \overline{F} \cdot \overline{G} \cdot H\)
\( + A \cdot \overline{B} \cdot C \cdot D \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot \overline{B} \cdot C \cdot D \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot H\)
\( + A \cdot \overline{B} \cdot C \cdot D \cdot \overline{E} \cdot \overline{F} \cdot G \cdot \overline{H}\)
\( + A \cdot \overline{B} \cdot C \cdot D \cdot \overline{E} \cdot \overline{F} \cdot G \cdot H\)
\( + A \cdot \overline{B} \cdot C \cdot D \cdot \overline{E} \cdot F \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot \overline{B} \cdot C \cdot D \cdot \overline{E} \cdot F \cdot \overline{G} \cdot H\)
\( + A \cdot \overline{B} \cdot C \cdot D \cdot \overline{E} \cdot F \cdot G \cdot \overline{H}\)
\( + A \cdot \overline{B} \cdot C \cdot D \cdot \overline{E} \cdot F \cdot G \cdot H\)
\( + A \cdot \overline{B} \cdot C \cdot D \cdot E \cdot \overline{F} \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot \overline{B} \cdot C \cdot D \cdot E \cdot \overline{F} \cdot \overline{G} \cdot H\)
\( + A \cdot \overline{B} \cdot C \cdot D \cdot E \cdot \overline{F} \cdot G \cdot \overline{H}\)
\( + A \cdot B \cdot \overline{C} \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot B \cdot \overline{C} \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot H\)
\( + A \cdot B \cdot \overline{C} \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot G \cdot \overline{H}\)
\( + A \cdot B \cdot \overline{C} \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot G \cdot H\)
\( + A \cdot B \cdot \overline{C} \cdot \overline{D} \cdot \overline{E} \cdot F \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot B \cdot \overline{C} \cdot \overline{D} \cdot \overline{E} \cdot F \cdot \overline{G} \cdot H\)
\( + A \cdot B \cdot \overline{C} \cdot \overline{D} \cdot \overline{E} \cdot F \cdot G \cdot \overline{H}\)
\( + A \cdot B \cdot \overline{C} \cdot \overline{D} \cdot \overline{E} \cdot F \cdot G \cdot H\)
\( + A \cdot B \cdot \overline{C} \cdot \overline{D} \cdot E \cdot \overline{F} \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot B \cdot \overline{C} \cdot \overline{D} \cdot E \cdot \overline{F} \cdot \overline{G} \cdot H\)
\( + A \cdot B \cdot \overline{C} \cdot \overline{D} \cdot E \cdot \overline{F} \cdot G \cdot \overline{H}\)
\( + A \cdot B \cdot \overline{C} \cdot \overline{D} \cdot E \cdot \overline{F} \cdot G \cdot H\)
\( + A \cdot B \cdot \overline{C} \cdot D \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot B \cdot \overline{C} \cdot D \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot H\)
\( + A \cdot B \cdot \overline{C} \cdot D \cdot \overline{E} \cdot \overline{F} \cdot G \cdot \overline{H}\)
\( + A \cdot B \cdot \overline{C} \cdot D \cdot \overline{E} \cdot \overline{F} \cdot G \cdot H\)
\( + A \cdot B \cdot \overline{C} \cdot D \cdot \overline{E} \cdot F \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot B \cdot \overline{C} \cdot D \cdot \overline{E} \cdot F \cdot \overline{G} \cdot H\)
\( + A \cdot B \cdot \overline{C} \cdot D \cdot \overline{E} \cdot F \cdot G \cdot \overline{H}\)
\( + A \cdot B \cdot \overline{C} \cdot D \cdot \overline{E} \cdot F \cdot G \cdot H\)
\( + A \cdot B \cdot \overline{C} \cdot D \cdot E \cdot \overline{F} \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot B \cdot \overline{C} \cdot D \cdot E \cdot \overline{F} \cdot \overline{G} \cdot H\)
\( + A \cdot B \cdot \overline{C} \cdot D \cdot E \cdot \overline{F} \cdot G \cdot \overline{H}\)
\( + A \cdot B \cdot \overline{C} \cdot D \cdot E \cdot \overline{F} \cdot G \cdot H\)
\( + A \cdot B \cdot \overline{C} \cdot D \cdot E \cdot F \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot B \cdot C \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot B \cdot C \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot H\)
\( + A \cdot B \cdot C \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot G \cdot \overline{H}\)
\( + A \cdot B \cdot C \cdot \overline{D} \cdot \overline{E} \cdot \overline{F} \cdot G \cdot H\)
\( + A \cdot B \cdot C \cdot \overline{D} \cdot \overline{E} \cdot F \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot B \cdot C \cdot \overline{D} \cdot \overline{E} \cdot F \cdot \overline{G} \cdot H\)
\( + A \cdot B \cdot C \cdot \overline{D} \cdot \overline{E} \cdot F \cdot G \cdot \overline{H}\)
\( + A \cdot B \cdot C \cdot \overline{D} \cdot \overline{E} \cdot F \cdot G \cdot H\)
\( + A \cdot B \cdot C \cdot \overline{D} \cdot E \cdot \overline{F} \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot B \cdot C \cdot \overline{D} \cdot E \cdot \overline{F} \cdot \overline{G} \cdot H\)
\( + A \cdot B \cdot C \cdot \overline{D} \cdot E \cdot \overline{F} \cdot G \cdot \overline{H}\)
\( + A \cdot B \cdot C \cdot \overline{D} \cdot E \cdot \overline{F} \cdot G \cdot H\)
\( + A \cdot B \cdot C \cdot \overline{D} \cdot E \cdot F \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot B \cdot C \cdot \overline{D} \cdot E \cdot F \cdot \overline{G} \cdot H\)
\( + A \cdot B \cdot C \cdot D \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot B \cdot C \cdot D \cdot \overline{E} \cdot \overline{F} \cdot \overline{G} \cdot H\)
\( + A \cdot B \cdot C \cdot D \cdot \overline{E} \cdot \overline{F} \cdot G \cdot \overline{H}\)
\( + A \cdot B \cdot C \cdot D \cdot \overline{E} \cdot \overline{F} \cdot G \cdot H\)
\( + A \cdot B \cdot C \cdot D \cdot \overline{E} \cdot F \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot B \cdot C \cdot D \cdot \overline{E} \cdot F \cdot \overline{G} \cdot H\)
\( + A \cdot B \cdot C \cdot D \cdot \overline{E} \cdot F \cdot G \cdot \overline{H}\)
\( + A \cdot B \cdot C \cdot D \cdot \overline{E} \cdot F \cdot G \cdot H\)
\( + A \cdot B \cdot C \cdot D \cdot E \cdot \overline{F} \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot B \cdot C \cdot D \cdot E \cdot \overline{F} \cdot \overline{G} \cdot H\)
\( + A \cdot B \cdot C \cdot D \cdot E \cdot \overline{F} \cdot G \cdot \overline{H}\)
\( + A \cdot B \cdot C \cdot D \cdot E \cdot \overline{F} \cdot G \cdot H\)
\( + A \cdot B \cdot C \cdot D \cdot E \cdot F \cdot \overline{G} \cdot \overline{H}\)
\( + A \cdot B \cdot C \cdot D \cdot E \cdot F \cdot \overline{G} \cdot H\)
\( + A \cdot B \cdot C \cdot D \cdot E \cdot F \cdot G \cdot \overline{H}\)

And that's just for the GT comparison stage! I haven't even tried to simplify that beast...
 
Last edited:

MisterBill2

Joined Jan 23, 2018
27,523
I do notice that the TS seemed to be limited to using two input gates, which is certainly a very major limitation.
It also seems that the whole discussion has wandered away from any practical schemes.
 

MrAl

Joined Jun 17, 2014
13,704
Do it again, but this time spent fifteen minutes. ;)

It's easy to mess up Boolean manipulations, but that wasn't the point.

HINT: You inverted something and then, for some reason, went and inverted it again, yielding what you already had as a prior partial result.

Also, a LUT-based solution is off the table -- You said, "then choose the gates that those expressions represent."

My response is that this is easier said than done.

The reason is that Boolean expressions using AND, OR, and NOT are not good fits for expressions that represent minimal logic circuit implementations.

If you are just going to do a LUT, there's no reason to do the prior step of your suggested approach, which was, "you can then go on to simplify those expressions." Why bother to simply the expressions? Just write a program to walk through all of the combinations and generate the table that needs to be programmed into the LUT.

Plus, if the goal is to get the smallest and/or fastest possible implementation, the access time for a LUT has to be considered as well as the physical size that is going to be required to hold it. That might or might not result in the fasted implementation, but it is virtually guaranteed that it won't result in the smallest.

Hi,

Haha, yes I don't do this by hand anymore.

If we reduce A*(A*B)' we have to invert part of that one time (first invert level) and we get A'*B.
In the same way we do the other 'side' we get A*B'.
Now we have to invert both of those:
not A'*B = A+B'
not A*B' = A'+B

Now under the highest invert we have:
(A+B')*(A'+B)
expanding that we get:
A*B+A'*A+B'*B+A'*B'
reducing that we get:
A*B+A'*B'
which is XNOR.
Inverting that we get XOR.

This is, as noted by the post following mine, is simply the XOR of A and B.

I would have used a program to do this today.

If we want to print out the programming for a ROM then yes, we don't necessarily have to reduce first. If we want to use discrete gates then I guess we do. In this case we ended up with a single gate if we are allowed to use XOR gates, or and XNOR gate followed by an inverter.

I actually have a program for this I wrote some time ago. Just have to find it again :)
 

Thread Starter

xox

Joined Sep 8, 2017
936
I do notice that the TS seemed to be limited to using two input gates, which is certainly a very major limitation.

It also seems that the whole discussion has wandered away from any practical schemes.

I'm actually open to any number of inputs. Notice that the hundreds-of-transistors monstrosity I was proposing features 8 input gates. (And yes I do realize the suggestion wasn't exactly practical, even if implemented with SMD components. It was more of a theoretical statement; If it could be made small enough it would probably be very fast.)
 

WBahn

Joined Mar 31, 2012
32,844
Hi,

Haha, yes I don't do this by hand anymore.

If we reduce A*(A*B)' we have to invert part of that one time (first invert level) and we get A'*B.
In the same way we do the other 'side' we get A*B'.
Now we have to invert both of those:
not A'*B = A+B'
not A*B' = A'+B

Now under the highest invert we have:
(A+B')*(A'+B)
expanding that we get:
A*B+A'*A+B'*B+A'*B'
reducing that we get:
A*B+A'*B'
which is XNOR.
Inverting that we get XOR.

This is, as noted by the post following mine, is simply the XOR of A and B.

I would have used a program to do this today.

If we want to print out the programming for a ROM then yes, we don't necessarily have to reduce first. If we want to use discrete gates then I guess we do. In this case we ended up with a single gate if we are allowed to use XOR gates, or and XNOR gate followed by an inverter.

I actually have a program for this I wrote some time ago. Just have to find it again :)
But how are you going to implement that XOR gate (in CMOS)?

How many transistors is it going to use? How much delay will it have relative to the delay of a single NOT gate?

How would you manipulate the Boolean expression in order to arrive at that faster and/or smaller implementation?

Let me be more direct.

We now have two Boolean expressions for XOR:

(#1) Y = ((A·(A·B)')'·((A·B)'·B)')'

and

(#2) Y = (A·B')+(A'·B) (Typo fixed -- thanks MrAl)

Of these two, which one is "simpler"?

Which one represents the implementation that is faster? By how much?

Which one represents the implementation that is smaller? By how much?
 
Last edited:

WBahn

Joined Mar 31, 2012
32,844
I got:

\(

Y = \overline{A} \cdot B + A \cdot \overline{B}

\)

Which I believe is a simple XOR gate. Not sure what kind of CMOS circuit might be used though (I've only ever worked with PNP/NPM).

On a side note I do like the idea of using a custom Programmable Array Logic circuit for making an efficient 4-bit comparator. It would require a lot of transistors but each of those signals would just pass through a single AND gate followed by an OR gate, so it would likely be blazing fast. Of course the boolean expression for each output is absolutely horrendous:

And that's just for the GT comparison stage! I haven't even tried to simplify that beast...
One approach to do the comparison is to use an adder to subtract the two numbers, A-B. Then, your comparison comes down to doing two very simple things.

S = A - B

If S is zero, then A=B. if the result is negative, then A<B.

To get the first signal, you simple NOR all of the bits together, since an OR will be LO if and only iff all of it's inputs are LO.

EQ = (S3+S2+S1+S0)'

This is a simple gate in CMOS having a single gate-delay.

The other signal is simply the same as the MSB of the sum

LT = S3

So there is no delay here, it is merely a wire.

The other four relational possibilities are easily obtained from these two:

NE = EQ'
GE = LT'
GT = (EQ+LT)'
LE = GT'

Hence, once you have the difference, you can get all six relational outputs using a single N-input NOR gate, one 2-input NOR gate, and the NOT gates. You have a maximum delay of three gate delays and the transistor count is (N+2.5) that of a single 2-input NAND gate. Keep in mind, that this is AFTER you get the difference, so you still need an adder and how you implement that will be the driving factor for both speed and size. But here you can play partitioning games to balance the two very effectively because you don't need the actual difference to be correct (unless you want that for some other purpose).
 

Thread Starter

xox

Joined Sep 8, 2017
936
One approach to do the comparison is to use an adder to subtract the two numbers, A-B. Then, your comparison comes down to doing two very simple things.


S = A - B


If S is zero, then A=B. if the result is negative, then A<B.


To get the first signal, you simple NOR all of the bits together, since an OR will be LO if and only iff all of it's inputs are LO.


EQ = (S3+S2+S1+S0)'


This is a simple gate in CMOS having a single gate-delay.


The other signal is simply the same as the MSB of the sum


LT = S3


So there is no delay here, it is merely a wire.


The other four relational possibilities are easily obtained from these two:


NE = EQ'

GE = LT'

GT = (EQ+LT)'

LE = GT'


Hence, once you have the difference, you can get all six relational outputs using a single N-input NOR gate, one 2-input NOR gate, and the NOT gates. You have a maximum delay of three gate delays and the transistor count is (N+2.5) that of a single 2-input NAND gate. Keep in mind, that this is AFTER you get the difference, so you still need an adder and how you implement that will be the driving factor for both speed and size. But here you can play partitioning games to balance the two very effectively because you don't need the actual difference to be correct (unless you want that for some other purpose).
Being a programmer myself, this was actually my first thought! One thing about that approach however is the fact that subtraction in twos-complement means an inversion then increment of the right-hand-side variable. In other words roughly two additions would be required. That aside, I don't think that the adder circuit would necessarily be much bigger (or more specifically, more "levels" for the signal to pass through) than a comparator. But yes if the whole process could be done efficiently, all of the various comparison functions would only require a couple of extra gates at most.

Talking about CMOS circuits. Aren't those super-sensitive to static electricity, so special precautions need to be taken when handling them? Working with BJTs it almost seemed like you could manhandle the little buggers without much of a concern. Whereas CMOS make me think of anti-static wrists straps and such.
 

WBahn

Joined Mar 31, 2012
32,844
Being a programmer myself, this was actually my first thought! One thing about that approach however is the fact that subtraction in twos-complement means an inversion then increment of the right-hand-side variable. In other words roughly two additions would be required. That aside, I don't think that the adder circuit would necessarily be much bigger (or more specifically, more "levels" for the signal to pass through) than a comparator. But yes if the whole process could be done efficiently, all of the various comparison functions would only require a couple of extra gates at most.
It doesn't require two additions. In an adder that supports carry-in, you simply invert all of the bits of B (the subtrahend) and use the carry-in bit to add the one. If you don't have a carry-in signal, you simply invert both A (the minuend) and the output (the difference).

The big penalty that you would pay using an adder is that the carry must propagate across all the bits. For a simple ripple-carry adder, this becomes significant pretty quickly as the width of the input signals increases. This can be mitigated, at the cost of increased complexity, using a variety of fast-carry or carry-lookahead strategies. But, if we aren't interested in having the actual difference at the end of the day, then we can use a set of smaller adders along with some glue logic to get the result quicker. We can explore some of those options, if you would like.

Talking about CMOS circuits. Aren't those super-sensitive to static electricity, so special precautions need to be taken when handling them? Working with BJTs it almost seemed like you could manhandle the little buggers without much of a concern. Whereas CMOS make me think of anti-static wrists straps and such.
In principle, CMOS circuits should be handled with static-safe procedures. In practice, particularly for the hobbyist, modern CMOS IC chips have sufficient anti-static protection that they can be handled about as roughly as TTL chips. I've designed chips that had a few inputs that were unprotected (the parasitic capacitance associated with even mild protection circuits was simply too much for the application) and if you blinked your eyes too fast from less than ten feet away, you might blow them. Certainly in any kind of production environment or if you are assembling things you are selling or need to work for years and years, it would be worthwhile to observe reasonable safe-handling procedures (which aren't that onerous). The same is true for either really expensive (because they are expensive, so why risk it) or extremely high-speed (because high-speed is not conducive to strong anti-static protection). But for hobby and lab type circuits, you can be amazingly careless. I've got lots of CMOS parts that have been stored loose in non-static plastic bins for literally decades that have been moved around from place to place many times and that I have never taken any precautions when handling them and I have yet to see one fail. Now, I wouldn't want to have to back up their long-term reliability with anything much beyond having to say, "Sorry," when they fail prematurely.
 

Thread Starter

xox

Joined Sep 8, 2017
936
Quick question. I was curious to see how an XOR gate might be implemented with CMOS but my first attempt is not going very well. For one thing there seems to be a 1.5V voltage drop at the source pins of the OR'ed NFETS when they are conducting. That in turn causes the PFET down the line (which is controlled by the AND'ed NFETS) to produce an output of just under 2V, and so the XOR gate fails to activate when it's supposed to. The second (somewhat minor) issue is while the AND gates are not on, a residual 200 mV still appears at the second transistor's source terminal. Not a huge deal I guess but I just expected it to be much closer to zero. Any ideas what I am doing wrong here?

cmos-xor-experiment.png
 
Last edited:

MrAl

Joined Jun 17, 2014
13,704
I'm actually open to any number of inputs. Notice that the hundreds-of-transistors monstrosity I was proposing features 8 input gates. (And yes I do realize the suggestion wasn't exactly practical, even if implemented with SMD components. It was more of a theoretical statement; If it could be made small enough it would probably be very fast.)
Hi,

I only needed equality and 8 bits, so I used 8 XOR (or XNOR) gates and a single 8 input gate (NOR or OR or AND or NAND don't remember that far back now).
 

MrAl

Joined Jun 17, 2014
13,704
But how are you going to implement that XOR gate (in CMOS)?

How many transistors is it going to use? How much delay will it have relative to the delay of a single NOT gate?

How would you manipulate the Boolean expression in order to arrive at that faster and/or smaller implementation?

Let me be more direct.

We now have two Boolean expressions for XOR:

(#1) Y = ((A·(A·B)')'·((A·B)'·B)')'

and

(#2) Y = (A·B')+(A·B')

Of these two, which one is "simpler"?

Which one represents that implementation that is faster? By how much?

Which one represents the implementation that is smaller? By how much?
Hi there,

You wrote:
(#1) Y = ((A·(A·B)')'·((A·B)'·B)')'

and did you mean:
(#2) Y= (A*B')+(A'*B)

#2 results in just one logic gate XOR(A,B) while the other looks like it needs maybe five gates, so why would you ask which one is simpler. Did you have something else in mind?

What one is faster, isn't that obvious? By how much, check the maximum gate delay input to output.

What implementation is smaller, one gate vs maybe five gates.

I don't want to implement this with discrete CMOS transistors and the first post in this thread did not seem to indicate that.

Overall I am not sure what you are trying to get at with these questions. I'm sure it is interesting but you will have to elaborate.
 

Thread Starter

xox

Joined Sep 8, 2017
936
Hi,

I only needed equality and 8 bits, so I used 8 XOR (or XNOR) gates and a single 8 input gate (NOR or OR or AND or NAND don't remember that far back now).
Well sure equality/inequality only requires two layers of gates. Initially I used three because at the time I didn't know that multi-input NOR gates were even a thing. (Yes, I live under a rock.)
 

MrAl

Joined Jun 17, 2014
13,704
Well sure equality/inequality only requires two layers of gates. Initially I used three because at the time I didn't know that multi-input NOR gates were even a thing. (Yes, I live under a rock.)
Hi again,

I can't remember if I had to do any inequalities. If I did, I would have purchased some compare chips most likely TTL family because I worked with a lot of that way back then.
The application I needed the 8 bit equality compare was for detecting when there was horizontal and vertical coincidence with a fixed horizontal and fixed vertical 8 bit counts. So that was detecting a fixed point in 2d space with a continuously changing point in 2d space. The fixed point could be altered slowly while the changing point was changing very fast.
 

WBahn

Joined Mar 31, 2012
32,844
Quick question. I was curious to see how an XOR gate might be implemented with CMOS but my first attempt is not going very well. For one thing there seems to be a 1.5V voltage drop at the source pins of the OR'ed NFETS when they are conducting. That in turn causes the PFET down the line (which is controlled by the AND'ed NFETS) to produce an output of just under 2V, and so the XOR gate fails to activate when it's supposed to. The second (somewhat minor) issue is while the AND gates are not on, a residual 200 mV still appears at the second transistor's source terminal. Not a huge deal I guess but I just expected it to be much closer to zero. Any ideas what I am doing wrong here?

View attachment 357581
True CMOS only has transistors. No resistors, no capacitors, no current sources.

What you are showing is an attempt to use some kind of linear differential amplifier to make an XOR gate, but what happens if A and B are just almost the same, but one is slightly higher voltage than the other? They are still close enough to be considered the same logic value, but they aren't exactly the same voltage (and, in practice, they never will be exactly the same voltage).

In CMOS, we avoid this issue by always driving every transistor either hard into cutoff or hard into saturation, therefore they act like switches that are either ON or OFF.

NFETs are turned on when the gate voltage is sufficiently greater than the source voltage, so we turn them ON by applying a HI signal (close to the power supply) and turn them OFF by applying a LO signal (close to the negative rail, or "ground"). To ensure that this happens reliably, we only use NFETs to pull a signal line LO.

PFETs are turned on when the gate voltage is sufficiently less than the source voltage, so we turn them ON by applying a LO signal and turn them OFF by applying a HI signal. To ensure that this happens reliably, we only use PFETs to pull a signal line HI.

We generally design basic digital circuits so that each input signal goes to one NFET that will pull something LO when the input is HI and also to one PFET that will pull something HI when the input is LO.

This is why CMOS is intrinsically an inverting logic family (the same is true of TTL, but it is not true of ECL, so this isn't something that is universally the case).

So let's first look at the NOT gate:
1761286740950.png
M1 is a PFET and M2 is an NFET. In digital circuits, the distinction between source and drain is arbitrary. Also, the body connection is generally ignored, though there are some ramifications that the designer sometimes need to take into account.

The bubble that indicates the PFET is an inversion bubble. Here is the way to think of it when viewing them as a switch -- if the signal is HI, then the switch is closed (i.e., turned ON). For the NFET, the input is sent directly to the switch, so it is ON when the input is HI. But for the PFET, the input is first inverted before being applied to the switch, so the input must be LO to turn it on.

At any given time, the input is either HI or LO. We assume that transitions between these two states happen quickly. For now, at least, let's ignore what can happen if this turns out not to be the case.

If the input is HI, then M2 is a closed switch and M1 is an open switch, which ties the output LO.

If the input is LO, then M2 is an open switch and M1 is a close switch, which ties the output HI.

To implement more complex logic circuits, we combine transistors in series and parallel, just like we sometimes do with physical switches, to implement OR and AND relationships.

If switches are placed in series, then the combined switch circuit is open if ANY of the switches are open and is closed only if ALL of the switches are closed.

If switches are placed in parallel, then the combined switch circuit to is open only if ALL of the switches are open and it is closed if ANY of the switches are closed.

So now let's consider a NAND gate.

A NAND gate's output is LO only if BOTH inputs are HI. That describes two NFETs that are placed in series.

Conversely, a NAND gate's output is HI if ANY of the inputs are LO. This describes PFETs that are placed in parallel.

So a NAND gate can be implemented as follows:

1761287476447.png

If I want to add more inputs, I just add more PFETs in parallel and more NFETs in series. The limiting factor is the effective resistance of all of the NFETs in series, since those resistances add. CMOS gates are essentially capacitors, so to change them from a high to a low voltage, we must charge or distance that capacitance and the rate at which that happens is determined by the resistance of the output of the gate driving it, so the required speed places a limit on how many inputs we can support. For general purpose logic circuits, a limit of around eight is pretty typical. The same is true for the fanout, which is how many inputs a given logic gate can drive, but by limiting the input to about eight inputs, we can usually drive dozens of gates (again, that's dictated by the necessary speed). I've designed chips where a single output drive literally millions of gates, but speed wasn't an issue -- in fact, I needed the transitions to be slow (millisecond time scale instead of nanosecond time scale).

If we place the NFETs in parallel and the PFETs in series, then we have a gate that is LO if ANY input is HI, but is HI only if ALL inputs are LO. That describes a NOR gate.

An AND gate is implemented by following a NAND gate with a NOT gate. Similarly, an OR gate is implemented by following a NOR gate with a NOT gate.

The size of the overall circuit is roughly proportional to the number of transistors in it. The speed of the circuit is roughly proportional to the number of gates that a signal must propagate through from input to output (along the longest possible path). Thus, we see that NOT, NAND and NOR gates are all roughly the same speed, while AND and OR gates are 50% larger than NAND and NOR and have twice the delay.

XOR is the black sheep of the family and there isn't a nice, simple, fast, and small way to design a circuit to implement it. There are lots of different ways to go about it, each having pros and cons relative to the others. Many of these techniques, in an effort to reduce the size, result in circuits in which the output affects the input. This is a violation of true CMOS in which the loading of the output has very little impact on the input signals.

To make a CMOS XOR gate, one way is to build it up from more basic gates, namely NOT, NAND, NOR, AND, and OR (all of which we've already described how to implement above).

A direct implementation based on the defining definition for the Boolean XOR function is

Y = ((A')·B) + (A·(B'))

I'm assuming you are comfortable with the logic notation that used multiplication symbol for AND, the addition symbol for OR, and the apostrophe for NOT.

If I also assume that you are familiar with the basic graphical logic gate symbols, the direct implementation of this equation is

1761288609142.png
The size of this circuit is 20 transistors and it has three gate delays, since the NOT is one gate delay and the AND and OR gates are each two more.

But now let's consider a different implementation:

1761288858780.png
This circuit has 16 transistors and only 3 gate delays. The earlier circuit is thus 25% larger and exhibits 67% more delay.

What is the Boolean expression that represents this implementation?

Y = ((A·(A·B)')'·((A·B)'·B)')'

Although the Boolean expression LOOKS significantly more complicated than the prior one, it actually represents a significantly smaller and faster implementation. This is why I said earlier that just manipulating Boolean expressions to "simplify" logic circuits is far easier said than done. Boolean expressions naturally express logic in terms of NOT, AND, and OR. But logic circuits are implemented as combinations of NOT, NAND, and NOR. Furthermore, Boolean equations don't do a good job of signal reuse. For instance, notice that the output of that first NAND gate is used as an input to two different NAND gates in the next layer. But in the Boolean expression, that (A·B)' that represents it has to be duplicated.

But we can actually do better than this, and still stick to true CMOS, by implementing the XOR functionality directly at the transistor level to create an XOR gate as a primitive element (i.e., not a composite of other gates).

1761289450017.png

This implementation has just 12 transistors and only two gate delays, making it twice the size of an AND or OR gate, but just as fast. It also makes it barely more than half the size of the first XOR circuit above and is 2.5x the speed.

These are not just academic considerations. Shortly after I was hired as an IC designer (my first career engineering position), I was asked to look over the digital logic for a chip that wasn't meeting the timing spec -- it was missing it by quite a bit. I expected it to be quite a challenge, because others had been banging on the problem for a few weeks and they were getting desperate because the chip tape-out deadline was fast approaching. The first thing I did was push down through the schematics to get a feel for how all of the logic was implemented and if there were any low-hanging fruit I could spot quickly. When i pushed into the XOR gate, it gasped because it was implemented using the "simple" Boolean logic. So the first thing I did was replace it with the four-NAND version and rerun the simulation. It immediately met timing. For later chips, I replaced it with the direct CMOS version -- I couldn't do that on this chip because, since it was now a primitive gate, I had to first layout the new gate and define the outline and ports for the place and route tool and there was no where near enough time to do that.
 

WBahn

Joined Mar 31, 2012
32,844
Hi there,

You wrote:
(#1) Y = ((A·(A·B)')'·((A·B)'·B)')'

and did you mean:
(#2) Y= (A*B')+(A'*B)

#2 results in just one logic gate XOR(A,B) while the other looks like it needs maybe five gates, so why would you ask which one is simpler. Did you have something else in mind?

What one is faster, isn't that obvious? By how much, check the maximum gate delay input to output.

What implementation is smaller, one gate vs maybe five gates.

I don't want to implement this with discrete CMOS transistors and the first post in this thread did not seem to indicate that.

Overall I am not sure what you are trying to get at with these questions. I'm sure it is interesting but you will have to elaborate.
Just because you put a box around something and give it a name does not make it simpler, smaller, or faster.

You don't have to go down to discrete transistors.

(#1) Y = ((A·(A·B)')'·((A·B)'·B)')'

Represents a significantly smaller and faster implementation of XOR than does

(#2) Y= (A*B')+(A'*B)

(and, yes, I had a typo, so thanks for pointing that out).
 

Thread Starter

xox

Joined Sep 8, 2017
936
True CMOS only has transistors. No resistors, no capacitors, no current sources.


What you are showing is an attempt to use some kind of linear differential amplifier to make an XOR gate, but what happens if A and B are just almost the same, but one is slightly higher voltage than the other? They are still close enough to be considered the same logic value, but they aren't exactly the same voltage (and, in practice, they never will be exactly the same voltage).


In CMOS, we avoid this issue by always driving every transistor either hard into cutoff or hard into saturation, therefore they act like switches that are either ON or OFF.


NFETs are turned on when the gate voltage is sufficiently greater than the source voltage, so we turn them ON by applying a HI signal (close to the power supply) and turn them OFF by applying a LO signal (close to the negative rail, or "ground"). To ensure that this happens reliably, we only use NFETs to pull a signal line LO.


PFETs are turned on when the gate voltage is sufficiently less than the source voltage, so we turn them ON by applying a LO signal and turn them OFF by applying a HI signal. To ensure that this happens reliably, we only use PFETs to pull a signal line HI.


We generally design basic digital circuits so that each input signal goes to one NFET that will pull something LO when the input is HI and also to one PFET that will pull something HI when the input is LO.


This is why CMOS is intrinsically an inverting logic family (the same is true of TTL, but it is not true of ECL, so this isn't something that is universally the case).


So let's first look at the NOT gate:

1761286740950.png

M1 is a PFET and M2 is an NFET. In digital circuits, the distinction between source and drain is arbitrary. Also, the body connection is generally ignored, though there are some ramifications that the designer sometimes need to take into account.


The bubble that indicates the PFET is an inversion bubble. Here is the way to think of it when viewing them as a switch -- if the signal is HI, then the switch is closed (i.e., turned ON). For the NFET, the input is sent directly to the switch, so it is ON when the input is HI. But for the PFET, the input is first inverted before being applied to the switch, so the input must be LO to turn it on.


At any given time, the input is either HI or LO. We assume that transitions between these two states happen quickly. For now, at least, let's ignore what can happen if this turns out not to be the case.


If the input is HI, then M2 is a closed switch and M1 is an open switch, which ties the output LO.


If the input is LO, then M2 is an open switch and M1 is a close switch, which ties the output HI.


To implement more complex logic circuits, we combine transistors in series and parallel, just like we sometimes do with physical switches, to implement OR and AND relationships.


If switches are placed in series, then the combined switch circuit is open if ANY of the switches are open and is closed only if ALL of the switches are closed.


If switches are placed in parallel, then the combined switch circuit to is open only if ALL of the switches are open and it is closed if ANY of the switches are closed.


So now let's consider a NAND gate.


A NAND gate's output is LO only if BOTH inputs are HI. That describes two NFETs that are placed in series.


Conversely, a NAND gate's output is HI if ANY of the inputs are LO. This describes PFETs that are placed in parallel.


So a NAND gate can be implemented as follows:


1761287476447.png


If I want to add more inputs, I just add more PFETs in parallel and more NFETs in series. The limiting factor is the effective resistance of all of the NFETs in series, since those resistances add. CMOS gates are essentially capacitors, so to change them from a high to a low voltage, we must charge or distance that capacitance and the rate at which that happens is determined by the resistance of the output of the gate driving it, so the required speed places a limit on how many inputs we can support. For general purpose logic circuits, a limit of around eight is pretty typical. The same is true for the fanout, which is how many inputs a given logic gate can drive, but by limiting the input to about eight inputs, we can usually drive dozens of gates (again, that's dictated by the necessary speed). I've designed chips where a single output drive literally millions of gates, but speed wasn't an issue -- in fact, I needed the transitions to be slow (millisecond time scale instead of nanosecond time scale).


If we place the NFETs in parallel and the PFETs in series, then we have a gate that is LO if ANY input is HI, but is HI only if ALL inputs are LO. That describes a NOR gate.


An AND gate is implemented by following a NAND gate with a NOT gate. Similarly, an OR gate is implemented by following a NOR gate with a NOT gate.


The size of the overall circuit is roughly proportional to the number of transistors in it. The speed of the circuit is roughly proportional to the number of gates that a signal must propagate through from input to output (along the longest possible path). Thus, we see that NOT, NAND and NOR gates are all roughly the same speed, while AND and OR gates are 50% larger than NAND and NOR and have twice the delay.


XOR is the black sheep of the family and there isn't a nice, simple, fast, and small way to design a circuit to implement it. There are lots of different ways to go about it, each having pros and cons relative to the others. Many of these techniques, in an effort to reduce the size, result in circuits in which the output affects the input. This is a violation of true CMOS in which the loading of the output has very little impact on the input signals.


To make a CMOS XOR gate, one way is to build it up from more basic gates, namely NOT, NAND, NOR, AND, and OR (all of which we've already described how to implement above).


A direct implementation based on the defining definition for the Boolean XOR function is


Y = ((A')·B) + (A·(B'))


I'm assuming you are comfortable with the logic notation that used multiplication symbol for AND, the addition symbol for OR, and the apostrophe for NOT.


If I also assume that you are familiar with the basic graphical logic gate symbols, the direct implementation of this equation is


1761288609142.png

The size of this circuit is 20 transistors and it has three gate delays, since the NOT is one gate delay and the AND and OR gates are each two more.


But now let's consider a different implementation:


1761288858780.png

This circuit has 16 transistors and only 3 gate delays. The earlier circuit is thus 25% larger and exhibits 67% more delay.


What is the Boolean expression that represents this implementation?


Y = ((A·(A·B)')'·((A·B)'·B)')'


Although the Boolean expression LOOKS significantly more complicated than the prior one, it actually represents a significantly smaller and faster implementation. This is why I said earlier that just manipulating Boolean expressions to "simplify" logic circuits is far easier said than done. Boolean expressions naturally express logic in terms of NOT, AND, and OR. But logic circuits are implemented as combinations of NOT, NAND, and NOR. Furthermore, Boolean equations don't do a good job of signal reuse. For instance, notice that the output of that first NAND gate is used as an input to two different NAND gates in the next layer. But in the Boolean expression, that (A·B)' that represents it has to be duplicated.


But we can actually do better than this, and still stick to true CMOS, by implementing the XOR functionality directly at the transistor level to create an XOR gate as a primitive element (i.e., not a composite of other gates).


1761289450017.png


This implementation has just 12 transistors and only two gate delays, making it twice the size of an AND or OR gate, but just as fast. It also makes it barely more than half the size of the first XOR circuit above and is 2.5x the speed.


These are not just academic considerations. Shortly after I was hired as an IC designer (my first career engineering position), I was asked to look over the digital logic for a chip that wasn't meeting the timing spec -- it was missing it by quite a bit. I expected it to be quite a challenge, because others had been banging on the problem for a few weeks and they were getting desperate because the chip tape-out deadline was fast approaching. The first thing I did was push down through the schematics to get a feel for how all of the logic was implemented and if there were any low-hanging fruit I could spot quickly. When i pushed into the XOR gate, it gasped because it was implemented using the "simple" Boolean logic. So the first thing I did was replace it with the four-NAND version and rerun the simulation. It immediately met timing. For later chips, I replaced it with the direct CMOS version -- I couldn't do that on this chip because, since it was now a primitive gate, I had to first layout the new gate and define the outline and ports for the place and route tool and there was no where near enough time to do that.



Thanks, I was just starting to realize that (A) my placement of the resistors was the source of all of the quirky behavior I was observing and (B) as you have pointed out CMOS is an intrinsically inverting logic family, which turns out to make things somewhat trickier when compared to the BJT equivalents. It's a very subtle (and even counterintuitive) difference that will definitely take some getting used to! Your explanation makes a lot of sense though and I appreciate the outstanding overview of the subject.

I am having a bit of an issue implementing the XOR gate. When I leave out the short between the middle section PFET/NFET pairs, I can see the voltage that would normally activate the XOR gate output. But when in place, the charges are imbalanced so naturally it dissipates. Am I supposed to connect those separately to drive additional transistors?

xor-gate-ish.png


I made Vdd a high-impedance voltage source and connected Vss to ground. That shouldn't be the problem though, should it?

**** EDIT ****

Nevermind that, I just botched the connections! It's working perfectly now. :)cmos-xor-gate.png
 
Last edited:

MrAl

Joined Jun 17, 2014
13,704
Just because you put a box around something and give it a name does not make it simpler, smaller, or faster.

You don't have to go down to discrete transistors.

(#1) Y = ((A·(A·B)')'·((A·B)'·B)')'

Represents a significantly smaller and faster implementation of XOR than does

(#2) Y= (A*B')+(A'*B)

(and, yes, I had a typo, so thanks for pointing that out).
Ok, so how are you deducing that #1 is smaller and faster than #2 ?

Also, how do you get greater than or less than from #1 as well as equals (or not equal) ?
 

Thread Starter

xox

Joined Sep 8, 2017
936
Ok, so how are you deducing that #1 is smaller and faster than #2 ?

Also, how do you get greater than or less than from #1 as well as equals (or not equal) ?
As explained in this post, you can see that the so-called "simplified" XOR expression amounts to something like 20 FETs, whereas the former expression yields a circuit that can be implemented with just 12 of them.

And that's just a single logic gate of course. As far as greater-than/less-than goes (since we are talking about CMOS here) that would require coming up with the most efficient combination of NAND/NOR gates.
 

MrAl

Joined Jun 17, 2014
13,704
As explained in this post, you can see that the so-called "simplified" XOR expression amounts to something like 20 FETs, whereas the former expression yields a circuit that can be implemented with just 12 of them.

And that's just a single logic gate of course. As far as greater-than/less-than goes (since we are talking about CMOS here) that would require coming up with the most efficient combination of NAND/NOR gates.
Hi,

Oh ok, well originally it looked like you were looking for the simplest solution using gates not raw transistors. My comments were based on that assumption.

Now since you wanted equality and GT and LT, if you build an XOR gate from the expression A'*B+A*B' then it looks like you can get all three functions from the same 'gates'. That is because:
"A<B" => A'*B => C
"A>B" => A*B' => D
"A=B" => C+D
This requires those separate C and D sections.
If you want to use transistors, see what you can come up with.
 
Top