gray counter and compare value

O

Olaf

Hi,

I'm using the gray counter at comp.lang.vhdl FAQ 4.2.29, extended with a
reset.

Anyway, I would like use it as a water level counter. Therefore I need
to compare the counter value against one top value to hit an action. The
top value is in hex/bin format.

Here the question: Does exist a VHDL convert function to en-/decode the
hex into gray code? How does it look? Since the mentioned Gray Code
Counter Model has a generic size, it should be also generic.

I would know only a non-generic solution using a LUT ROM.

Thanks
Olaf
 
K

KJ

Olaf said:
Hi,

I'm using the gray counter at comp.lang.vhdl FAQ 4.2.29, extended with a
reset.

Anyway, I would like use it as a water level counter. Therefore I need
to compare the counter value against one top value to hit an action. The
top value is in hex/bin format.

Here the question: Does exist a VHDL convert function to en-/decode the
hex into gray code? How does it look? Since the mentioned Gray Code
Counter Model has a generic size, it should be also generic.

I would know only a non-generic solution using a LUT ROM.
Since this 'top value' is a constant it can be computed using a VHDL
function. What you need to do is create a function (calling it
'Compute_Top' for purposes of this discussion) where you pass it a parameter
that is the number of bits in your gray code counter. This function would
return the value that you would then use to compare against. Below is some
pseudo code to use as a general guide to follow.

entity My_Entity generic(nBits: natural) is
-- list your ports
end My_Entity;

architecture RTL of My_Entity is
function Compute_Top(nBits: natural) return std_ulogic_vector is
variable Gray_Code_Value: std_ulogic_vector(nBits - 1 downto 0) :=
(others => '0'); -- Assuming you want to start here
begin
for i in 0 to 2**nBits - 1 loop
Gray_Code_Value := -- Put your code to update to the next gray
code value here
end loop;
return(std_ulogic_vector(Gray_Code_Value));
end function Compute_Top;

constant TOP_VALUE: std_ulogic_vector(nBits - 1 downto 0) :=
Compute_Top(nBits);
signal Gray_Code_Counter: std_ulogic_vector(nBits - 1 downto 0);
begin
.....
if (Gray_Code_Counter = TOP_VALUE) then
-- do whatever it is you want to do here when the gray code counter
reaches max
.....

The above code is fairly straightforward, but when 'nBits' get large, you
might notice that it takes quite a while for the top value to get computed
(even though it is only done once). A faster way to compute the 'top' value
is to run the gray code counter logic in reverse. That way instead of
looping through 2**n - 1 times to get your constant, you simply run once
through computing what the previous gray code would be which is the code
that would be preceeding "0" which would be the 'top' value.

Kevin Jennings
 
M

Mirko Liss

Olaf:
Here the question: Does exist a VHDL convert function to en-/decode the
hex into gray code? How does it look? Since the mentioned Gray Code
Counter Model has a generic size, it should be also generic.


The gray code of the number x is:

x XOR (x shift_right 1)


You can get the inverse gray code by applying this formula repeatedly.
With 64bit words, you need to apply it 63 times. That's simple and
easily adjustable to another word size, but rather slow.

This version of the inverse gray code of 64 bit code works somewhat
faster:

x := x XOR (x shift_right 1);
x := x XOR (x shift_right 2);
x := x XOR (x shift_right 4);
x := x XOR (x shift_right 8);
x := x XOR (x shift_right 16);
x := x XOR (x shift_right 32);

These statements can be reordered as you like.
 
O

Olaf

Hi,

thanks for your replay. Would this function do the job (untested)?

function hex2gray (signal hex : in std_logic_vector) return
std_logic_vector is
constant WIDTH : integer := hex'length;
variable x : unsigned(hex'range) := unsigned(hex);
begin

assert (WIDTH > 1) and (WIDTH < integer'high)
report "Invalid Bit Size"
severity failure;

for n in 0 to WIDTH-1 loop
x := x XOR shift_right(x, 2**n);
end loop;

return std_logic_vector(x);

end function hex2gray;

Thanks
Olaf
 
A

Ahmed Samieh

Hi,

thanks for your replay. Would this function do the job (untested)?

function hex2gray (signal hex : in std_logic_vector) return
std_logic_vector is
constant WIDTH : integer := hex'length;
variable x : unsigned(hex'range) := unsigned(hex);
begin

assert (WIDTH > 1) and (WIDTH < integer'high)
report "Invalid Bit Size"
severity failure;

for n in 0 to WIDTH-1 loop
x := x XOR shift_right(x, 2**n);
end loop;

return std_logic_vector(x);

end function hex2gray;

Thanks
Olaf

this function will do it (tested) :

FUNCTION hex2gray(hex : std_logic_vector)
RETURN std_logic_vector IS
VARIABLE x : unsigned(hex'RANGE) := unsigned(hex);
BEGIN
x := x XOR shift_right(x,1);
RETURN std_logic_vector(x);
END FUNCTION hex2gray;

look at http://en.wikipedia.org/wiki/Gray_code

Ahmed Samieh
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top