Mapping memory and controlling outputs
Currently, it is unknown to me how to implement a memory space within a FPGA for the host processor to deposit frames and for the FPGA to sample and latch from.
The pico-ice FPGA dev board that will be used for testing has 128KB SPRAM and 15KB DPRAM. Ideally, the host will send a full or partial frame to the DPRAM, signal a new frame transfer, then copy the data from the DPRAM to the SPRAM. After finishing the transfer, the FPGA will signal back to the host that it is ready for another transfer, and continue to refresh the panels.
However, there is one critical aspect to this transfer. The driver core within the FPGA must not be interrupted, lest the screen flickers or flashes. So, the driver core must have a controlled pause to copy in new data.
---
title: FPGA Dataflow Diagram
---
stateDiagram-v2
s0 : Zero internal ram
sTest : Output R, G, B, to all LEDs
sWait : Wait
sCopy : Copy frame data to SPRAM, toggle area indicator
sWrite : Write LED buffer to output
[*] --> s0
s0 --> sTest
sTest --> sWait
sWait --> sCopy : DRDY
sCopy --> sWrite
sWrite --> sWrite : No Input
sWrite --> sWait : DAVAIL
FPGA Program Writing notes
PLL generation
The OSS Suite of tools includes "icepll", which is an easy tool to create a Verilog block for the PLL module. By running the command icepll -i 12 -o 100 -p -m -n pll -f pll.sv, a file called "pll.sv" is created with a 12MHz input clock (from an external GPIO source) to a 100MHz output clock. This module can then be instantiated by the top module to easily implement the PLL.
This command and setup is specific for the iCE40, but can easily be translated to the ECP5 FPGA line, potentially others as well.
Data Storage
For storing the panel frame information in the FPGA, the overall structure of the data needs to be determined. Each pixel has three color components, each 8 bits wide, for a total of 24 bits per pixel. For a single panel, there are 4096 pixels. For the simplest FPGA synthesis, putting all of this into one flat array is best.
Data storage pattern
ARRAY_DEPTH = COLOR_DEPTH * ROW_PAIRS;
DATA_WIDTH = 6 * COLUMNS;
This creates one flat array, where each address is created from the bitplane number and the selected rowpair. Then, each array element has bit storage for an entire rowpair of data, which in this instance is 384 bits.
Other information
One interesting aspect of the toolchain is the ability to create FPGA "schematics", which seem to be logic flowcharts for FPGAs. For example: this image is the current bitstream flow for the FPGA.