XIVPS

A blog concerned with electronics and everything else

VHDL ROTARY

14 Oct 2019 - xi

You have probably seen rotary encoders before. They are those turny-bits on your average home entertainment system, your radios, the knobs in your car, etc. However, it is important to not confuse them with potentiometers, which work differently. Generally, if the knob has indents and no hard limits, there is probably a rotary encoder behind it.

We will implement a core for reading and interpreting the quadrature signals from such an encoder. The design is architecture-independent and thus can be implemented on many different FPGAS and other logic devices. We will also write a testbench for it, and use GHDL for simulation.

Implementation

The principle of rotary encoders is pretty simple:

Lets say the black surfaces lead to a one on the output, the white to a zero. If you now imagine the disc to rotate clockwise, the upper lead(A) gets connected to black first, then the lower one(B), and then both of them are high. The same behavior is visible in the timing diagram.

The most simple approach to writing a decoder for this is a state machine in VHDL. If we make sure to buffer the A and B signals from the IO pins(and therefore sync them with the clk signal), this approach works as long as there is a cpu clock cycle for every state(surprise).

The code can also be found at Rotary Encoder.

entity rotary is
  port (
    reset : in STD_LOGIC;
    clk : in STD_LOGIC;
    r_in : in STD_LOGIC_VECTOR(1 downto 0);

    cw_out : out STD_LOGIC;
    ccw_out : out STD_LOGIC
  );
end rotary;

First of all, the entity definition. We have two logic signals for CLK and RESET, the rotary encoder signals A and B are connected to each of the STL_LOGIC_VECTOR elements. The output of the entity are two tick signals, one for CW rotation and one for CCW rotation. The actual architecture is comprised of a simple state machine with the following states: