Version 1.0: quadrature_decoder.vhd (6.9 KB)
- VHDL source code of a Quadrature Decoder component
- Outputs the direction and a position count of signals from a quadrature encoder
- Option to clear the position counter to set the “origin” or index
- Configurable size of position counter
- Configurable debounce time to qualify input stability and remove glitches
This details a Quadrature Decoder circuit for use in CPLDs and FPGAs, written in VHDL. The component reads in signals from a Quadrature Encoder, determines their direction, tracks their cumulative position, and outputs the results to user logic. It was designed using Quartus II, version 13.1.0. Resource requirements depend on the implementation. Figure 1 illustrates a typical example of the Quadrature Decoder integrated into a system.
Figure 1. Example Implementation
Quadrature encoders use two channels to sense the position of a movable apparatus, typically a rotating disk/shaft (rotary encoder) or a linear strip (linear encoder). The disk or strip has two coded tracks on it, positioned 90 degrees out of phase, as shown in Figure 2. As the code track moves in relation to the stationary sensors, the sensor output signals correspond to the part of the track they see.
Figure 2. Code Tracks and Output Signals
The Quadrature Decoder interprets these output signals. By counting the transitions on the two channels, the decoder determines how far the apparatus has moved, and it evaluates the direction of movement based on the sequence of the transitions. If an origin is set, then the count on the decoder tracks the position of the apparatus relative to that origin. Some rotary quadrature encoders include another output channel that produces a single pulse per revolution, called an index, which is often used for this purpose.
The first stage of the Quadrature Decoder synchronizes and debounces the input signals from the encoder. It is based the debounce logic circuit explained and documented here with some minor modifications (allowing for a more precise debounce time at the expense of additional logic). Figure 3 depicts this circuit. When the input changes, the output of its corresponding XOR gate clears the counter. When it does not change, the counter begins to count. If the inputs remain stable long enough for the count to reach the debounce_time, then the new value is stored in the final register and the counter disables itself until there is another change on one of the inputs. The defined relationship between the a and b inputs allows them to share a debounce counter, and the same time period is used to debounce both. The set_origin_n input has an independent debounce circuit that works on the same principle.
Figure 3. Synchronization and Debounce Circuit
Table 1 lists the possible a and b input transitions, along with the corresponding decoded values of direction and position.
Table 1. Truth Table
As seen in the truth table, the direction is determined by
direction = a_new XOR b_prev
and the position increments and decrements on the same criteria. These values are only registered when new values of a and b are validated. This occurs when the debounce time is met and either the value of a or b has changed.
The set_origin_n input synchronously clears the position counter (setting a reference position) and also disables the direction output.
Figure 4 shows the logic circuit.
Figure 4. Decoder Circuit
The Quadrature Decoder is configured by setting the GENERIC parameters in the ENTITY. Table 2 describes the parameters.
Table 2. Generic Descriptions
The generic positions sets the size of the position counter. The counter’s output position ranges in value from 0 to positions - 1. The counter wraps around if the bounds of its range are exceeded in either direction. (If the counter is decremented from position 0, the new value is positions - 1. If it is incremented from positions - 1, the new value is 0.)
The debounce time for the a and b inputs is set by the debounce_time generic. The actual debounce time is (debounce_time + 2) * the system clock period. This time is highly application dependent. The parameter should be set such that it is shorter than the minimum time the encoder signals are expected to remain at the same code (determined by the speed and geometry of the moving system) and also long enough that it removes glitches or chatter during the transitions between codes. The default value is 50,000, which corresponds to 1 ms with a 50 MHz clock. For many systems, the debounce time must be much shorter.
The set_origin_n input has an independent debounce circuit. Since this input may come from a pushbutton or other source, it might require a much longer debounce time than the a and b inputs. Its debounce time is set by the set_origin_debounce_time generic. The debounce time is (set_origin_debounce_time + 2) * the system clock period. The default value of this generic is 500,000, corresponding to 10ms with a 50 MHz clock.
Table 3 describes the Quadrature Decoder’s ports.
Table 3. Port Descriptions
Figure 5 depicts an example waveform to illustrate the quadrature decoder’s operation. In this example, the number of positions is configured to 16. As the a and b inputs (ab_tb) progress in a positive direction, the direction output asserts and the position output increments. When the set_origin_n input deasserts, the position output clears. Once set_origin_n reasserts, the position output resumes incrementing from the new reference point as the inputs continue in a positive direction. Once they switch to a negative direction, the direction output deasserts and the position output decrements. When the position output decrements from 0, it wraps around to its maximum value of 15 ( positions -1).
Figure 5. Example Waveform
This Quadrature Decoder is a programmable logic component that tracks the direction and a position count of the signals from a quadrature encoder. The size of the position counter is configurable, as is the debounce times for the inputs. It also includes a synchronous clear, allowing the user to set a reference position or clear the position counter using a quadrature encoder’s index feature.
Comments, feedback, and questions can be sent to firstname.lastname@example.org.