FPGA data logging
Minimal logic analyser
ECE 5760 Cornell University

Viewing the state of the FPGA

Debugging a FPGA design requires that you somehow view the internal state of the FPGA. Intel/Altera have some tools to do this

A simple Logic Analyzer (Homebrew Logic Analyzer -- HOLA)

I wanted to build a very light-weight data logger that could be used as a logic analyser. The FPGA footprint should be minimal and the user interface completely determined by user code running on the HPS. Only the data aquisition and transfer to the HPS is defined. The data can be displayed as a text list, plotted as traces on the VGA, or exported to a spreadsheet.

To implement this, I used three state machines running at 100 MHz:

First implementations of HOLA

The HPS code transfers parameters, then just does a simple print out of 5 samples around the trigger. The verilog is set up with the data input to the logger being a 32 bit counter running at 100 MHz. The data input the analyzer is
data_input = {count[31:0]} .
The trigger input is

where KEY[3] is logic-low when pushed. If the HPS sends a trigger mask of 0h80000000, and a trigger word of 0h00000000 then the trigger will happen when the button is pushed. If the HPS sends a trigger mask of 0h0000ffff, and a trigger word of 0h00001000 then the trigger will happen when the count is 0h1000.
(HPS_code, verilog, Qsys_layout, ZIP)

A slight modification of the DUT verilog code sets up with the data input to the logger being 28 bits of a 32 bit counter running at 100 MHz, and 4 bits of counter state. The counter state merely sequences between 0,1,2 as a simple source. The data input the analyzer is
data_input = {DUT_state, count[27:0]} .
The trigger input is
The HPS code is modified to parse the 32 bit data into count and state and show 10 samples before/after the trigger. The first image below shows the program output with count and state with a trigger_mask=FFFF and trigger_value=1000. The second image shows program output with trigger_mask=8000FFFF and trigger_value=1000. The data capture occured when the count low 4 digits were 1000 and the button is pushed.
(HPS_code, verilog)

Modularized version of HOLA

Rearranging the hardware to separate the logic analyser from the device-under-test makes a cleaner interface.
The functionality is unchanged, as is the Qsys layout.
There are two connections to the DUT, connections to two SRAM modules on the Qsys bus, and a clock and reset.
The formatted verilog for DUT, analyser interface, and Qsys interfaces. (Verilog)
A modified version of the HPS code prints binary as well as the hex count and the state variable. (HPS_code)

Inserting HOLA into your design

There are just a few items to change to insert HOLA into your design:

As an example, insert HOLA into simplified version of
VGA display using a bus_master as a GPU for the HPS Display from SDRAM
project from the bus-master page.
The goal is to be able to use the VGA as a graphic output for the logic analyzer.

Adding waveform plotting to HOLA

Once the VGA interface is running, it is possible to add some graphics to HOLA. This example uses a DDS sinewave generator as the device-under-test. The clocked sine ROM adds a one cycle phase delay between the phase and the sine value. In the console image you can see the trigger condition was set to zero and masked to the low-order 8-bits. You can also see the one cycle sine delay. This mask isolates the phase value from the verilog data_input to HOLA. The data_input is parsed into 16-bits of sine and 8-bits of phase for display on the VGA. As seen below, the green line is at the trigger value of zero phase in the first image. Setting the trigger mask to 0xff and the trigger value to 0x40 produces a 90 degree phase shift at the trigger point, as seen in the second image.
(HPS_code, verilog, ZIP)

Modularizing and simplifying the HPS interface to HOLA

To make the system easier to use for debugging, the low level functions on the HPS were abstracted to five functions:

The code for many applications will just call the start routine, plot some data, and end. The example queries for a trigger_mask, trigger_value, and zoom factor, the plots the phase of a DDS system, the individual bits of the phase, and the resulting sinewave. Two zoom levels are shown below. Zoom level 0 plots 1 pixel/horizontal pixel. Zoom level 2 plots 4 pixels/horizontal pixel. The phase and sine vectors are also printed.
(HPS_code, Verilog and zip is same as above)
(HPS_code with binary print)