Every newbie's favorite project: the Quadrature Rotary Encoder revisited

I caught the long thread here on the quadrature rotary encoder from 2 weeks ago. Like the OP in that thread, I am new to combinatorial logic and describing it with VHDL.

The problem on the surface seems so enticingly simple. Peter's solution presented with the "high" speed clock strikes me as wasteful. (I'll gratefully accept your guidance and correction, of course.)

The quadrature decoder itself seems reasonably well defined by a single D flipflop with clock enable. One encoder switch (call it q1) clocks the dff on its rising edge. Debouncing logic drives the clock-enable. The second encoder switch (q2) drives D, making Q the direction of rotation. Direction and some strobe can feed the direction and clock on an up/down counter.

The "some strobe" part could be problematic. Is there no way to generate this without an external clock? If I drive the counter clock from the debounced q1, it arrives before direction is valid. (Maybe that's good enough and usable. I only want to get this into the starter kit, marvel at some moving LEDs, and then move on. At this point, I can live with a little backlash and some inaccuracy at direction changes.) It seems I can simply gate q1 with an inverted debounce signal, using a simple AND2 with one inverted input, to drive the counter strobe.

Debouncing seems on the surface pretty simple also: ignore further changes on q1 until q2 changes sense. And this seems to be where I'm stuck. I want to sample q2 on the rising edge of q1, and compare q2 with its value with the old q2 value when debouncing started. Alternatively, I want to clock "something" on the next arriving rising _or_ falling edge of q2. XST doesn't like either one, and my head is likewise in a pretzel here. Isn't there any way to do this part without an external clock?

(I left school 25 years. This is self assigned homework, and usenet and amazon.com are my only classrooms. Your help is really the only help I'll get.)

Regards, Mike.

Reply to
MikeWhy
Loading thread data ...

Mike,

There is always a clock present (FPGA design can only be done in a synchronous system, synchronous means there is a clock, speed is unimportant, but today folks want performance, which usually means at least one ~50 MHz clock will be present somewhere).

If you are not using a FPGA, well, then, have fun.

Austin

Reply to
austin

Learn to snowplow before you ski in the trees. Combinational logic is an advanced topic in my book. Start with a synchronous process.

It isn't. Flops are free on an FPGA.

...

Ah, there's the rub. Synchronous design requires much less thinking, and can be proven to work with computer simulation and static timing analysis.

-- Mike Treseler

Reply to
Mike Treseler

I use a state machine that only allows transitions from one AB state to another adjacent state, ie. only allowing one input to change state at a time. If both A and B change at the same time, it is impossible to determine which direction the movement was.

Jon

Reply to
Jon Elson

** Listens for the noise from Peter's foxhole ** ;)

It has a more than minimal register count, but in a FPGA that is hardly an important issue.

All the presented solutions used a higher speed clock.

You can use a delay-line, to get a later clock edge. (see below)

It is POSSIBLE to make a self-clocked Quadrature counter (and I have done it, in a CPLD), but it is NOT simple, and can use MORE logic than a clocked one. It is very much a niche-solution, for cases where you do not have any other clock domains, and want the lowest possible power.

There is another 'hybrid' solution, which adds some 'change-sense' logic to the State-Follower-Faster-Clock design, and it enables the Clock,(or clock osc) UNTIL the States are locked again (latency varies with earlier posted examples), no more than a handful of clocks later.

This will have very high sleep:clk ratios.

This is (slightly) more logic than the simplest design, but will save a lot of power.

It would be well suited to a CPLD with a 1 terminal Gated RC Osc, and low idle power/low emc design targets.

Idle (but ready) state powers under 10uA are possible with this approach.

It is also much simpler to design with today's tools :)

-jg

Reply to
Jim Granville

I've successfully implemented several entirely asynchronous designs in Spartan-3 family parts. Only to see if it could be done, though; I wouldn't try to put one into production.

Reply to
Eric Smith

Why not use it in production? Is there any technical reason why not to use asynchronous designs? E.g. if I want to use Muller C-gates for an aynchronous design with FPGAs?

formatting link

--
Frank Buss, fb@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
Reply to
Frank Buss

As far as I can tell, there isn't anything about the FPGA hardware that prevents it. The development tools, however, are all based on the idea of synchronous design, and will fight you every step of the way if you try to use any asynchronous feedback. You can beat the synthesis and P&R into submission, though they complain, but the static timing analyzer and the power estimator are particularly unsuited to async designs.

You also might not be able to get any support for asynchronous design through official channels. (I'm only guessing, I haven't actually tried.)

Eric

Reply to
Eric Smith

It put a BUFG on an encoder input and routed it to heck and back first. Aside from that, it almost works. Now I can get on with my life.

The final outcome: 6 slices, 6 flipflops, and a GCLK.

Thanks all for the help and the discussion. It wasn't immediately clear in my reading why some things are done the way they are.

=========================================================================

  • Final Report * ========================================================================= Final Results RTL Top Level Output File Name : rot_lights.ngr Top Level Output File Name : rot_lights Output Format : NGC Optimization Goal : Speed Keep Hierarchy : NO

Design Statistics # IOs : 11

Cell Usage : # BELS : 14 # AND2 : 1 # INV : 1 # LUT3 : 9 # LUT4 : 1 # VCC : 1 # XOR2 : 1 # FlipFlops/Latches : 6 # FD : 1 # FDC : 2 # FDE_1 : 1 # FDP : 1 # FDPE : 1 # Clock Buffers : 1 # BUFG : 1 # IO Buffers : 11 # IBUF : 3 # OBUF : 8 =========================================================================

Reply to
MikeWhy

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.