# GARY: Graphics Adapter for Retropixel Yeeting This is a project to build a graphics adapter for the Sentinel 65X, as an upgrade to the VERA graphics core. It's a work in progress. ## Current status Still building it. Unless you want to tinker or hack on the design, it's not yet ready for use. As of 2024-09, the high level architecture looks like this, with grayed out modules being the TODOs. ![functional diagram of GARY](images/gary-architecture.jpg) You can also look at [the design requirements](Requirements.md) to get an idea of why this exists and roughly where we're going, although it's a fairly loose set of guidelines and may change as development progresses. ## Requirements GARY is written in [Bluespec SystemVerilog](https://github.com/b-Lang-org/bsc), and synthesized with the Yosys/Nextpnr open source FPGA toolchain. If you can use nix, the flake.nix in this repository provides the necessary tools, which you can make available with `nix develop`. Otherwise, consult flake.nix for a list of software. At a minimum you'll need: - The [Bluespec SystemVerilog toolchain](https://github.com/b-Lang-org/bsc) - [Yosys](https://github.com/YosysHQ/yosys) and [nextpnr](https://github.com/YosysHQ/nextpnr) with Lattice ECP5 support - [OpenFPGALoader](https://trabucayre.github.io/openFPGALoader/) to program designs onto an FPGA - A [Go compiler](https://go.dev/) if you want to use the debugger - [Invoke](https://www.pyinvoke.org/) to drive the build system - Some kind of VCD waveform viewer like [GTKWave](https://github.com/gtkwave/gtkwave) to debug failing tests. If you want to run this on hardware, you'll also need supported hardware. Currently, the only working target is the [ULX3S](https://ulx3s.github.io/) board with a Lattice ECP5 LFE5U-85 FPGA. Once the design is fully working, it may be ported to other boards or FPGAs. ## Developing GARY uses Invoke as a small build system. You can read tasks.py to see the details, but these are the main available commands: - `inv build `: run the Bluespec compiler on the given target. - `inv synth `: run full synthesis to bitstream on the given target. - `inv test `: run unit tests in Bluesim. - `inv clean`: delete build outputs. - `inv genclk`: generate clock configuration for the Lattice ECP5 PLL primitive. The overall workflow looks like this: - Write Bluespec SystemVerilog in .bsv files, possibly with supporting Verilog-2005 in .v files. - Use `inv build` to check the Bluespec design and elaborate the modules marked for synthesis. - Write unit tests in `_Test.bsv` files, and use `inv test` to run them. The tests run in Bluesim, and output VCD waveform files if you need to debug failures. - Create a top-level module in `/Top.bsv`, with an accompanying `/pin_map.lpf` to map I/Os to physical pins and set timing constraints. - Run `inv synth` to synthesize the top-level module into a bitstream for flashing to target. - Use `openFPGALoader` to program your hardware of choice. Most development time should be spent in the upper parts of this list, writing tests and running them in a simulator and maybe synthesizing some test designs to see how well/poorly modules turn into hardware. Trying to diagnose buggy designs on hardware is going to be very frustrating, do yourself a favor and only move to hardware with code you've already tested a whole bunch in simulation. Build targets can be a single Bluespec file (`inv build lib/UART.bsv`), or a directory to build all Bluespec in that subtree (`inv build lib`). Test targets can be a single test file (`inv test lib/Strobe_Test.bsv`) or a directory to run all tests in that subtree (`inv test lib`, `inv test .`). Synthesis targets can be a single Bluespec file (`inv synth hack/Top.bsv`), a directory containing a `Top.bsv` file (`inv synth experiments/vram`), or the name of a hardware target as found in the `hardware` subdirectory (`inv synth ulx3s`).