The tests I did last year with the printer were driven by a Microchip PIC 16LF872. I'm primarily a software engineer, so that environment is easier for me to play in. However, when I wrote the C code for that, I did it with some thought to converting it to Verilog. Thus I started out by copying my C code and set about doing a straight translation. For the most part I think it would have worked, but in the end I re-wrote most of it.
One of the parts that did survive mostly intact was the debouncing code. The
Looking at the PCB in the P170-DH calculator I found an
My PIC test circuit used the 10K ohm resistors to +5V and no capacitors. The PIC pins I used have Schmitt trigger inputs which provide hysteresis, and I implemented a 4-bit shift register in software for debounce and edge detection. The scan rate was about 37 microseconds per cycle, so it would take about 111 microseconds to detect a valid edge. That seemed to work just fine for the printer.
The Lattice iCE40-HX provides about 50 millivolts of hysteresis, but the Xilinx
And here is the source code for that module:
Since the FPGA logic operates in parallel it can cycle much faster than the PIC. I chose a 10 microsecond cycle, with a deeper FIFO to achieve similar timing. This should make it more resistant to errors. The depth of the FIFO is a parameter defined on line 2. If the hardware debouncing is sufficient this can be set as low as 1 to minimize the latency.
Any time a signal arrives asynchronously with the system clock it's best to run it through a synchronizer to avoid metastability problems. My synchronizer is formed by the flip-flops inferred by "sync" and "fifo" (lines 15 and 16). The "state" output is essentially an
The only "magic" in any of this is the attribute "ASYNC_REG". This is a Xilinx-specific attribute that tells the place-and-route to keep the synchronizer flip-flops in physical proximity to each other to minimize the signal propagation lag between them. In the case of the Spartan-6 FPGA, Xilinx says this is only necessary at clock speeds above 300 MHz. For this project my expected clock rate is 50 MHz or slower, but I like this module so much it may become something of a stock item for me. I have another project where I'm getting close to this, so I'm just trying to be "proper" here.