EXTERNAL SIGNALS MAY NOT BE CLEAN ENOUGH FOR CERTAIN LOGIC
Every external signal coming into the FPGA has to be passed through a series of flipflops to reduce the risk of metastable states - the risk that if the pulse arrives at just the wrong time compared to the clock edge in the FPGA, it may assume an incorrect state or even hang up. The conventional solution is to pass through three clocked flipflops to clean up the signal for use inside the FPGA.
The risk of a signal sitting in a metastable state goes down dramatically by the third flipflop. It does introduce a delay of three clock cycles before you are seeing what has occurred externally, but with a 100MHz FPGA clock and the relatively slow equipment to which I am connecting, this is not an issue.
These signals may have a bit of bounce in them, similar to how contacts behave when a switch is flipped. That is, even though digital logic is driving the signal rather than electrical contacts, I might see a sequence of bits coming out of the three flipflops that don't definitively transition between 1 and 0 states at only one cycle. The output might have a stream of 0 0 0 1 0 1 1 1 for example, where a long sequence of 0 change to a long sequence of 1 but there is a sort of stutter for a cycle or two.
Often we want to react when a signal changes state, but we take an action only once. In essence we only care about the signal edge, the rising transition. If there is a stutter, than we might detect more than one rising edge when the external situation only changed once. If we are counting based on the edges, we might incorrect count higher than we should.
In many cases, the external signal is used to advance a state machine, so that it doesn't matter that there is a pair of edges close together, but I have to think carefully about whether the state machine could malfunction with stutters. For example, the state machine may use the falling edge to move onward, which the stutter will appear to deliver.
HYSTERESIS - SCHMITT TRIGGERING
Schmitt triggers are gates that switch at different thresholds in one direction than the other, designed to eliminate the risk of small variations inadvertently switching the output state. Usually this is an analog approach - perhaps the rising edge must get to 75% of the full on voltage before the gate registers it as a 1, but it won't switch back to 0 unless the falling edge drops below 25%. The signal can bounce or oscillate around the 50% level quite a bit and still not be reflected in the output.
This is hysteresis - where the change in state depends on the history of the signal not just the immediate value. It adds a delay before the change in the signal is recognized and acted upon, but it can eliminate bouncing or stuttering signals. It involves different thresholds for when it turns to 1 and when it turns to 0.
MY THRESHOLD FILTERS
I created a module that adds this hysteresis for critical external signals. It first address metastability with the usual series of three flipflops. It then adds or subtracts to a counter based on the instantaneous signal state. The thresholds for when the output changes are specific high and low counts. We might require five successive 1 values before the output is switched to one, when the counter reaches a count of 5. Future 0 values decrease the counter from its maximum, but we don't change the output state until we get to a count of 2. That spread between the rising and falling thresholds is the protection against bounce or stutter.
The time delay can be an issue - in the example above a signal that rises to 1 won't be recognized for a minimum of 8 FPGA cycles, more if there were stutters. At 100MHz clock frequency, that is 80 nanoseconds or more delay. The case for most of my projects is that the signals are much, much slower than that. Even the stream of clock and data bits from the disk drive are changing more like 1400 nanoseconds, more than 17.5x slower. More importantly, all the signals are arriving wih a similar delay.
It will add delay for when my output signals to an external device don't react for 80 nanoseconds, but that isn't significant. A sector on the disk takes 10 milliseconds to rotate past the head, thus the signal delay is only 0.0008% of the sector duration.
I am first applying my threshold filters to the tool I built to use a Diablo disk drive to read and archive all my 1130 disk cartridges. The protocol for the disk is to record magnetic flux reversals in 'bit cells' of two bit times. A reversal always occurs first, which is the clock, then the second bit time skips the reversal if the bit value is 0 otherwise a reversal signals a 1 bit.
The disk drive itself tries to separate the flux reversals and route them out separate clock and data signal lines, but I have to see the clock pulses to know which bit of a word that a data pulse belongs to. Thus, the edges of clock and data really matter in this process. I expect my filter to help me determine when to watch for data pulses and when to shift the prior result into a word.
My state machine is driven by the clock pulse edges - the falling edge sensitizes me to watch for any 1 bit coming on the data line. The falling edge of the clock resets the detector, then any data pulse turns it on. The rising edge of the clock is when I check the detector to see if a data pulse had arrived any time during the roughly 1.4 microseconds between those edges.
Another application where the threshold filter might be very helpful is in the Virtual 2315 Cartridge Facility, where I have had some discrepancies between the seek distances requested by the disk diagnostic program and the attained cylinder position. Since the commands from the 1130 to the disk pass through the V2315CF, if a stutter caused a failure in my FPGA logic I could have dropped a movement or added one as I drove the disk drive from my code.
No comments:
Post a Comment