Question : Gray Code Generator

On Mon, 29 Dec 1997 11:43:19 +0100, Andreas Doering

Quote:

>I did exactly this, just this morning, using synopsys FPGA-compiler.

>However, the resulting design is very slow, that is (for width = 8)

>up to 7

>logic levels (LUT) are passed with target archtitecture

>ALTERA FLEX10K,

>for -3 speed grade this results in around 30 ns delay, way

>too much.

If you are using FLEX10K, why not implement the 8 bit next state

conversion with an EAB configured as an 8 bit wide ROM?

I tried exactly the same brute force attempt as yourself, except I

wrote 256 case statements :

when "00000000" => result <= "00000001" ;

when "00000001" => result <= "00000011" ;

etc.

Synthesised to ORCA 2CxxA -3 speed grade and with a rough place &

route gave the register to register performance of 72 MHz.

Combinatorially, the critical path synthesised as a mux delay (two 5

input LUT's feeding a 2 input mux) followed by routing, followed by a

5 input function. So that's 2 levels of logic. (but the mux does do an

11 input function)

Quote:

>For a fast gray counter I would prefer a pipelined design with a

>redundand representation.

I thought a bit over this one, and the best I could come up with for

large length counters was to take an n-bit binary counter and generate

pre-calculators for where the gray bits change. Fortunately, the MSB

of the gray counter is just the MSB of your binary counter, but I

generated it anyway for completeness of the VHDL.

Maybe it's not the most elegant, but it works, (Modelsim says so after

running through the entire 16 bit count), is relatively extensible,

and seems to give reasonable speeds. (code at end of this post)

I put this to ORCA again, and got 54 MHz in a -3 speed grade, which

doesn't seem too bad for a 16 bit Gray count.

Hope this helps.

Stuart

-- 16 bit Gray counter using inversion selection.

library IEEE ;

use IEEE.Std_Logic_1164.ALL ;

use IEEE.Std_Logic_Arith.ALL ;

use IEEE.Std_Logic_Unsigned.ALL ;

entity gray IS

port ( clk, reset : IN bit ;

result : OUT std_logic_vector(15 downto 0) )

;

end gray ;

architecture behavioural of gray is

signal counter : std_logic_vector(15 downto 0) ;

signal invert : std_logic_vector(15 downto 0) ;

signal gray : std_logic_vector(15 downto 0) ;

begin

main_counter : process ( reset, clk )

begin

if (reset = '0') then

counter <= (others => '0') ;

elsif (clk'event and clk = '1') then

counter <= counter + '1' ;

end if ;

end process ;

inversion_generation : process ( counter )

begin

invert <= (others => '0') ;

if counter(0) = '0' then invert(0) <= '1' ;

end if ;

if counter(1 downto 0) = "01" then invert(1) <= '1' ;

end if ;

if counter(2 downto 0) = "011" then invert(2) <= '1' ;

end if ;

if counter(3 downto 0) = "0111" then invert(3) <= '1' ;

end if ;

if counter(4 downto 0) = "01111" then invert(4) <= '1' ;

end if ;

if counter(5 downto 0) = "011111" then invert(5) <= '1' ;

end if ;

if counter(6 downto 0) = "0111111" then invert(6) <= '1' ;

end if ;

if counter(7 downto 0) = "01111111" then invert(7) <= '1' ;

end if ;

if counter(8 downto 0) = "011111111" then invert(8) <= '1' ;

end if ;

if counter(9 downto 0) = "0111111111" then invert(9) <= '1' ;

end if ;

if counter(10 downto 0) = "01111111111" then invert(10) <= '1'

;

end if ;

if counter(11 downto 0) = "011111111111" then invert(11) <=

'1' ;

end if ;

if counter(12 downto 0) = "0111111111111" then invert(12) <=

'1' ;

end if ;

if counter(13 downto 0) = "01111111111111" then invert(13) <=

'1' ;

end if ;

if counter(14 downto 0) = "011111111111111" then invert(14) <=

'1' ;

end if ;

if counter(14 downto 0) = "111111111111111" then invert(15) <=

'1' ;

end if ;

end process ;

output_result : process ( reset, clk )

begin

if (reset = '0') then

gray <= (others => '0') ;

elsif (clk'event and clk = '1') then

gray <= ( gray xor invert ) ;

end if ;

end process ;

result <= gray ;

end behavioural ;

--

For Email remove "die.spammer." from the address