From: Stephen D. Williams (sdw@lig.net)
Date: Mon Jun 12 2000 - 17:24:00 PDT
Ok, overkill answer here:
Eugene Leitl wrote:
> A somewhat unusual question, can someone point me towards resources on
> how to design local (only neighbouring bits change) bit flip Gray-ish
> codes, and how to design logics how to deal with them? Adders would be
> fine for starters.
>
> (This is about very long word and/or short clock arithmetics).
There is a standard Gray code, and it's compliment although I'm not sure how
standard it is.  I've used Gray Code in a bulb-forming machine to encode the
shaft angle on the rotary body that moved the collets holding the quartz glass
tubes being formed by H-O2 torches and molds...
I've also seen code that converts between gray code and twos compliment,
here's one version:
http://fritter.phyast.pitt.edu/~jm/cprogs/bin2g.html
Binary to Gray conversion
      This program takes a hexadecimal number which is binary and converts it
to a gray coded number. This program is designed to work for
numbers with fewer than 8 bits.
Sample compilation and output is below.
#include < stdio.h>
int main(int args, unsigned char *argc[]) {
        unsigned char num, gnum;
        int j, bit,numbits=8;
        unsigned int mask ;
        if (args!=2) {
           printf("Usage: bin2g HexBinaryNumber\n");
           return(-1);
        }
        if (args>2) {
            printf("Second argument ignored\n");
        }
        num = (unsigned char ) strtoul(argc[1],(char **)NULL, 16);
/*      bin2g is for numbers with bits fewer than 8, it works for any number
of bits, but the g2bin depends on the number of bits, currently, 8 */
        if (num > 0xff) {
                printf("Number must be smaller than 8 bits\n");
                return(-1);
        }
/* Calculate the grey code equivalent */
        gnum = num ^ (num >> 0x01);
        printf("Decimal binary num is %lu\n", num);
        printf("Decimal grey equivalent  is %lu\n", gnum);
        printf("Binary Number     Grey code number     \n");
        printf("  ");
        bitDump(&num, &numbits);
        printf("\t \t");
        bitDump(&gnum, &numbits);
        printf("\n");
        return(0);
        }
/*      bitDump function takes the number and the number of bits and prints
   the binary equivalent of the number  */
        int bitDump(unsigned char *num, int *numbts){
          int j;
          unsigned long int mask;
          int bit;
          mask = 0x80;
          for (j=0;j<*numbts;j++) {
                bit =(mask & *num) ? 1 : 0;
                printf("%d", bit);
                mask >>=1;
          }
        return(0);
        }
And g2b.c:
#include <stdio.h>
int main(int args, unsigned char *argc[]) {
        unsigned char num, gnum;
        int j, bit,numbits=8;
        unsigned int mask ;
        if (args!=2) {
        printf("Usage: g2bin GreyCodeNumber\n");
        return(-1);
                }
        gnum=(unsigned char) strtoul(argc[1], (char **)NULL, 16);
#ifdef DEBUG
        printf("Grey number is 0x%02x\n", gnum);
#endif
        if (gnum > 0xff) {
                printf("Number must be smaller than 8 bits\n");
                return(-1);
        }
        num = gnum ^ (gnum >> 0x01) ^ (gnum >> 0x02) ^ (gnum >> 0x03)
        ^ (gnum >> 0x04) ^ (gnum >> 0x05) ^ (gnum >> 0x06) ^ (gnum >> 0x07);
        printf("Decimal binary num is %lu\n", num);
        printf("Decimal grey equivalent  is %lu\n", gnum);
        printf("Grey code number     Binary Number\n");
        printf("  ");
        bitDump(&gnum, &numbits);
        printf("\t \t");
        bitDump(&num, &numbits);
        printf("\n");
        return(0);
        }
        int bitDump(unsigned char *num, int *numbts){
          int j;
          unsigned long int mask;
          int bit;
          mask = 0x80;
          for (j=0;j<*numbts;j++) {
                bit =(mask & *num) ? 1 : 0;
                printf("%d", bit);
                mask >>=1;
          }
        return(0);
        }
Or another:
http://www.progsoc.uts.edu.au/~telford/reference/algorithm/grey_code.text
As lookup table:
Grey    Bin     Dec
0000    0000    0
0001    0001    1
0011    0010    2
0010    0011    3
0110    0100    4
0111    0101    5
0101    0110    6
0100    0111    7
1100    1000    8
1101    1001    9
1111    1010    10
1110    1011    11
1010    1100    12
1011    1101    13
1001    1110    14
1000    1111    15
1000    0000    16
1001    0001    17
1011    0010    18
1010    0011    19
1110    0100    20
1111    0101    21
1101    0110    22
1100    0111    23
1100    1000    24
1101    1001    25
1111    1010    26
1110    1011    27
1010    1100    28
1011    1101    29
1001    1110    30
1000    1111    31
As state transitions (or limit cycles):
((0 0)
 (1 1)
 (2 3 2)
 (4 6 5 7 4)
 (8 12 10 15 8)
 (9 13 11 14 9)
 (16 24 20 30 17 25 21 31 16)
 (18 27 22 29 19 26 23 28 18))
/*
 * binary to grey code converter
 */
void binprint( int x )
{
        printf( "%c%c%c%c%c%c%c%c (%d)\n",
                        x & 0x0080 ? '1' : '0',
                        x & 0x0040 ? '1' : '0',
                        x & 0x0020 ? '1' : '0',
                        x & 0x0010 ? '1' : '0',
                        x & 0x0008 ? '1' : '0',
                        x & 0x0004 ? '1' : '0',
                        x & 0x0002 ? '1' : '0',
                        x & 0x0001 ? '1' : '0',
                        x );
}
int b2g( int b ) { return( b ^ ( b >> 1 )); }
int g2b( unsigned int b )
{
        int i, g = 0;
        for( i = 0; i < 32; i++ )
        {
                g ^= b;
                b >>= 1;
        }
        return( g );
}
int main( int argc, char *argv[])
{
        int i;
        for( i = 1; i < argc; i++ )
        {
                char *p;
                int n;
                n = strtol( argv[ i ], &p, 0 );
                if( p > argv[ i ])
                {
                        printf( "Input=" );
                        binprint( n );
                        printf( "bin->grey=" );
                        binprint( b2g( n ));
                        printf( "grey->bin=" );
                        binprint( g2b( n ));
                }
                else
                {
                        printf( "??? %s ???\n", argv[ i ]);
                }
        }
        return( 1 );
}
2600 Driving controller used Gray Code:
http://www.videogames.org/2600Stuff/DrivingControllers
Micromachined:
http://itri.loyola.edu/mems/c6_s4.htm
Cool article about async clocks and Grey Code addressing:
http://www.isdmag.com/Editorial/2000/design0003.html
How about some VHDL to implement it?  (I can only get a general idea from the
VHDL, but looks very interesting.)
http://www.xilinx.com/products/spartan2/recipes/rec009.htm
On rotary encoders:
http://www.ubasics.com/adam/electronics/doc/rotryenc.shtml
sdw
-- Insta.com - Revolutionary E-Business Communication sdw@insta.com Stephen D. Williams Senior Consultant/Architect http://sdw.st 43392 Wayside Cir,Ashburn,VA 20147-4622 703-724-0118W 703-995-0407Fax Jan2000
This archive was generated by hypermail 2b29 : Mon Jun 12 2000 - 17:28:33 PDT