
Gray Code - stansmith
http://www.datagenetics.com/blog/november32014/index.html
======
smoyer
Coming from a embedded systems background (mostly in the telecommunications
sector), I have a deep love for Gray Code. My fondest memory is teaching a
group of software engineers how "us hardware guys" do logic minimization.

Imagine a set of deeply nested if-then-else conditions that are dependent upon
a fixed set of boolean flags - this is pretty common in a state machine.
Reducing those conditions to a formula that calculates a boolean value is
often far less taxing on a small uC.

So I brought out one of my Electrical Engineering books (The Art of
Electronics by Horowitz and Hill), let them each read the section on Karnaugh
Maps [1] and then ran through some examples using their decision networks.
Watching those light bulbs come on was one of the favorite events in my
career.

[1]
[https://en.wikipedia.org/wiki/Karnaugh_map](https://en.wikipedia.org/wiki/Karnaugh_map)

~~~
andrewjkerr
Hah! I remember learning about K-Maps in my Digital Logic class and it blew my
mind. Gotta love them.

------
schoen
This is such a beautiful explanation! And I love the shaft orientation
detector example.

The biggest effect that Gray code had on my life was when it helped me pass an
entrance exam to a math camp when I was pretty young (younger than most other
students), because one of the questions on the entrance exam was "can you
prove that there is or isn't a Hamiltonian circuit on any n-dimensional
hypercube?".

The Hamiltonian path is a path that visits every node once, and a Hamiltonian
circuit does this and also returns to the starting point.

[https://en.wikipedia.org/wiki/Hamiltonian_path](https://en.wikipedia.org/wiki/Hamiltonian_path)

Well, I knew about the binary Gray code from Martin Gardner (in his book
_Knotted Doughnuts and Other Mathematical Entertainments_ ), and I realized
that if you think of an n-bit number as a coordinate in n-dimensional space
(like 10101110 is the coordinate (1, 0, 1, 0, 1, 1, 1, 0)), then the n-bit
binary Gray code is already a description of a Hamiltonian cycle on the unit
n-dimensional hypercube.

It tells you how to trace the path, because it tells you which vertices to go
to in which order. Every transition from one number to the next is an edge of
the cube because it involves changing exactly one bit (so, exactly one
dimension), which is exactly what defines the edge of a cube (it's a movement
in exactly one dimension). You visit every vertex because the Gray code
includes every number, and as this linked article says, the default Gray code
is cyclic and comes back to the original starting point at the end.

We know that there's a Gray code for any number of bits because there is a
recursive reflective procedure for constructing them to any length (as
described in this article): take the (n-1)-bit Gray code, write it forwards
prefixed with 0 and then backwards prefixed with 1, and you have an n-bit Gray
code. This also has a nice geometric interpretation, which is that given a
Hamiltonian circuit on an (n-1)-dimensional hypercube, you can do it on the
"lower" hypercube, go "up", do it backwards, and then come "down", and now
you've created a Hamiltonian circuit on the larger n-dimensional hypercube.

This answer let me pass the test and get into the math camp, but I found it
pretty difficult when I actually went, I think because I didn't exactly come
up with this answer "on my own": Martin Gardner did a ton of the work for me
in teaching me about Gray codes, and I had already been thinking about the
isomorphism between binary numbers and hypercubes before for some reason.

------
Marcus10110
This is a fundamental in FPGAs. The mode where the bit is unstable is called
metastability. Most FPGA tools can automatically infer gray code for state
machine states, and pretty much all cross clock domain FIFOs will use grey
code to indicate where the read and write pointers are located.

~~~
schoen
I remember someone (but not whom or where: maybe on HN or maybe a blog post)
saying that all digital systems that accept and quantize analog input will
have _some_ analog input conditions with consequences that persist and extend
arbitrarily far into the digital part of the system (so that theoretically you
could cause an OS on a digital computer to crash just by pressing a key on the
keyboard at the _exact_ right time). Does anyone remember where this
observation appeared, and is anyone's familiarity with metastability enough to
clarify how accurate or inaccurate this description is?

~~~
bkirwi
There you go.[0] I believe it's called the 'arbiter problem' in that context,
and your description seems basically correct.

[0]: [http://research.microsoft.com/en-
us/um/people/lamport/pubs/b...](http://research.microsoft.com/en-
us/um/people/lamport/pubs/buridan.pdf)

~~~
Animats
Yes. This is a well known problem. See
([https://en.wikipedia.org/wiki/Arbiter_[electronics]](https://en.wikipedia.org/wiki/Arbiter_\[electronics\])).
It's not possible to build an arbiter which will reliably decide who wins in a
fixed time. It is, however, possible to design one which can detect that the
arbiter hasn't stabilized yet and delays until it has. All multiprocessor
shared-memory systems need this.

------
ddingus
Great piece! I enjoyed it.

The author comments: It's possible to generate Gray codes without this
restriction (though to be honest, I can't understand the value of this, as the
step-change on the warp around would experience the exact problem we are
trying to solve!)

Linear encoders seems to me a perfect application.

~~~
asynchronous13
But a linear encoder would work with a Gray code that had the restriction AND
it would work with a Gray code that did not have the restriction. So there's
no benefit for the linear encoder.

~~~
ddingus
What if it's encoded with absolute values, not relative?

------
apitheia
With ternary grey code, only one digit is changed at a time, but sometimes
that change can be more than one value, why isn't ternary ordered so that each
digit only changes by at most 1 number? for example:

    
    
       0 → 000 | 000
       1 → 001 | 001
       2 → 002 | 002
      10 → 012 | 012
      11 → 010 | 011
      12 → 011 | 010
      20 → 021 | 020
      21 → 022 | 021
      22 → 020 | 022
     100 → 120 | 122
     101 → 121 | 121
     102 → 122 | 120
     110 → 102 | 110
     111 → 100 | 111
     112 → 101 | 112
     120 → 111 | 102
     121 → 112 | 101
     122 → 110 | 100
     200 → 210 | 200
     201 → 211 | 201
     202 → 212 | 202
     210 → 222 | 212
     211 → 220 | 211
     212 → 221 | 210
     220 → 201 | 220
     221 → 202 | 221
     222 → 200 | 222

~~~
a1369209993
The middle column _is_ changing by at most one number. Furthermore, it's
changing by at most one number always in the same direction, a feature not
shared by the right column. (The direction thing doesn't matter for binary
grey codes, since 1 + 1 = 1 - 1 = 0 and 0 + 1 = 0 - 1 = 1.)

------
fintler
I still think the most interesting thing about gray codes is the relationship
to hilbert curves. It's really useful for figuring out locality with a cheap
calculation (axes to/from transpose).

------
Throwaway1224
I use gray code to generate sobol sequences, which are psuedo random number
sequences that help you approximate a distribution more quickly than purely
random sequences.

------
fredsted
A great example of a useful article that keeps me reading HN.

------
IshKebab
If you liked this, google "single track gray codes".

~~~
jonsen
I've used it once making a DRAM refresh controller. That was almost forty
years ago before DRAMs came with refresh circuitry build in and before you
could get dedicated chips for it. I made this 6-state sequencer

    
    
      ABC -> A'B'C'
    
      000 -> 100 -> 110 -> 111 -> 011 -> 001 -> 000 -> ...
    

This sequence requires minimal hardware to program

    
    
      A' = not(C)   B' = A   C' = B
    

Also easy to decode the states for control signals

    
    
      000 = not(A) & not(C)
    
      100 = A & not(B)
    
      110 = B & not(C)
    
      etc.
    

I remember this especially because I made a bug. I forgot false state
prevention. If the circuit starts randomly at power up, it may enter this
sequence

    
    
      010 -> 101 -> 010 -> 101 -> 010 -> 101 -> ...
      

and it did at one test.

------
AndyNemmity
There was an article about computers optimizing a card trick earlier this
week, and it was using Gray code.

------
EugeneOZ
What about to add control digits?

------
stansmith
There are many, many, other cool articles on the site.

[http://www.datagenetics.com/blog.html](http://www.datagenetics.com/blog.html)

Once you start reading, you'll spend the rest of the day!

