Gray Code Fundamentals – Part 2

The term Gray code is typically used to refer to a binary sequence in which only a single bit changes value when transitioning between adjacent states.

In this, the second installment of our mini-series, we take a look at generating Gray codes and also Binary-to-Gray and Gray-to-Binary conversions.

Just to refresh our memories, in Part 1 we considered the concept of Gray codes in general; in Part 3 we will ponder the generation of sub-2n Gray code count sequences; in Part 4 we will consider the generation of sub-2n sequences with consecutive values; and in Part 5 we will take a leap into the unknown to wrestle with the concept of "n-ary" (non-Boolean) Gray codes.

Generating a Gray code
Before we start, let's briefly remind ourselves as to the difference between a standard binary count and one of the many possible Gray code equivalents as illustrated in Figure 2-1 (we'll use 4-bit sequences for the purpose of these examples).

Commencing with a state of all zeros, a Gray code can be generated by
always changing the least significant bit that results in a new state.
An alternative method which may be easier to remember and use is as
follows:

Commence with the simplest Gray code possible; that is, for a single bit.

Create a mirror image of the existing Gray code below the original values.

Prefix the original values with 0s and the mirrored values with 1s.

Repeat steps 2) and 3) until the desired width is achieved.

An example of this "mirroring process" used to generate a 4-bit Gray
code is shown in Figure 2-2 (it might be more correct to call this a
"recursive reverse-and-prefix" technique).

Figure 2-1. Binary versus Gray codes (4-bit count sequences).

Figure 2-2. Using a mirroring process to generate a 4-bit Gray code.

Binary-to-Gray and Gray-to-Binary conversions
It is often required to convert a binary sequence into a Gray code or vice versa. Such converters are easy to create and are of especial interest here due to their affinity to Reed-Müller implementations (I’ll do an article on Reed-Müller Logic after I’ve finished this mini-series on Gray codes). First let's consider a Binary-to-Gray converter as illustrated in Figure 2-3.

Figure 2-3. Binary-to-Gray converter.

The checkerboard patterns of 0s and 1s in the Karnaugh Maps immediately indicate the potential for Reed-Müller implementations. Similar checkerboard patterns are also seen in the case of a Gray-to-Binary converter as illustrated in Figure 2-4.

Figure 2-4. Gray-to-Binary converter.

It's very quiet in here!
Gray code counters are of interest for a variety of applications, such as representing the state variables in state machines or acting as pointers in First-In First-Out (FIFO) memories. This is because only one output bit is ever toggling at a time in a Gray code "counter", as opposed to possibly multiple bits in a binary counter.

In addition to preventing intermediate states, Gray code counters consume only half the power of an equivalent binary counter and they generate correspondingly less noise. Actually, while the power and average noise difference between a Gray and a binary counter asymptotically approaches two, the peak noise difference is equal to the number of bits, since a Gray counter toggles only one bit at a time while a binary counter toggles all of its bits simultaneously two times over the course of a full-count cycle with fewer bits toggling proportionally more times.

Actually implementing a Gray code counter
Before we proceed, let's briefly ponder the process of actually implementing a Gray code counter. Just to give us something to play with, let's suppose we wish to generate a Gray code that can be used to index into a memory array. For example, suppose we're implementing something sort-of like a FIFO, and that (for the purposes of this example), we simply wish to keep on cycling through all of the memory locations. The point is that we aren't particularly concerned as to the order in which we address the locations, just that we sequence our way through them visiting each one a single time before returning to the first location to do it all over again.

Assuming that we're dealing with a 16-word memory array, one scenario [as illustrated in Figure 2-5 (a)] starts with a standard 4-bit binary counter, in which the current count value is passed through a chunk of feedback logic to generate the next count value. Also, the current count value is passed through a Binary-to-Gray converter (as introduced in Figure 2-3) to generate a corresponding Gray code.

Figure 2-5. Two techniques for generating a Gray code sequence.

The alternative technique [as illustrated in Figure 2-5(b)] is to simply create a Gray code counter from the ground up. Now, if we were to compare the binary counter (including binary-to-Gray converter) with the Gray code counter, there are several things I don't know off the top of my head:

How many logic gates are required for each implementation?

How many levels of logic gates are there in the two feedback paths?

What's the (relative) maximum frequency of each type of counter?

What's the (relative) switching activity, noise, and power consumption of each type of counter?

I tell you, I'm constantly amazed by the number of things I don't know. Now, we could work this out, but I'm a tad busy at the moment, so we'll leave the pondering of these posers as an exercise for the reader (grin). Of course, if you do work all of this out, it would make the basis for a great follow-up article that I could post under your name here on Programmable Logic Designline.

But we digress… in Part 3 we will take a look at generating sub-2n Gray code count sequences.

About the AuthorClive “Max” Maxfield is president of Maxfield High-Tech Consulting and editor of the EE Times Programmable Logic Designline. After receiving his B.Sc. in Control Engineering in 1980 from Sheffield Hallam University, Sheffield, England, Max began his career as a designer of central processing units for mainframe computers. Over the years, he has designed and built all sorts of interesting "stuff" from silicon chips to circuit boards and brainwave amplifiers to Steampunk “Display-O-Meters”. Max has also been at the forefront of Electronic Design Automation (EDA) for more than 20 years.

@BSc Student: i am a bit stuck on how to derive the state map for the conversion which i would then use to design the sequeantial circuit.

I think there are two things here. let's say you have four registers that are used to hole your BCD count. Let's call them b3, b2, b1, and b0. So the first thing you need is a block of combinatorial logic in the feedback path to generate the next BCD value in the count sequence.

That is, you take the outputs from b3, b2, b1, and b0, feed them into your block of logic, and use the outputs from this logic to drive the inputs to your registers, so every time you get a clock pulse the BCD counter counts.

The next thing you need is another block of combinatorial logic that takes the outputs from the b3, b2, b1, and b0 registers and generates your 4-bit Gray code -- let's call these bits g3, g2, g1, and g0.

Take a look at my table -- let's start with g0. The only times this is a 1 corresponds to the BCD states of 1, 2, 7, and 8 (0001, 0010, 0111, and 1000). So we can say:

Hi Clive for yours interesting posts. I hope it would be in a better position to help. I am a final year engineering student and I am to design a sequential circuit which converts BCD to Gray code. Hope you will be able to help.

It may be easier for you to implement Gray counters with T-FF but for fully optimized equations that would not be the case. A good deal of it depends upon the native FF's available (T-FF's are usually permutations of native D or JK). From a logic point of view T's are easy, you write equations for when to change so MSB's are easy and narrow equations while LSB's are complex wide equations. Generally speaking JK's work best for logic reduction because they can essentially function as both D and T with many don't care states. As for power, there are two components, static power is process controlled while dynamic power is a linear function of toggles. Since a full sequence Gray counter asymptotically approaches 2 very quickly it's reasonable to say that they take half the power of a binary counter. For a full sequence Gray counter of n bits there are 2^n toggles while for a binary counter there are (2^(n+1))-2. Or to list binary power cost relative to Gray for n bits 2 through 8: 1.500, 1.750, 1.875, 1.938, 1.969, 1.984, 1.992
respectively.

Regarding the gray code counter, I found it easiest to use a "toggle" flip flop. The next state equations for an n-bit counter were:
ns(i) := (not cs(0)) and (not cs(1)) and ... (not cs(i-2)) and cs(i-1) and (not cs(i) xor cs(i+1) xor ... cs(n-1))
I believe that the gray code counter will always be larger (binary counter toggle enable is simply an AND of all of the lower bits), use more power and be more difficult to debug. We always use binary counters and convert when we need. BTW: make sure your converted signals are registered if they cross any clock domains, otherwise you loose the benefit of gray code.
Dave Simpson