Pmodenc

From Hamsterworks Wiki!

Jump to: navigation, search

This ]FPGA Project was completed in July 2013.

The outputs of the PMODENC make about 80 transitions per turn. This project just counts the transitions and outputs to "value", which I map to LEDs.

I should debounce the signals to stop the transitions jumping up and down, but these will not cause an error a long as the 'quad' input is synchronized (which I do in the 'sr' shift register, which is why it is a bit longer than seems needed).

pmodenc.vhd

----------------------------------------------------------------------------------
-- Engineer:  Mike Field <hamster@snap.net.nz>
-- 
-- Module Name:    pmodenc - Behavioral 
-- Description:    Process the quadrature signals from the rotary encode on 
--                 the Digilent PMODENC 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity pmodenc is
    Port ( clk   : in  STD_LOGIC;
           quad  : in  STD_LOGIC_VECTOR (1 downto 0);
           up    : out  STD_LOGIC;
           down  : out  STD_LOGIC;
           error : out  STD_LOGIC);
end pmodenc;

architecture Behavioral of pmodenc is
   signal sr : std_logic_vector(5 downto 0) := (others => '0');
begin

process(clk)
   begin
      if rising_edge(clk) then
         up    <= '0';
         down  <= '0';
         error <= '0';
         case sr(3 downto 0) is
            when "0100" => down <= '1';
            when "1101" => down <= '1';
            when "1011" => down <= '1';
            when "0010" => down <= '1';

            when "1000" => up <= '1';
            when "1110" => up <= '1';
            when "0111" => up <= '1';
            when "0001" => up <= '1';
            
            when "0011" => error <= '1';
            when "1100" => error <= '1';
            when "0110" => error <= '1';
            when "1001" => error <= '1';
            
            when others =>
         end case;
         sr <= quad & sr(sr'high downto 2);
      end if;
   end process;
end Behavioral;

accumulator.vhd


----------------------------------------------------------------------------------
-- Company:   Mike Field <hamster@snap.net.nz>
--
-- Module Name:  accumulator - Behavioral 
--
-- Description: Accumulate the 'up' and 'down' pulses from a rotary encoder.
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity accumulator is
    Port ( clk : in  STD_LOGIC;
           up : in  STD_LOGIC;
           down : in  STD_LOGIC;
           value : out  STD_LOGIC_VECTOR (7 downto 0));
end accumulator;

architecture Behavioral of accumulator is
   signal total : unsigned(value'range) := (others => '0');
begin
   value <= std_logic_vector(total);

process(clk)
   begin
      if rising_edge(clk) then
         if up = down then
            null;
         elsif up = '1' then
            total <= total + 1;
         else -- down must = '1'
            total <= total - 1;
         end if;
      end if;
   end process;
end Behavioral;

top_level.vhd

----------------------------------------------------------------------------------
-- Company:   Mike Field <hamster@snap.net.nz>
--
-- Module Name:  top_level - Behavioral 
--
-- Description: Top level for testing a PMODENC rotary encoder
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity top_level is
    Port ( clk : in  STD_LOGIC;
           quad : in  STD_LOGIC_VECTOR (1 downto 0);
           value : out  STD_LOGIC_VECTOR (7 downto 0));
end top_level;

architecture Behavioral of top_level is

   COMPONENT accumulator
   PORT(
      clk : IN std_logic;
      up : IN std_logic;
      down : IN std_logic;          
      value : OUT std_logic_vector(7 downto 0)
      );
   END COMPONENT;

   COMPONENT pmodenc
   PORT(
      clk : IN std_logic;
      quad : IN std_logic_vector(1 downto 0);          
      up : OUT std_logic;
      down : OUT std_logic;
      error : OUT std_logic
      );
   END COMPONENT;

   signal up, down : std_logic;
begin

   Inst_accumulator: accumulator PORT MAP(
      clk => clk,
      up => up,
      down => down,
      value => value
   );

   Inst_pmodenc: pmodenc PORT MAP(
      clk => clk,
      quad => quad,
      up => up,
      down => down,
      error => open
   );

end Behavioral;

Personal tools