Math circuits demonstration
\(\)What good are fast math circuits, if you can’t show them off? We decided to make a test setup to both demonstrate and verify the implementation of the circuits.
In the demo, an Arduino reads the operands from rotary encoders and shows them on 7-segment displays. It sends the operands along with the desired operation to the FPGA. That then returns the result to the Arduino, that shows it on the OLED screen.
Schema
The schematic below shows the connections between the various printed circuit boards. Links to the vendors of the various parts can be found on my Arduino Stuff page. Note that the schematic shows an OLED instead of an LCD display.
Arduino 101
This project uses an Arduino 101, because it uses 3.3 Volt I/O like the FPGA board. Any similar 3.3 Volt Arduino board with sufficient I/O will do. This library supports rotary encoders connected to the Arduino/Genuino 101. It should work for other microcontrollers for as long as they can generate the necessary interrupts.
Input operands using Rotary Encoders
Many sketches exist for the Arduino UNO, most of them only supporting a single rotary encoder. I borrowed from one of them, and adapted it for Arduino 101. The driver is interrupt driven, can be instantiated more than once, ignores suspicious input signals and allows both linear or non-linear mode. The latter makes the step size dependent on the rotation speed.
The main challenge was to find a way for the interrupt service routines to invoke a C++ Class Member Function. The solution chosen relies on virtual functions and friend classes used as described in the article Interrupts in C++ by Alan Dorfmeyer and Pat Baird. My source code is available at:
Display operands using 7-Segment Displays
I chose a 7-segment display that can be driven using a two wire serial protocol (I2C) and is supported by the Arduino library. Even though this is a 5V part, I made it accept 3V3 I/O by removing the internal pull-ups and adding external pull-ups to 3V3. This has the added advantage of not having four pull-up resistors in parallel from each of the 7-segment displays.
Implement the math circuits using FPGA
The FPGA development board is the Terasic DE0-Nano as described in my Getting Started guide. It contains a Altera Cyclone IV. This budget board is sufficient to demonstrate the circuits. For more speed one can upgrade from the 60 nm technology used in the Cyclone IV to the Stratix 10 that uses a 14 nm process.
The connection between Arduino and the FPGA uses a fast serial protocol (SPI). The Arduino libraries come with support for this protocol. For the FPGA we developed the implementation ourselves as described in Math Talk.
Display the results on an OLED screen
A LCD proved to be visibly to slow to keep up with the FPGA’s results. Instead, I switched to a 3.12″ OLED screen (Newhaven NHD-3.12-25664UCY2). I found winneymj’s driver that I adapted for the Arduino 101. The resulting OLED Display library has been submitted back upstream.
Besides the usual SPI interface, this devices uses a data/command* signal (\(D/\overline{C}\)) signal. The OLED may draw up to 271 mA what makes it required to connect an external power supply to Arduino’s barrel jack [appnote datasheet]. More info at Intro, Using static timing analysis, TU Delft
Measuring propagation delay
Latency is the real delay of a circuit, a measure of how long the inputs to a device are stable is the result available on outputs. In order to evaluate the various algorithms, a software tool is needed that uses a Time-to-Digital Converters.
For a course measurement, we can use a PLL mega block to generate a 200 MHz clock on the NE0-Nano as described in the User Manual pg. 55. For a sub-nano second accuracy , you can use a delay line carefully drafted with the chip planner as suggested in Implementation of a 42 ps Resolution TDC on a Cyclone IV FPGA. A similar approach, but lacking details, is described by JPL.