From: Michael on
Hi there - I am continuing to attempt to learn VHDL this weekend!
Currently I'm trying to interface to the quadrature encoder on my
Spartan 3E Starter Kit. It outputs normal quadrature signals. So, I
tried to write a very simple bit of code for this purpose, which just
checks which edge on which signal occurred and then checks the state
of the other signal and infers if the count should be incremented or
decremented from that. My code is at the bottom of my post.

In theory this method of quadrature decoding should work perfectly,
unless I'm forgetting something. But for some reason which I'm afraid
I don't understand this is not synthesizable. I liked the idea of
using this method for quadrature decoding as it didn't require me to
deal with storing the previous state - the use of the falling_edge()
and rising_edge() functions did that for me. Xilinx ISE help brought
me to this page: http://www.xilinx.com/support/answers/14047.htm.
However, I don't have any embedded 'event statements, or any 'event
statements at all, for that matter (unless again I'm missing
something).

What exactly am I doing wrong, and is there a way to fix it? Thanks so
much!

-Michael

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;

entity hello_world is
port (
clk, enc_a, enc_b : in std_logic;
switches : in std_logic_vector (3 downto 0);
led : out std_logic_vector (7 downto 0)
);
end hello_world;

architecture rtl of hello_world is
signal cnt : unsigned (30 downto 0);
signal encval : unsigned (7 downto 0);
signal enccnt : unsigned (7 downto 0);
begin
process(clk)
begin
if rising_edge(clk) then
cnt <= cnt + 1;
encval <= "000000" & enc_b & enc_a;
end if;
end process;
process (enc_a, enc_b)
begin
if (rising_edge(enc_a) and enc_b = '1') then
enccnt <= enccnt - 1;
elsif (rising_edge(enc_a) and enc_b = '0') then
enccnt <= enccnt + 1;
elsif (falling_edge(enc_a) and enc_b = '1') then
enccnt <= enccnt + 1;
elsif (falling_edge(enc_a) and enc_b = '0') then
enccnt <= enccnt - 1;
elsif (rising_edge(enc_b) and enc_a = '1') then
enccnt <= enccnt + 1;
elsif (rising_edge(enc_b) and enc_a = '0') then
enccnt <= enccnt - 1;
elsif (falling_edge(enc_b) and enc_a = '1') then
enccnt <= enccnt - 1;
elsif (falling_edge(enc_b) and enc_a = '0') then
enccnt <= enccnt + 1;
end if;
end process;

led <= std_logic_vector(cnt(30 downto 23)) when switches(0)='0' else
std_logic_vector(encval);

end rtl;
From: Mike Treseler on
Michael wrote:

> What exactly am I doing wrong

1. Using inputs as clocks.
2. Using two clocks in a process.

and is there a way to fix it?

Declare as many registers as you need,
but put everything in your first process.
Have a look at my examples.

-- Mike Treseler


From: Frank Buss on
Michael wrote:

> In theory this method of quadrature decoding should work perfectly,
> unless I'm forgetting something.

The quadrature encoder on the Spartan 3E Starter Kit is mechanical, you
should implement some debouncing. Maybe some simple holdoff is sufficient,
but if there are fast crosstalk glitches, a simple low pass filter (in
VHDL) would be a good idea, too.

--
Frank Buss, fb(a)frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Michael on
On Apr 20, 6:42 pm, Mike Treseler <mike_trese...(a)comcast.net> wrote:
> Michael wrote:
> > What exactly am I doing wrong
>
> 1. Using inputs as clocks.
> 2. Using two clocks in a process.

So rising_edge() and falling_edge() can only be used with clocks?

> and is there a way to fix it?
>
> Declare as many registers as you need,
> but put everything in your first process.

Why does everything have to be in one process? Is there a reason it's
objectionable to have one process that is sensitive to only my clock
and one process that's only sensitive to a couple inputs? And so
you're suggesting I go with a state based approach? Or something else?
What are these extra registers for?

> Have a look at my examples.
>
> -- Mike Treseler

What examples are you referring to?

Thanks!

-Michael
From: Michael on
On Apr 20, 6:50 pm, Frank Buss <f...(a)frank-buss.de> wrote:
> Michael wrote:
> > In theory this method of quadrature decoding should work perfectly,
> > unless I'm forgetting something.
>
> The quadrature encoder on the Spartan 3E Starter Kit is mechanical, you
> should implement some debouncing. Maybe some simple holdoff is sufficient,
> but if there are fast crosstalk glitches, a simple low pass filter (in
> VHDL) would be a good idea, too.
>
> --
> Frank Buss

Hi Frank - I thought about debouncing and - unless I'm being dumb - I
think as long as only one input is changing at a time, bounce won't
affect this approach in the steady state. I mean that if I turn it 4
counts, it might count something like 0 1 2 3 2 3 4 3 4. But the final
value will be correct.

-Michael