News
4-08-2025: Custom low latency asynchronous FIFO with PIC microcontroller generator/checker.
11-15-2024: Added some example projects using the Diglent Cmod A7-35T
Contact:
Send email to ted_rossin at yahoo
Note: When downloading files, click the circled icon at the top of the new page to retrieve the file.
Projects are built with Vivado 2024.1.
Projects include a file named How.txt that explains how to click the Vivado buttons to recreate the project from scratch. This file also explains how to download the design to the Digilent Cmod A7 board (both directly to the FPGA and to the external serial flash memory).
Only the source of the Vivado projects are saved. Any IP (PLLs, memories, FIFOs ...) must be recreated by double clicking on them in the source viewer so that they can be regenerated or simply simulating or building the projects will create them.
Projects include test benches which work in the Vivado simulator or with the Icarus simulator.
Most projects are simulated using the free Icarus Verilog simulator. Use either gtkwave or my waveform viewer (VcdView).
AsyncDouble.zip (4-08-2025) requires code from Common.zip
AsyncFifoTest.zip (2-03-2025) requires tools (CLC compiler) and code (Common) from PIC page
This is a test setup for the low latency asynchronous FIFO in the Common directory. Two FIFOs are used. The input FIFO is driven from an external clock (a little less than 8 MHz) generated by a PIC microcontroller which drives 8 bit data and a load signal and senses a full signal. This microcontroller is the data generator and uses stuttering to make sure the input FIFO goes empty periodically. The input FIFO in the FPGA is unloaded using a PLL generated 100 MHz clock which is also stuttered to make sure the FIFO goes full.
The data from the input FIFO is written into the output FIFO using the same 100 MHz clock that is used to read the input FIFO. The output FIFO is read and checked by a second PIC microcontroller using an external clock (a little more than 8 MHz asynchronous to the data generator clock) which generates the unload signal and checks the read data while sensing the Valid signal. This data checker PIC microcontroller reads in bursts to make sure the output FIFO goes full and also drives and OLED display to show how many busts of read data (256 bytes) have been checked and displays an error message if unexpected data is encountered.
Testing was done on a Digilent Cmod A7 board with two PIC18F27Q10 devices. These devices were used because they contain Configurable Logic Cells (CLC) that are used to generate the clock and LOAD/UNLOAD pulses while sensing the FULL and VALID signals instead of using slow software bit-banging.
To verify the generator/checker the gray to binary and binary to gray encoders were removed to make sure data errors were detected (it took about 3 seconds to fail). Removing the double synchronizers also caused failures but took a bit longer to show up when using the gray code.
The final implementation has run without error for over a month and checks about a terabyte of data a week.
SerialPort.zip (6-21-2024) requires code from Common.zip
Small example for Digilent Cmod A7 which uses the two push buttons, LEDs plus the serial interface via USB to control a PWM implementation which controls the RGB LED.
Button 1 selects modify mode by cycling through each of 4 modes after the button is pressed (increase Red, increase green, increase blue and increase all). The current mode is displayed in binary on the two green LEDs. While button 0 is down, the selected colors are increased and wrap back to zero after reaching the maximum value. The green LED brighter than the red which is brighter than the blue so the PWM values are scaled to make all three appear to be the same brightness.
The serial port uses the UART (uart.v) found in the common directory which is configured using the BAUD_DIV parameter to run at 115,200 baud. Serial commands (all need to be followed by \r or \n or \r\n Ugh.):
rhh Set Red PWM value to 0xhh
ghh Set Green PWM value to 0xhh
bhh Set Blue PWM value to 0xhh
s Return current values or Red, Green and Blue
The clock wizard was used to create a 100 MHz clock from the onboard 12 MHz input clock. The locked output from the PLL is delayed to create a reset.
RAM and FIFO Info.pdf Some notes I jotted down while observing the behavior of the RAMs and FIFOs.
BlockRAM.zip (9-22-2024) requires code from Common.zip
Example of writing and reading various block RAM configurations via the serial port. Also, 16 debug pins are driven so a logic analyzer can examine the behavior of the RAMs. The test bench uses behavior models located in the Common directory when simulating with Icarus for a large speed up in the edit debug cycle. See the description for the Common.zip for information on how to create high level RAM and ROM models for simulating outside of Vivado. The description also explains how to create ROM data in a format that Vivado can use and is easy to convert to a hex file so that it can be loaded via readmemh in a standalone simulator.
The PLL is configured to run at 10 MHz so that a cheap logic analyzer can be used to observe the outputs. The serial port is configured to run at 115200 baud. The binary commands are as follows:
0x02 Debug Select non-reg RAM
0x03 Debug Select reg RAM
0x04 Debug Select non-reg ROM
0x05 Debug Select Simple DP RAM
0x06 Debug Select True DP RAM
0x10 Reset address
0x11 Dump first 64 elements of device
0x12 Test out address collisions
otherwise: Write RAMs with value. If bit 7 is clear, the address is advanced.
BlockRAMFifo.zip (11-16-2024) requires code from Common.zip
Example of writing and reading various synchronous FIFO configurations via the serial port. Also, 16 debug pins are driven so a logic analyzer can examine the behavior of the FIFOs. The test bench uses behavior models located in the Common directory when simulating with Icarus for a large speed up in the edit debug cycle. See the description for the Common.zip for information on how to create high level FIFO models for simulating outside of Vivado.
The Common directory model named FifoUnloadToRead is used to make a first word fall through FIFO from a standard FIFO (Fifo5_2) which has one cycle less of latency that the first word fall through FIFO created with the FIFO generator (Fifo5).
The PLL is configured to run at 10 MHz so that a cheap logic analyzer can be used to observe the outputs. The serial port is configured to run at 115200 baud. The binary commands are as follows:
0x10 Reset FIFO
0x11 Dump FIFO 64 elements of device
0x12 Read Depth
0x13 Which Select a FIFO for PIO output.
Otherwise Write FIFOs with value, value+0x40, value+0x41, value+0x42 with some gaps
FifoAsync.zip (11-15-2024) requires code from Common.zip
Example of writing and reading various asynchronous FIFO configurations via the serial port. Also, 16 debug pins are driven so a logic analyzer can examine the behavior of the FIFOs. The test bench uses behavior models located in the Common directory when simulating with Icarus for a large speed up in the edit debug cycle.
See the description for the Common.zip for information on how to create high level asynchronous FIFO models for simulating outside of Vivado.
The PLL is configured to run at 10 MHz for the write side and 6 MHz for the read side so that a cheap logic analyzer can be used to observe the outputs. The serial port is configured to run at 115200 baud. The binary commands are as follows:
0x10 Reset FIFO
0x11 Dump 64 elements of device or until empty.
0x12 Read Depth
0x13 Which Select a FIFO for PIO output.
Otherwise Write small FIFOs with value, value+0x40, value+0x41, value+0x42 with some gaps. Write the big FIFOs with 127 incrementing values.
Common Verilog modules and high level Verilog models for PLLs, memories and FIFOs for simulation outside of Vivado (Icarus). This directory of files is used by most projects and includes common code.
Common.zip (4-08-2025)
CommonBehaveModels.pdf (11-15-2024) Describes how to use/create the high level models in the Common/Test directory.
Non-behavioral models in the Common directory (one day I'll add a pretty PDF with more detail):
FifoUnloadToRead.v: Module to convert a standard FIFO into a first word fall through (normal) FIFO without adding a cycle of latency. See the Synchronous FIFO code under Block RAM FIFO Experiments for an example that uses this module.
Uart.v: Serial port interface with double buffered input and output registers. This module is parametrized so that most baud rates can be implemented as long as the input clock is running fast enough.
FifoAsync.v: Asynchronous FIFO with lower latency than one in the IP Catalog. This model has been synthesized and tested for errors with more than a terabyte of data sent through it with no failures.