OpenCores
URL https://opencores.org/ocsvn/quadraturecount/quadraturecount/trunk

Subversion Repositories quadraturecount

[/] [quadraturecount/] [trunk/] [QuadratureDecoder.vhd] - Diff between revs 6 and 9

Show entire file | Details | Blame | View Log

Rev 6 Rev 9
Line 1... Line 1...
 
library ieee;
 
use ieee.std_logic_1164.all;
 
 
 
-- c2003 Franks Development, LLC
 
-- http://www.franks-development.com
 
-- !This source is distributed under the terms & conditions specified at opencores.org
 
 
 
--How we 'talk' to the outside world:
 
entity QuadratureDecoderPorts is
 
    port (
 
        clock :                 in std_logic;
 
        QuadA :                 in std_logic;
 
        QuadB :                 in std_logic;
 
        Direction :     out std_logic;
 
                CountEnable :   out std_logic
 
    );
 
end QuadratureDecoderPorts;
 
 
 
--What we 'do':
 
architecture QuadratureDecoder of QuadratureDecoderPorts is
 
 
 
        --local 'variables' or 'registers'
 
 
 
        --this runs our state machine: where are we in the decoding process?
 
        --the following constants describe each state
 
        --note that every possible state is not listed.  the unused states
 
        --are physically unreachable in a functioning quadratre device, given that the 
 
        --clock is fast enough to 'catch' each transition on the quadrature inputs
 
        --LR means left-right, RL = left-right.  Of course the two are reversed
 
        --if the two quadratre inputs are switched.
 
        signal state : std_logic_vector(3 downto 0);
 
        constant Wait0 : std_logic_vector(3 downto 0) := "0000";
 
        constant Wait1 : std_logic_vector(3 downto 0) := "0001";
 
        constant Count0 : std_logic_vector(3 downto 0) := "0010";
 
        constant Count1 : std_logic_vector(3 downto 0) := "0011";
 
        constant LR1 : std_logic_vector(3 downto 0) := "1001";
 
        constant LR2 : std_logic_vector(3 downto 0) := "1101";
 
        constant LR3 : std_logic_vector(3 downto 0) := "0101";
 
        constant RL1 : std_logic_vector(3 downto 0) := "0100";
 
        constant RL2 : std_logic_vector(3 downto 0) := "1100";
 
        constant RL3 : std_logic_vector(3 downto 0) := "1000";
 
 
 
        --this is a temp where the two quadrature inputs are stored
 
        signal Quad : std_logic_vector(1 downto 0);
 
 
 
        --as a single quadrature count is made up of several states, and the decoder
 
        --can remain in a given state indefinately (if the quadrature input
 
        --device is not 'moving'), so we need these 'gate-ing' variables
 
        --to keep us from counting on every clock when we sit idle in the 
 
        --'count' state; thusly, we just count on the first clock 
 
        --upon entering a 'count' state.
 
        signal counted : std_logic;
 
        signal counting : std_logic;
 
 
 
begin   --architecture QuadratureDecoder
 
 
 
process (clock)
 
 
 
        begin --(clock)
 
 
 
        if ( (clock'event) and (clock = '1') )  then --every rising edge
 
 
 
                --convert inputs from asynch to synch by assigning once on each rising edge of clock
 
                Quad(0) <= QuadA;
 
                Quad(1) <= QuadB;
 
 
 
                --we are not going to be counting on this clock by default
 
                CountEnable <= '0';
 
 
 
                --we are not in a 'count' state
 
                if (Counting = '0') then
 
 
 
                        Counted <= '0';   --haven't counted when not in count state
 
                        CountEnable <= '0';       --are not outputing a count either
 
 
 
                end if;
 
 
 
                --we are in a count state
 
                if (Counting = '1') then
 
 
 
                        if (Counted = '1') then   --note that this is covered by default, but is included for clarity.
 
                                CountEnable <= '0';        --already counted this one, don't output a count
 
                        end if;
 
 
 
                        if (Counted = '0') then     --we haven't counted it already
 
                                Counted <= '1';    --make sure we dont count it again on next clock
 
                                CountEnable <= '1';        --output a count!
 
                        end if;
 
 
 
                end if;
 
 
 
                -- run our state machine
 
                -- the state transitions are governed by the nature of reality -
 
                -- vis-a-vis this is what quadratre is.
 
                -- the '--?' are the physically un-reachable states.
 
                -- note that it is imperative that the clock be at least (4 I recal)
 
                -- times faster than the maximum transition rate on each quadratre
 
                -- input, or else transitions will occur in between clocks, corrupting
 
                -- the state of the decoder.  Put differently, the quadratre device must
 
                -- physically remain in each state for at least a single clock
 
                -- or state changes will not be 'captured' and decoder output will be bogus.
 
                -- which is substancially the case with any clock-based logic.
 
                -- the difference is that a normal glitch is any change in input which
 
                -- has duration less than a single clock, but in quadrature, as single
 
                -- transition of the actual device cases 4 transitions in the state,
 
                -- by design of the quadrature encoding process.
 
                case state is
 
 
 
                        when Wait0 =>
 
                                if (Quad = "00") then state <= Wait0; end if;
 
                                if (Quad = "01") then state <= RL1; end if;
 
                                if (Quad = "10") then state <= LR1; end if;
 
                                if (Quad = "11") then state <= Wait0; end if; --?
 
                                Counting <= '0';
 
 
 
                        when Wait1 =>
 
                                if (Quad = "00") then state <= Wait0; end if;
 
                                if (Quad = "01") then state <= RL1; end if;
 
                                if (Quad = "10") then state <= LR1; end if;
 
                                if (Quad = "11") then state <= Wait0; end if; --?
 
                                Counting <= '0';
 
 
 
                        when Count0 =>
 
                                if (Quad = "00") then state <= Wait0; end if;
 
                                if (Quad = "01") then state <= RL1; end if;
 
                                if (Quad = "10") then state <= LR1; end if;
 
                                if (Quad = "11") then state <= Count0; end if; --?
 
                                Counting <= '1';
 
 
 
                        when Count1 =>
 
                                if (Quad = "00") then state <= Wait0; end if;
 
                                if (Quad = "01") then state <= RL1; end if;
 
                                if (Quad = "10") then state <= LR1; end if;
 
                                if (Quad = "11") then state <= Count0; end if; --?
 
                                Counting <= '1';
 
 
 
                        when LR1 =>
 
                                if (Quad = "00") then state <= Wait0; end if;
 
                                if (Quad = "01") then state <= LR1; end if; --?
 
                                if (Quad = "10") then state <= LR1; end if;
 
                                if (Quad = "11") then state <= LR2; end if;
 
                                Direction <= '0';
 
                                Counting <= '0';
 
 
 
                        when LR2 =>
 
                                if (Quad = "00") then state <= LR2; end if; --?
 
                                if (Quad = "01") then state <= LR3; end if;
 
                                if (Quad = "10") then state <= LR1; end if;
 
                                if (Quad = "11") then state <= LR2; end if; --?
 
                                Direction <= '0';
 
                                Counting <= '0';
 
 
 
                        when LR3 =>
 
                                if (Quad = "00") then state <= Count0; end if;
 
                                if (Quad = "01") then state <= LR3; end if;
 
                                if (Quad = "10") then state <= LR3; end if; --?
 
                                if (Quad = "11") then state <= LR2; end if;
 
                                Direction <= '0';
 
                                Counting <= '0';
 
 
 
                        when RL1 =>
 
                                if (Quad = "00") then state <= Wait0; end if;
 
                                if (Quad = "01") then state <= RL1; end if;
 
                                if (Quad = "10") then state <= RL1; end if; --?
 
                                if (Quad = "11") then state <= RL2; end if;
 
                                Direction <= '1';
 
                                Counting <= '0';
 
 
 
                        when RL2 =>
 
                                if (Quad = "00") then state <= RL2; end if; --?
 
                                if (Quad = "01") then state <= RL1; end if;
 
                                if (Quad = "10") then state <= RL3; end if;
 
                                if (Quad = "11") then state <= RL2; end if; --?
 
                                Direction <= '1';
 
                                Counting <= '0';
 
 
 
                        when RL3 =>
 
                                if (Quad = "00") then state <= Count0; end if;
 
                                if (Quad = "01") then state <= RL3; end if; --?
 
                                if (Quad = "10") then state <= RL3; end if;
 
                                if (Quad = "11") then state <= RL2; end if;
 
                                Direction <= '1';
 
                                Counting <= '0';
 
 
 
                        when others => state <= Wait0; -- undefined state; just go back to wait so we don't get stuck here...
 
 
 
                end case; --state
 
 
 
        end if; --clock'event
 
 
 
        end process; --(clock)
 
 
 
end QuadratureDecoder;
 
 
 
 
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.