How to implement a Gray Code counter? 
Author Message
 How to implement a Gray Code counter?

How to implement a Gray code counter
--


ICQ : 135925467


Tue, 15 Mar 2005 15:05:58 GMT  
 How to implement a Gray Code counter?
How big?
ASIC or FPGA with dedicated carry chains?
Do you know what the gray count sequence is and can't figure out the
implementation or are you completely unfamiliar?
Do you just want a clock triggered counter?  Up and down?  Optical
encoder driven count?

The correlation from a binary count to a gray count value is simple (
assign gray_cnt = bin_cnt ^ bin cnt >> 1 ) so if you just need to pass a
gray code value across time domains, this is the simplest form of
generating a gray value.

If you need the native count format for a small counter (4 bits) I'd
probably go for a case statement.  If you need a large counter, the form
you need is a bit more involved but very attainable.  Do a
groups.google.com search in comp.lang.verilog and comp.arch.fpga and you
may get many hits.

- John_H

0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0
0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0
0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0

Quote:

> How to implement a Gray code counter
> --


> ICQ : 135925467



Wed, 16 Mar 2005 00:36:26 GMT  
 How to implement a Gray Code counter?

Quote:

> How to implement a Gray code counter

`timescale 1ns/100ps
module gray_counter (clk, aclr, ena, gray_code);
 parameter SIZE = 4;
 input clk, aclr, ena;
 output [SIZE-1:0] gray_code;

 reg [SIZE-1:0] gray_code;
 reg [SIZE-1:0] tog;
 integer i,j;


  if (aclr==1'b0) begin
   gray_code <= 0;
  end
  else begin
  if (ena==1'b1) begin
   tog = gray_code;
   for (i=0; i<=SIZE-1; i=i+1) begin
    tog[i] = 1'b0;
    for (j=i; j<=SIZE-1; j=j+1) begin
     tog[i] = tog[i] ^^ gray_code[j];
    end //j loop
    tog[i] = !tog[i];
    for (j=0; j<=i-1; j=j+1) begin
     tog[i] = tog[i] && !tog[j];
    end //j loop
   end //i loop
   tog[SIZE-1] = 1'b1;
   for (j=0; j<=SIZE-2; j=j+1) begin
    tog[SIZE-1] = tog[SIZE-1] && !tog[j];
   end //j loop;
   gray_code <= gray_code ^ tog;
  end //enabled
 end //sequential update
endmodule



Thu, 17 Mar 2005 05:13:20 GMT  
 How to implement a Gray Code counter?
First thanks for your answer.
I just work on ASIC for FIFO and I hope
to get the grey code with the clock affect directly.
My FIFOs will have different depth. So I want to find the method or arithmetic of generating grey code.
--


ICQ : 135925467


Thu, 17 Mar 2005 15:33:38 GMT  
 How to implement a Gray Code counter?
Since your goal is address transfer across time domains, perhaps the best way from a supportability
standpoint is to use a binary counter and do the conversion to gray in parallel.

From the suggestions Peter Alfke's made on comp.arch.fpga, it might be best to keep both a binary and gray
register set running in parallel.

wire [width-1:0] next_bin;
reg [width-1:0] bin, gray;
assign next_bin = bin + 1;

begin
  bin <= next_bin;
  gray <= next_bin ^ (next_bin >> 1);
end

This makes it much more obvious what's going on, allows the compiler to optimize well without going through
hoops.

If you need the minimalist implementation, Dane's code may give you what you want.

The idea behind gray code is that - for an up counter - the LSbit will toggle when the parity of the value
is even.  When the parity is odd, the bit where the next bit below is logic one and the remaining LSbits
are zero gets the toggle;  the exception is the MSbit where it will toggle whether the next bit below is a
one or a zero and all the remaining bits are zero.

0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
0 0 0 0 1 1 1 1^1 1 1 1 0 0 0 0^
0 0 1 1^1 1 0 0 0 0 1 1^1 1 0 0
0 1^1 0 0 1^1 0 0 1^1 0 0 1^1 0
e o e o e o e o e o e o e o e o

Conversion from gray back to binary is simply "bin[n] = ^gray[width-1:n]" for 0 <= n < width.
What would your compiler do if you define "bin" from the gray in the above manner to calculate the next_bin
in the first place?  Possibly some very ugly stuff, but who knows?

- John_H

Quote:

> First thanks for your answer.
> I just work on ASIC for FIFO and I hope
> to get the grey code with the clock affect directly.
> My FIFOs will have different depth. So I want to find the method or arithmetic of generating grey code.
> --


> ICQ : 135925467



Sat, 19 Mar 2005 04:30:38 GMT  
 How to implement a Gray Code counter?
A nice closed-form of the gray-to-binary conversion would make the experimental construct something like:

wire [width-1:0] bin, next_bin;
reg [width-1:0] gray;
assign bin = gray ^ (bin>>1);
assign next_bin = bin + 1;

  gray <= next_bin ^ (next_bin >> 1);

See what you get and decide for yourself!



Sat, 19 Mar 2005 04:56:21 GMT  
 How to implement a Gray Code counter?

Quote:

> How to implement a Gray code counter

The sequence can also be coded as a case statement in Verilog. I wrote
a quick and dirty program to generate the case statement and explore
various sequences (e.g. if they are circular). It can be downloaded
from:

wget http://gustad.com/pub/eda/jc.tgz
gzip -dc jc.tgz | tar xvf -
cd jc
make
: zener jc; ./jct 4
./jct is starting up
case 10'b0000: ns = 10'b0001;
case 10'b0001: ns = 10'b0011;
case 10'b0011: ns = 10'b0010;
case 10'b0010: ns = 10'b0110;
case 10'b0110: ns = 10'b0111;
case 10'b0111: ns = 10'b0101;
case 10'b0101: ns = 10'b0100;
case 10'b0100: ns = 10'b1100;
case 10'b1100: ns = 10'b1101;
case 10'b1101: ns = 10'b1111;
case 10'b1111: ns = 10'b1110;
case 10'b1110: ns = 10'b1010;
case 10'b1010: ns = 10'b1011;
case 10'b1011: ns = 10'b1001;
case 10'b1001: ns = 10'b1000;
case 10'b1000: ns = 10'b0000;
./jct is finishing up

The 10's have to be changed to 4's (your specified width) manually.

Disclaimer: I wrote this more than 8 years ago. There is no
documentation etc. It was never made to be published, but somebody
asked for it some time ago and I uploaded it and it's still there...

Petter
--
________________________________________________________________________
Petter Gustad         8'h2B | ~8'h2B        http://www.gustad.com/petter



Sun, 20 Mar 2005 06:00:07 GMT  
 How to implement a Gray Code counter?


Quote:
> First thanks for your answer.
> I just work on ASIC for FIFO and I hope
> to get the grey code with the clock affect directly.
> My FIFOs will have different depth. So I want to find the method or arithmetic of generating grey code.
> --


> ICQ : 135925467

  When I did this, I used regular counters to keep track of read/write pointers,
converted to greycode to send accross time domains, and converted back again to
regular counting for empty full checks etc.

converting a binary count to a grey code count is very easy

  grey_count[x:0] = binary_count[x:0] xor {0, binary_count[x:1]].

Do the inverse to go from grey to binary (it is a little more complicated
and left as a exercise for the reader).

This way you can get fast counters, comparitors for binary arithmatic, yet
have only single bit changes for going between time domains.

Ken



Sat, 19 Mar 2005 21:56:02 GMT  
 
 [ 8 post ] 

 Relevant Pages 

1. gray code counter in asyn FIFO design

2. Do gray code counters comsume less power

3. Gray Code Counter - Comments?

4. Gray code counters

5. Do gray code counters comsume less power

6. Source Code for Gray Counter

7. Gray Code Counter?

8. Gray code counters

9. 16 bit Gray Counter

10. RTL description of a 16Bit gray counter

11. Fw: Gray counter STRUCTURAL (VHDL)

12. Gray counter STRUCTURAL (VHDL)

 

 
Powered by phpBB® Forum Software