Thoughts on comparison circuits?

WBahn

Joined Mar 31, 2012
32,840
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?

View attachment 357591


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. :)View attachment 357592
There's no reason to make Vdd a high-impedance source. You should be able to directly connect it to your 5 V supply (unless the simulator you are using has convergence issues, which a good simulator shouldn't, but if it does, use a small resistance, like 100 Ω. If your FETs are the size that would typically be found on an IC for the internal logic, the ON resistance is still substantial, possibly in the tens of kilohms range.
 

Thread Starter

xox

Joined Sep 8, 2017
936
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.
Ah, so a 1-bit comparator. I'll have to think on that one. The truth table for LT and GT are not standard logic functions (AFAIK) so it would be a pretty exotic configuration methinks. I wouldn't even bother with the equality comparison though. Better to use a dedicated N-bit EQU/NEQ module. Otherwise just chain together a bunch of 1-bit comparators to make larger modules and then put a gate on the final output for a "free" EQU/NEQ.

*** EDIT ***

Come to think of it, it wouldn't even be possible to use a 1-bit "general purpose" comparator to chain/stack together multiple modules. Consider the first stage. You compare the most significant bits of the left and right values and produce two outputs. Now do the same for the next significant set of bits. So you have four outputs total to feed into the next stack. But it only take two inputs! So that won't work.
 
Last edited:

Thread Starter

xox

Joined Sep 8, 2017
936
There's no reason to make Vdd a high-impedance source. You should be able to directly connect it to your 5 V supply (unless the simulator you are using has convergence issues, which a good simulator shouldn't, but if it does, use a small resistance, like 100 Ω. If your FETs are the size that would typically be found on an IC for the internal logic, the ON resistance is still substantial, possibly in the tens of kilohms range.
Got it! But just to be clear does that mean a high-impedance source is undesirable, or just unnecessary?
 

WBahn

Joined Mar 31, 2012
32,840
Ah, so a 1-bit comparator. I'll have to think on that one. The truth table for LT and GT are not standard logic functions (AFAIK) so it would be a pretty exotic configuration methinks. I wouldn't even bother with the equality comparison though. Better to use a dedicated N-bit EQU/NEQ module. Otherwise just chain together a bunch of 1-bit comparators to make larger modules and then put a gate on the final output for a "free" EQU/NEQ.
Your 1-bit comparator can't be chained because it has no way to bring the information from adjacent bits.

But, like I said in my original response in Post #2, you can use the same concept as a ripple-carry adder that is made up of half-adders and full-adders, except that you have a ripple-comparator that is made up of half-comparators and full-comparators.

For a half-comparator, you have the following truth table:

Code:
A B | EQ NE | LT GE | GT LE
0 0 |  1  0 |  0  1 |  0  1
0 1 |  0  1 |  1  0 |  0  1
1 0 |  0  1 |  0  1 |  1  0
1 1 |  1  0 |  0  1 |  0  1
Notice that in each pair of outputs, the second is just the logical negation of the first. Also, you only need one from each of two of the output pairs, you don't need all three. So you are free to choose from any of the twelve possible choices that result, whichever makes the implementation "better" according to whatever metric defines "better".

So let's think about this.

People want to just jump in and use EQ (or NE), which is the XNOR (or XOR) of the two inputs, but we've already seen that this is the black sheep of the logic family. So what if we used the other two columns instead.

In generating the XOR, using the more efficient quad-NAND implementation, what are the internal signals that get generators?

1761307755186.png
Code:
A B | C D E
0 0 | 1 1 1
0 1 | 1 1 0
1 0 | 1 0 1
1 1 | 0 1 1
So D is the LE signal and E is the GE signal, which gives us what we need and we don't need the final NAND gate at all!

1761308258162.png
If we use NOR gates instead of NAND gates, then the top output is the LT and the bottom is the GT.

In either case, we have 12 transistors and 2 gate delays.

The full-comparator has four inputs, namely the A and B from that bit position, but also the two comparison outputs from the prior bit. I'll let you take a shot at working out that logic.
 

WBahn

Joined Mar 31, 2012
32,840
Got it! But just to be clear does that mean a high-impedance source is undesirable, or just unnecessary?
Undesirable. You want voltage sources to be low impedance (ideally zero) and current sources to be high impedance (ideally infinite). In the real world, these are not possible (but we can get really close, if we are willing to throw enough money at it). but simulators like to live in the ideal world, in which case if you connect and ideal voltage source to an ideal capacitor, you get a current that is infinitely large but lasts for an infinitely small amount of time (i.e., an impulse). Simulators don't handle that very well and can fail to converge on a solution as a result.
 

MrAl

Joined Jun 17, 2014
13,704
Ah, so a 1-bit comparator. I'll have to think on that one. The truth table for LT and GT are not standard logic functions (AFAIK) so it would be a pretty exotic configuration methinks. I wouldn't even bother with the equality comparison though. Better to use a dedicated N-bit EQU/NEQ module. Otherwise just chain together a bunch of 1-bit comparators to make larger modules and then put a gate on the final output for a "free" EQU/NEQ.

*** EDIT ***

Come to think of it, it wouldn't even be possible to use a 1-bit "general purpose" comparator to chain/stack together multiple modules. Consider the first stage. You compare the most significant bits of the left and right values and produce two outputs. Now do the same for the next significant set of bits. So you have four outputs total to feed into the next stack. But it only take two inputs! So that won't work.
What? An XOR gate does 1 bit for equality. If you can use an XOR gate by itself, which you had shown several times now, you can use an XOR gate that also includes GT and LT. Not sure what the problem is but feel free to elaborate.
 

MrAl

Joined Jun 17, 2014
13,704
Your 1-bit comparator can't be chained because it has no way to bring the information from adjacent bits.
Hello,

And why not? If you can use an XOR gate you can use a split XOR gate. Multiple bits would be done the same way as with a regular XOR gate for equality, except now we also get GT and LT.
 

WBahn

Joined Mar 31, 2012
32,840
Hello,

And why not? If you can use an XOR gate you can use a split XOR gate. Multiple bits would be done the same way as with a regular XOR gate for equality, except now we also get GT and LT (or three, if you still produce NE).
If you are just going to use an XOR gate to compare two bits (and split it to get GT and LT) that's fine. So now you have a black box that takes two 1-bit inputs and produces two outputs (or three).

How do you then chain that to the next pair of bits?

You can't, because you now have four inputs (or five), the two 1-bit inputs from the next pair, plus the two (or three) outputs from the prior pair.

So, just like having a half-adder to add two 1-bit values together, you can't just chain a bunch of half-adders to produce a multibit adder, because you can't accommodate the carry from the prior bits. So you build a full-adder that takes in both the two new bits plus the carry information from the prior bit position.
 
Last edited:

WBahn

Joined Mar 31, 2012
32,840
The paradigm seems to be constantly changing in this thread.
No, you just need to pay a bit more attention to subcontexts.

I responded to your claim that you can simplify an implementation by going to the Boolean expression, simplifying that, and then using the gates that the simplified expression suggests.

I said that doing that was easier said than done and then provided an example where that was not the case. That example was nothing more than an XOR function.
 

MrAl

Joined Jun 17, 2014
13,704
If you are just going to use an XOR gate to compare two bits (and split it to get GT and LT) that's fine. So now you have a black box that takes two 1-bit inputs and produces two outputs (or three).

How do you then chain that to the next pair of bits?

You can't, because you now have four inputs (or five), the two 1-bit inputs from the next pair, plus the two (or three) outputs from the prior pair.

So, just like having a half-adder to add two 1-bit values together, you can't just chain a bunch of half-adders to produce a multibit adder, because you can't accommodate the carry from the prior bits. So you build a full-adder that takes in both the two new bits plus the carry information from the prior bit position.
Hello again,

What you you mean "you can't" ? This is just logic. If it is logic you can do anything :)

The full list of two bit compares would be in the order [MSB1 LSB1 __ MSB2 LSB2 __ Result] :
00 00 EQ
01 00 GT
10 00 GT
11 00 GT
then
00 01 LT
01 01 EQ
10 01 GT
11 01 GT
then
00 10 LT
01 10 LT
10 10 EQ
11 10 GT
then
00 11 LT
01 11 LT
10 11 LT
11 11 EQ

By examination we might deduce the following...
If MSB1>MSB2 then we have GT,
if MSB1<MSB2 then we have LT,
if MSB1=MSB2 then we look at LSB1 and LSB2 in the same manner.
This gives us enumerated GT and LT and EQ: GT1, GT2, LT1, LT2, EQ1, EQ2.
Using this we can generate:
GT=GT2+(EQ2*GT1)
This says that if GT2=1 then we immediately have the result of 'greater than', but if GT2=0 then we have to look at EQ2 to see if the MSB's are equal, and GT1 to see if the LSB was greater than. ANDing those two gives us the result GT which then is either high or low now depending on only EQ2 and GT1.
This extends to N bits but the timing may be something like O(n).
To get the timing down to O(logbase2(n)) takes a bit more work because we have to compute the EQ's in a tree structure.

I would think this is just one possible implementation there must be better ones.
Since the paradigm seems to have changed to using transistors rather than gates, maybe you can do it with transistors better. I was just going with the original idea of doing one bit multiple times and combining the outputs. EQ is simpler though.

Of course we have not yet thought about using a microcontroller. A lot can be done with that basic building block. That would be another paradigm shift though I guess ;)
 
Last edited:

MrAl

Joined Jun 17, 2014
13,704
No, you just need to pay a bit more attention to subcontexts.

I responded to your claim that you can simplify an implementation by going to the Boolean expression, simplifying that, and then using the gates that the simplified expression suggests.

I said that doing that was easier said than done and then provided an example where that was not the case. That example was nothing more than an XOR function.
I am not sure what you mean here, but I was just referring to how we went from using gates to using just transistors. I was never using lone transistors I was always using gates, that's all.
Your transistor workings are still interesting though.

I had thought that you just wanted the Boolean simplification also and application using gates. I actually wanted to use a PROM because that is the simplest implementation for any number of bits within reason. I was not thinking about creating an IC chip either.
 

WBahn

Joined Mar 31, 2012
32,840
Hello again,

What you you mean "you can't" ? This is just logic. If it is logic you can do anything :)
The key is that I said you can't just CHAIN them together.

Give me enough NAND gates and I can implement any Boolean logic function you want, including an entire computer, complete with memory. But that is not done by CHAINING a bunch of NAND gates together.

A logic chain is a circuit topology that consists of a bunch of identical blocks in which one feeds the next, along with the next bit(s) (pun intended) of data to be processed. It is like links in a chain, hence the name.

Perhaps an example will make the distinction clear enough to put us on the same page.

Consider making a 8-bit wide AND gate.

One way to do this is to use a CHAIN consisting of seven 2-bit wide AND gates:

1761350586290.png
Another way is to use a TREE using those same 2-bit wide AND gates:

1761350811506.png
Each topology has its pros and cons. The chain is more modular and lends itself to rapid expansion and orderly layout of the physical circuit, but the tree topology has considerably better speed performance, particularly as the number of bits increases.

A tree is not a chain and a chain is not a tree. I think they are mutually exclusive, though I don't know that I'm willing to assert that categorically -- I'm pretty sure that any circuit that would qualify as both would be pretty trivial, akin to a resistor connected across a voltage source putting both components in both series and parallel.

Like series and parallel resistors, the topology of a logic circuit implementations can exist that are neither chains or trees, even though they consist of nothing but identical parts. An example of that is the quad-NAND implementation of the XOR function.
1761351217114.png

Another example would be a ripple-carry adder implemented using nothing but half-adders. It can be done, but the resulting circuit is not a chain of half-adders. But if I use three half-adders to make a full-adder, then I can made the overall adders as a chain of full-adders. Of course, once we have our chain of full-adders, we are free to replace the internal implementation of a full-adder with anything we want, as long as we keep it functionally identical, without altering the fact that, at the level of the overall adder, it is implemented as a chain of full-adders.
 

Thread Starter

xox

Joined Sep 8, 2017
936
Your 1-bit comparator can't be chained because it has no way to bring the information from adjacent bits.

But, like I said in my original response in Post #2, you can use the same concept as a ripple-carry adder that is made up of half-adders and full-adders, except that you have a ripple-comparator that is made up of half-comparators and full-comparators.

For a half-comparator, you have the following truth table:

Code:
A B | EQ NE | LT GE | GT LE
0 0 |  1  0 |  0  1 |  0  1
0 1 |  0  1 |  1  0 |  0  1
1 0 |  0  1 |  0  1 |  1  0
1 1 |  1  0 |  0  1 |  0  1
Notice that in each pair of outputs, the second is just the logical negation of the first. Also, you only need one from each of two of the output pairs, you don't need all three. So you are free to choose from any of the twelve possible choices that result, whichever makes the implementation "better" according to whatever metric defines "better".

So let's think about this.

People want to just jump in and use EQ (or NE), which is the XNOR (or XOR) of the two inputs, but we've already seen that this is the black sheep of the logic family. So what if we used the other two columns instead.

In generating the XOR, using the more efficient quad-NAND implementation, what are the internal signals that get generators?

View attachment 357600
Code:
A B | C D E
0 0 | 1 1 1
0 1 | 1 1 0
1 0 | 1 0 1
1 1 | 0 1 1
So D is the LE signal and E is the GE signal, which gives us what we need and we don't need the final NAND gate at all!

View attachment 357603
If we use NOR gates instead of NAND gates, then the top output is the LT and the bottom is the GT.

In either case, we have 12 transistors and 2 gate delays.

The full-comparator has four inputs, namely the A and B from that bit position, but also the two comparison outputs from the prior bit. I'll let you take a shot at working out that logic.
Well, this has turned out to be quite a challenge! The best I could come up with so far:

The first module is what you might call a "half-comparator".

CMOS-half-comparator.png


That's 26 transistors, but also requires an additional 4 to do anything useful. Two of them are then used to make a 2-bit comparator:


CMOS-2-bit-comparator.png


All in all that's 60 transistors total. Which is not so great. But hey, at least it works. ¯\_(ツ)_/¯
 
Last edited:

MrAl

Joined Jun 17, 2014
13,704
Well, this has turned out to be quite a challenge! The best I could come up with so far:

The first module is what you might call a "half-comparator".

View attachment 357670


That's 26 transistors, but also requires an additional 4 to do anything useful. Two of them are then used to make a 2-bit comparator:


View attachment 357669


All in all that's 60 transistors total. Which is not so great. But hey, at least it works. ¯\_(ツ)_/¯
The heck with the transistors, I like that 'emoji" :)

I could not recreate the part that is the mouth though the closest I got with ANSI chars was:
¯\_("/)_/¯
 

WBahn

Joined Mar 31, 2012
32,840
Well, this has turned out to be quite a challenge! The best I could come up with so far:

The first module is what you might call a "half-comparator".

View attachment 357670


That's 26 transistors, but also requires an additional 4 to do anything useful. Two of them are then used to make a 2-bit comparator:


View attachment 357669


All in all that's 60 transistors total. Which is not so great. But hey, at least it works. ¯\_(ツ)_/¯
Correctness is the most important part -- it doesn't matter how fast, small, or cheap it is if it doesn't work.

It took me a while to figure out your approach and I thought I had done so, but after a closer inspection, I'm not sure. I would really help if you described the idea behind how your circuits work, a description of what the inputs and outputs mean, and truth tables of how they are intended to behave.

I'll try to walk though how my attempt to reverse engineer your circuit lead me to think and you can correct me where I've missed the mark.

My first impression was that your overall circuit is taking two 2-bit inputs, R and L, with the msb each being suffixed with H and the lsb suffixed with L. It is then producing two outputs, LG and RG, in which

LG = L>R?
RG = L<R?

With this supposition in mind, I then concluded (a conclusion that I am seriously questioning, however) that your half comparator answered the question

out = L>R (or L<R)

and that the idea was that you would swap L and R inputs to one of them to get the other, thus giving you both LT and GT outputs. But that doesn't seem to be what's happening since you aren't changing the L/R orientation, but instead taking the ones complement of one or the other. But perhaps this accomplishes the same thing.

My next point of concern is that your half-comparator circuit seems to be symmetric regarding L and R, meaning that they can be swapped without affecting the output. More troubling is that it appears that the bits in each position can be independently swapped without affecting the output. Either of these would render it incapable to properly distinguishing between L and R values properly. But perhaps my visual inspection is missing something.

To see one instance of this, consider just the LL and RL inputs to the half-comparator. The only place these two inputs go are to a 2-input NOR gate and it doesn't matter which one goes to which since NOR is symmetric. Assuming that LL is the lsb of the left number and RL is the lsb of the right, this means that the circuit will produce the same output for L=00, R=01 as it does for L=01, R=00.

I'll try to explore this a bit deeper later.
 

MrAl

Joined Jun 17, 2014
13,704
The key is that I said you can't just CHAIN them together.

Give me enough NAND gates and I can implement any Boolean logic function you want, including an entire computer, complete with memory. But that is not done by CHAINING a bunch of NAND gates together.

A logic chain is a circuit topology that consists of a bunch of identical blocks in which one feeds the next, along with the next bit(s) (pun intended) of data to be processed. It is like links in a chain, hence the name.

Perhaps an example will make the distinction clear enough to put us on the same page.

Consider making a 8-bit wide AND gate.

One way to do this is to use a CHAIN consisting of seven 2-bit wide AND gates:

View attachment 357658
Another way is to use a TREE using those same 2-bit wide AND gates:

View attachment 357659
Each topology has its pros and cons. The chain is more modular and lends itself to rapid expansion and orderly layout of the physical circuit, but the tree topology has considerably better speed performance, particularly as the number of bits increases.

A tree is not a chain and a chain is not a tree. I think they are mutually exclusive, though I don't know that I'm willing to assert that categorically -- I'm pretty sure that any circuit that would qualify as both would be pretty trivial, akin to a resistor connected across a voltage source putting both components in both series and parallel.

Like series and parallel resistors, the topology of a logic circuit implementations can exist that are neither chains or trees, even though they consist of nothing but identical parts. An example of that is the quad-NAND implementation of the XOR function.
View attachment 357660

Another example would be a ripple-carry adder implemented using nothing but half-adders. It can be done, but the resulting circuit is not a chain of half-adders. But if I use three half-adders to make a full-adder, then I can made the overall adders as a chain of full-adders. Of course, once we have our chain of full-adders, we are free to replace the internal implementation of a full-adder with anything we want, as long as we keep it functionally identical, without altering the fact that, at the level of the overall adder, it is implemented as a chain of full-adders.
Hello again,

Thanks for the detailed explanation that explains it all very well indeed.

The only question I have then is why did you bring up not being able to 'chain' if there happened to be another way?
You said: "The key is that I said you can't just CHAIN them together."
Why would that be so important, is it because it is easier to do a chain than some other way and that's an indication that it is not easy to do this in the first place?

Then, is there any general definition for 'chaining' because it looks like the solution I gave could also be called chaining, just at a higher level. That seems likely because each added bit requires outputs from previous logic states from performing on previous bits.

Then I guess we might ask, does it really matter if we can chain or not?
 

WBahn

Joined Mar 31, 2012
32,840
Hello again,

Thanks for the detailed explanation that explains it all very well indeed.

The only question I have then is why did you bring up not being able to 'chain' if there happened to be another way?
That subthread of the discussion is pretty clear, including an unbroken chain (no relation and no pun intended) of quotes and responses.

To wit, I didn't bring up chaining, I was responding to a claim that something could be chained that couldn't.

In this post, xox said, "Otherwise just chain together a bunch of 1-bit comparators to make larger modules and then put a gate on the final output for a "free" EQU/NEQ."

I responded to that in this post, saying, "Your 1-bit comparator can't be chained because it has no way to bring the information from adjacent bits."

To which you responded in this post, "And why not? If you can use an XOR gate you can use a split XOR gate. Multiple bits would be done the same way as with a regular XOR gate for equality, except now we also get GT and LT."

To which I responded in this post, "If you are just going to use an XOR gate to compare two bits (and split it to get GT and LT) that's fine. So now you have a black box that takes two 1-bit inputs and produces two outputs (or three). How do you then chain that to the next pair of bits? You can't, because you now have four inputs (or five), the two 1-bit inputs from the next pair, plus the two (or three) outputs from the prior pair."

To which you responded in this post, "What you you mean "you can't" ? This is just logic. If it is logic you can do anything"

To which I responded in this post, "The key is that I said you can't just CHAIN them together."
 

MrAl

Joined Jun 17, 2014
13,704
That subthread of the discussion is pretty clear, including an unbroken chain (no relation and no pun intended) of quotes and responses.

To wit, I didn't bring up chaining, I was responding to a claim that something could be chained that couldn't.

In this post, xox said, "Otherwise just chain together a bunch of 1-bit comparators to make larger modules and then put a gate on the final output for a "free" EQU/NEQ."

I responded to that in this post, saying, "Your 1-bit comparator can't be chained because it has no way to bring the information from adjacent bits."

To which you responded in this post, "And why not? If you can use an XOR gate you can use a split XOR gate. Multiple bits would be done the same way as with a regular XOR gate for equality, except now we also get GT and LT."

To which I responded in this post, "If you are just going to use an XOR gate to compare two bits (and split it to get GT and LT) that's fine. So now you have a black box that takes two 1-bit inputs and produces two outputs (or three). How do you then chain that to the next pair of bits? You can't, because you now have four inputs (or five), the two 1-bit inputs from the next pair, plus the two (or three) outputs from the prior pair."

To which you responded in this post, "What you you mean "you can't" ? This is just logic. If it is logic you can do anything"

To which I responded in this post, "The key is that I said you can't just CHAIN them together."
Ok thanks. So then how are you defining 'chain' here? Is that just referring to only one level of logic or something?
 
Top