Skip to content

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: FPGA Schematic Flow Diagram this image is the current bitstream flow for the FPGA.