Problem writing quadrature decoder

you only have 2 state bits, once you get 4, you can do it on a faster clock edge,

So if you consider a quad-state/johnson counter, as a first pass. [easier to follow than binary], and what you are coding is a phase lock, or tracking system counter (TSC) that spins that counter to match the Quad IP. It CAN spin at any speed, normally it will do one phase click, and then many,many idle states until the next phase click is needed

IP.TSC

00.00 01.01 11.11 10.10 are all HOLD or do nothing states, MOST clocks will be here

00.01

01.11 11.10 10.00 are all DEC(TSC) by one, and output DEC_EN to the long counter

00.10

01.00 11.01 10.11 are all INC(TSC) by one, and output INC_EN to the long counter

which leaves 4 other states

00.11 01.10 11.00 10.01 as different by TWO clocks, so these are illegal and should never happen in a correct margin design. Take them to a sticky-led, perhaps ?.

Once you have that working, you can compact the two TSC bits into the Long counter, two LSBs, by change to binary coding, if you really want to save two FFs :) In a FPGA tho, why bother ? ( In a small CPLD, you might take the effort. )

Also, on read/compare of the long counter, if the system WORD size is less than the counter size, you need to capture ALL bits in one clock, in case the counter rolls over between byte/word reads.

Jim Granville,

Reply to
-jg
Loading thread data ...

You almost have what you want but you will still have troubles because mechanical chatter can matter in a binary implementation. One way you CAN achieve your goals is to use Gray code counters, at least for the LSbits.

I previously designed a 3-bit Gray code counter for a first stage of a very fast counter such that I only have 1 LUT of delay for each bit and was able to count at a clock frequency limited by the delay of a single LUT. My design produced the same combinatorial loops warning but for a stable combinatorial quadrature counter, those are expected warnings and should still produce a programming file. Even here, I used this first stage as a divide-by-8 prescaler rather than using the count directly because getting a 3-bit Gray counter to sync up with a multi-bit Gray or binary counter isn't trivial though it is doable with a little care.

The key to getting a quadrature counter to work with a Gray code counter is to realize that when you are at a specific Gray count, only two bits can change: one for the forward direction, one for reverse. Effectively one channel of the quadrature counter can be slaved to the LSbit while the count determines which upper bit (and at what polarity) the other quadrature channel controls. When you transition between two upper bits being controlled by the one quadrature channel, the bits are both safe because the quadrature channel that controls those upper bits is in the middle, stable part of its cycle while the LSbit channel is transitioning the count, affecting which upper bit is controlled.

When the Gray count is read, the value is (typically) registered in the clock domain twice such that if one bit is caught mid-transition then that value will be settled upon by the second register - only one register - as a defined value. If instead there are multiple registers fed by that one first-stage value, it's possible two paths could "see" different values for this asynchronously changing signal.

If you can figure how to count in Gray and then how to change one bit (at a defined polarity) at a time for a given count, you will have an every-transition counter for full resolution and be asynchronous-friendly in your design. And you will get plenty of combinatorial-loop warnings for your design but you will be able to produce a programming file; they are just warnings, after all.

- John_H

Reply to
John_H

You have my solution available at :

formatting link

There is a test bench and simulation script.

As mentioned : don't forget to register A & B before hooking to the module.

Bertrand

Reply to
bcuzeau

Well, this is a challenge.

I am working on a design that uses 4 LUTs and 4 flip-flops, takes in raw A and B inputs plus a clock and outputs synchronously decoded CE and U/D signals to control a binary counter. There are 3 configuration options: 1, 2, or 4 counts per 360 degree contact cycle. And bounce is suppressed, and kept away from the counter :-)

"Everything you always wanted to have in a quadrature detector'" Peter

Reply to
Peter Alfke

ch

John - unless I'm missing something here... I think just watching edges is good enough to deal with any sort of debouncing problems, as long as only A or B (not both) are bouncing at any given time.

But either way - right now I really just want to figure out why I can't get the stupid thing to map properly - and then I will worry more about dealing with the small things. I just posted the full code, constraints, and console output on the FPGA4Fun forum:

formatting link

Can somebody please look at this? I just am at a complete loss as to what is wrong - but to you more experienced people the problem will probably jump right out.

Thanks!

-Michael

Reply to
Michael

Can you guarantee that the edge will transition fully and stay transitioned for a minimum length of time?

While most debounce problems are a true mechanical bounce issue where hard contacts make it difficult to engage and hold a contact instantly, I'm not comfortable enough to say that a bounce will be a hard transition from one logic level to another with microsecond-scale valid levels between bounces. I've always considered the mechanical transition to be undefined enough to make undebounced (I like this word) switches extremely poor for things like clocks.

In your case, do you even use those edges as clocks? I thought you had non-clocked combinatorial loops where you had binary counts affected by the edge. If that edge gets undefined, some bits may go one way while other bits go another way in that binary word unless you can guarantee the debounced behavior of those edges.

The Gray code based quadrature counter doesn't have problems with bounce. At all.

I'd like to make some time to look at your code but I natively code Verilog and I don't have a synthesizer at home. I'll see what I can do.

- John_H

Reply to
John_H

What does your trim report say about the trimmed signals?

From your mapper output you posted on FPGA4Fun, "See the trim report for details about why the input signal will become undriven."

- John_H

Reply to
John_H

Hi John - I couldn't figure out how to look at the trim report. There wasn't a single file with trim in it in the project directory. I GREPed the directory for trim and didn't turn up anything except for places where it says to look at the trim report. I googled and couldn't find anything, and I checked the Xilinx website for information about how to look at the trim report and couldn't find anything. Any suggestion as to where I can find this report?

Thanks!

-Michael

Reply to
michael

Hmmm, Can you explain how bounce can be suppressed in a 4 count design ? There, you cannot distinguish between a change in direction, and a contact bounce, as they have the same signature ?.

Does it also catch false/illegal states in the 4 count mode ?

I have heard of very high apparent edge rates in mechanical systems, caused by shock propogations (certainly enough to stress a Software Solution) - so a 50MHz+ clock is not as silly as it may sound :)

- Jim Granville,

Reply to
-jg

It's part of the mapper report file, *.mrp (often mydesign.mrp or map.mrp)

- Brian

Reply to
Brian Drummond

-jg wrote: (snip)

The clocked decoder latches the inputs on each clock cycle and updates the counter appropriately. It works as long as the clock is faster than the time between actual edges (including any bounce).

If the signals can bounce long enough for the encoder to get to the next edge, it is not possible to uniquely decode the signal. If the encode sits right on an edge, continually bouncing, the counter may miss some back transitions, but it also won't count the matching forward transition.

If you worry about metastability in the latch, add a second latch.

-- glen

Reply to
glen herrmannsfeldt

The design is done, we are finishing documentation, and Ken Chapman has graciously agreed to give it a thorough hardware test net week:

4 LUTs, 4 flip-flops, insensitive to contact bounce or any type of erratic mechanical movement. 1, 2, or 4 counts per encoder cycle (i.e. 90, 180 or 360 degrees between counts, as a config option) "The end of all discussions about quadrature encoders, mechanical or optical." Peter Alfke
Reply to
Peter Alfke

Then it must be VERY clever, even Clairvoyant, if it can separate 'any type of erratic mechanical movement', from a genuine mechanical movement! ;)

No mention of catching illegal states ? (clock too slow) ?

-jg

Reply to
-jg

I'll run the clock between 10 and 100 MHz, so it will never be too slow. There is no way to move a whole quadrant in one such clock period. Peter

Reply to
Peter Alfke

I would love to be clairvoyant, but in this design I only make two assumptions: that one of the two contacts is reliably open or closed, when the other one makes a (bouncy) transition. And that the mechanical travel time from one contact bouncing to the other contact bouncing is longer than a clock period of 10 to 100 MHz. I think those are reasonably safe assumptions. Peter

Reply to
Peter Alfke

Hi Peter,

Hmm, history is littered with such brave. sweeping statements!.

In the example I came across, the designer had also asserted the clock would never be to slow, :), but he did the maths based on average MASS velocities, and forgot about shock/whiplash. In a practical installation, he needed a faster clocked PLD for reliable operation. The real world can do that to designers.

There is also a drive these days to save power, and use only as many MHz as will suffice.

So, given the ease with which designers can get this wrong, and the ease with which catching this can be added, I would suggest that a good reference design should include this optional feature.

Feel free to blame me for the inclusion :)

Jim Granville

Reply to
-jg

te

Hi Peter, Your second description does not fully follow your first; the point I was making, was that in a full quadrant design, it is impossible to discriminate between "erratic mechanical movement" and a genuine movement and the counter must track Up/Dn/Up/Dn/Up until the contact settles. "insensitive to contact bounce" is thus impossible: the system should follow the bounce. (Which I think is what your second description is actually saying?)

-jg

Reply to
-jg

rate

Let's discuss this when the design is completely tested and described. My design does not follow the bouncing contact, it just ignores it and waits for the other contact to make a change... Peter

Reply to
Peter Alfke

The system does not count edges, it counts states. This means that bounces will not matter as long as only one input changes at a time. If you miss and even number of edges, you are at the same state you started at and the result is correct. If you miss an odd number, you are in the next state and the result is correct at the next clock.

This is not the case if you use the edges for clocks. That is a very bad thing to do and will give you lots of problems.

You do care if both inputs bounce. That is tough to follow.

Reply to
none

This can become somewhat semantic, but there is no bounce in a full 4 quadrant encoder. It cannot know what bounce is, and it MUST follow all edges that it is able to see.

To see this in a nice diagram, see figure 12

formatting link

Here, you will see a direction reversal, being tracked. It might look like a bounce to some, but the chip cannot know that, it has to react to all edges it sees.

If you are working in LESS than 4 quadrant mode, then yes, you can start some hand-over logic, but that will add some back-lash - which may be fine for a hand-operated knob application.

Which is why I was suggesting adding logic to show you have 'lost sync'. Then, you can lower the clock, to save power, and know when you have gone too far.

-jg

Reply to
Jim Granville

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.