• Stars
    star
    167
  • Rank 226,635 (Top 5 %)
  • Language
    C++
  • License
    GNU General Publi...
  • Created over 7 years ago
  • Updated 10 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A utility for Composing FPGA designs from Peripherals

AutoFPGA - An FPGA Design Automation routine

After now having built several FPGA designs, such as the xulalx25soc, s6soc, openarty, zbasic, icozip, and even a Basys-3 design of my own that hasn't been published, I started recognizing that all of these designs have a lot in common. In particular, they all have a set of bus masters, such as the UART-to-wishbone bridge that I use, the hexbus debugging bus that offers a simpler version of the same, or even the zipcpu. Many of these designs have also started to use (and reuse) many of the peripherals I've developed, such as the generic UART, the QSPI flash controller, the SD-card controller, the block RAM controller, the RMII Ethernet Controller, the Real-Time Clock, the Real-Time Date, the Organic LED controller, Xilinx's Internal Configuration Access Port, the wishbone scope, the GPS controlled clock, or even the PWM Audio Controller. All of these peripherals have a very similar format when included within a top level design, all of these require a certain amount of care and feeding as part of that top level design, but yet rebuilding that top level design over and over just to repeat this information becomes a pain.

Where things were really starting to get annoying is where the C++ information was depending upon Verilog information. A classic example of this is the base address of any bus components. However, if you add clock rate into the mix, you can then also control things such as any default UART configuration, default clock stepping information (for the RTC clock), or even default video clock information--just by knowing the FPGA's clock rate within your C++ environment.

Sharing information between Verilog and C++ then became one of the primary reasons for creating AutoFPGA. While peripheral address decoding is typically done in some main Verilog file, other files depend upon what this peripheral decoding is. These other files include the host register definition file (used for debugging access), the register naming file, the software board definition file used by newlib, the linker script used by the compiler, and even the LaTeX specification for the board. Creating and updating all of these files by hand anytime I create a new board file can get tedious. Further, every time a board is reconfigured, the constraints file, whether XDC or UCF file, needs to be updated to match the current constraints.

Solving this multi-language coordination problem is the purpose of AutoFPGA.

Unlike many of the other tools out there, such as Xilinx's board design flow, AutoFPGA is not built with the clueless beginner in mind, neither is it built to hide the details of what is going within the project it creates. Instead, AutoFPGA is built with the sole purpose of alleviating any burden on the FPGA designer who otherwise has to create and maintain coherency between multiple design files.

That this program facilitates composing and building new designs from existing components ... is just a bonus.

Goal

The goal of AutoFPGA is to be able to take a series of bus component configuration files and to compose a design consisting of the various bus components, linked together in logic, having an appropriate bus interconnect and more.

From a user's point of view, one would run AutoFPGA with a list of component definition files, given on the command line, and to thus be able to generate (or update?) the various design files discussed above:

Specifically, the parser must determine:

  • If any of the components used in the project need to be configured, and if so, what the configuration parameters are and how they need to be set. For example, the UART baud rate and RTC and GPS clock steps both need to be set based upon the actual clock speed of the master clock. Placing a clock module within the design that sets up a clock and declares its rate is the current method for accomplishing this. Designs using more than one clock often have an allclocks.txt file to define all of the various clocks used within a design.

  • If peripherals have or create interrupts, those need to be found and determined, and (even better) wired up.

  • If an AutoFPGA configuration file describes one of the following classes of items, then the file is wired up and connected to create the necessary bus wiring as well.

    • Bus masters

      Are automatically connected to a crossbar with full access to all of the slaves on the bus

    • One-clock Peripherals (interrupt controller, etc.)

    • Two-clock Peripherals (RTC clock, block RAM, scopes, etc.)

    • Memory Peripherals

      o These need a line within the linker script, and they need to define if their memory region, within that linker script, has read, write, or

      o Generic Peripherals (flash, SDRAM, MDIO, etc.)

  • Peripheral files need to be able to describe more than one peripheral. For example, the GPS peripheral file has a GPS-Clock, a companion test bench, GPS-TB, to measure the performance of the GPS clock, and a serial port (WBUART) to allow us to read from the GPS and to write to it and so configure it. Of course ... this also includes a parameter that must be set (baud rate) based upon the global clock rate.

Classes

Some peripherals might exist at multiple locations within a design. For example, the WBUART serial component can be used to create multiple serial ports within a design.

To handle this case, the WBUART configuration file may be subclassed within other component configuration files by defining a key @INCLUDEFILE=wbuart.txt. This will provide a set of keys that the current file can then override (inherit from).

Unfortunately, this only works if the included file has only one component defined within it.

Math

Some peripherals need to be able to perform basic integer math on a given value to determine an appropriate setting value. These peripherals need access to variables. The classic examples are the baud rate, which depends upon the clock rate, as well as the step size necessary for the RTC and the GPS clocks, both of which also depend upon the master clock rate. Other examples might include determining the size of the address space to assign to a core based upon the memory size of the component and so forth.

This feature is currently fully supported using integer math.

Legacy Updates

The original version of AutoFPGA supported only one bus master, one bus type, and an interconnect with a known bug in it.

Specifically, the broken interconnect would allow a master to make requests of one peripheral and then another before the first peripheral had responded, while not preventing the requests from returning out of order.

Fixing this bug introduced several incompatible changes, therefore there is an AutoFPGA legacy git tag defined to get back to the older version.

This newer version, however, now supports:

  • Multiple bus types: Wishbone (pipelined), AXI-Lite, and AXI

    Additional busses may be supported by simply creating a C++ bus component definition class for them.

  • Full crossbar support, using bus helper files from my WB2AXIP repository.

Much to my surprise, the full crossbar support has proved to be simpler, in terms of logic elements used, than the legacy interconnect I had been using.

Status

This project now has several designs built around it. These include the basic AutoFPGA-demo project, OpenArty, ArrowZip (legacy AutoFPGA only), AXI DMA test bench, ICOZip, SDR (a gateware defined radio), ZBasic, ZipStorm-mx (legacy AutoFGPA only), and ZipVersa. There's also a rather nice Nexys Video project that I've used for modifying and delivering to customers, although the current version on github is currently a touch out of date. You can see the autogenerated logic generated for this project in the demo directory.

I've also used AutoFPGA to generate a design for the Cyclone-V on the DE-10 Nano, as well as a design for an Arty Z7-20.

In sum:

  • Simple bus components ... just work. This includes both bus masters and bus slaves. Not only that, the bus simplifier logic also "just works", with the caveat below.

    Note that the AXI SINGLE simplifier itself hasn't (yet) been built. (It's waiting on a funded need.) For now, the AXI DOUBLE bus simplifier should work quite well. To use it, just declare a bus slave to be a slave of an AXI type bus, with SLAVE.TYPE set to SINGLE, then follow the rule listed in the simplifier. The same applies to the AXI-lite simplifiers. Wishbone simplifiers, both SINGLE and DOUBLE, are handled by logic inserted into main.v, rather than referenced by main.v.

  • Components with logic in the toplevel work nicely as well.

  • AutoFPGA can now support multiple, dissimilar clock rates. Users just need to specify a clock to generate it. The clock is then made available for configuration files to reference. This includes creating a test bench wrapper for Verilator that will drive a multi-clock simulation.

  • Addresses get assigned in three groups, and processed in three groups: simple SINGLE components having only one address, simple DOUBLE components having more addresses but only a single clock delay, and all other components and memories.

  • Multiple bus support is now included, allowing you to create and attach components through bus adapters. This will allow a request to transition from one component to the next, while also keeping track of what the final addresses are for reference from the top level bus.

    This makes it possible for the SDRAM to be on one bus, supporting video reads/writes, and for the CPU to be able to access that bus as well--as a sub-bus of the main peripheral/memory bus.

  • Interrupts get assigned to a named controller, and then C++ header files are updated to reflect the interrupt assignments

  • A simple integer mathematical expression evaluator exists, allowing simple math expressions and print formats. This makes it possible to set a global clock frequency value, and to then set baud rates and other clock dividers from it.

  • Only one type of address building is supported. I'd like to be able to support others, but so far this has been sufficient for my first project.

    o Likewise, the project only supports WB B4/pipelined. No support is provided for WB B3/classic (yet), although creating such support shoud not be difficult at all.

  • AutoFPGA now builds a ZipCPU Linker Script for the project. This script is highly configurable, and many of my projects contain configurations for multiple linker scripts--depending upon which memories I decide to include in the design, or which ones I want a particular piece of software to use.

  • The LaTeX specification table building isn't there ... yet.

Sample component files

Component files now exist for many of the components I've been using regularly. These include: a Flash controller, block RAM, a UART console, a very simple GPIO controller, RMII ethernet controller, MDIO ethernet control interface, a GPS UART and PPS-driven internal clock, a Real-Time (GPS driven) Clock, a PS/2 Mouse, an OLED component, and more. Many of these component cores exist and have their own repositories elsewhere. For example, the wishbone UART core may be found here, and you can find a MIG-based, Wishbone controlled SDRAM component here. You can also find a AXI examples, such as AXI S2MM stream-to-memory data mover, an AXI MM2S memory-to-stream data mover, or an AXM block RAM component in the AXI DMA test repository. Building the cores themselves is not a part of this project, but rather figuring out how to compose multiple cores into a top level design from both cores and component descriptions.

The ZipCPU blog

Several articles have now been written to date about AutoFPGA on the ZipCPU blog. These includes:

  1. A brief introduction to AutoFPGA

  2. Using AutoFPGA to connect simple registers to a debugging bus

    This article is really out of date, in that it describes only the legacy mode (one master, one bus type, etc.)

  3. AutoFPGA's linker script support gets an update

  4. Technology debt and AutoFPGA, the bill just came due

  5. Understanding AutoFPGA's address assignment algorithm

Getting Started

The current best reference for AutoFPGA is the icd.txt file, which describes all of the various tags AutoFPGA understands and how they can be used. I've also started working on an intermediate design tutorial based around AutoFPGA, so you might find that a useful place to start as well.

License

AutoFPGA is designed for release under the GPLv3 license. The AutoFPGA generated code is yours, and free to be relicensed as you see fit.

Commercial Applications

Should you find the GPLv3 license insufficient for your needs, other licenses can be purchased from Gisselquist Technology, LLC. Given that the AutoFPGA generated code is not encumbered by any license requirements, I really don't expect any such requests.

Likewise, please contact us should you wish to guide, direct, or otherwise fund the development of this project. You can contact me at my user name, dgisselq, at the wonderful ieee.org host.

More Repositories

1

zipcpu

A small, light weight, RISC CPU soft core
Verilog
1,268
star
2

wb2axip

Bus bridges and other odds and ends
Verilog
469
star
3

wbuart32

A simple, basic, formally verified UART controller
Verilog
272
star
4

dblclockfft

A configurable C++ generator of pipelined Verilog FFT cores
C++
213
star
5

sdspi

SD-Card controller, using either SPI, SDIO, or eMMC interfaces
Verilog
185
star
6

vgasim

A Video display simulator
Verilog
154
star
7

eth10g

10Gb Ethernet Switch
C
147
star
8

dspfilters

A collection of demonstration digital filters
Verilog
138
star
9

openarty

An Open Source configuration of the Arty platform
Verilog
119
star
10

dpll

A collection of phase locked loop (PLL) related projects
Verilog
95
star
11

cordic

A series of CORDIC related projects
C++
85
star
12

qspiflash

A set of Wishbone Controlled SPI Flash Controllers
Verilog
72
star
13

wbscope

A wishbone controlled scope for FPGA's
Verilog
72
star
14

sdr

A basic Soft(Gate)ware Defined Radio architecture
Verilog
71
star
15

interpolation

Digital Interpolation Techniques Applied to Digital Signal Processing
Verilog
53
star
16

zbasic

A bare bones, basic, ZipCPU system designed for both testing and quick integration into new systems
Verilog
42
star
17

wbi2c

Wishbone controlled I2C controllers
Verilog
40
star
18

fftdemo

A demonstration showing how several components can be compsed to build a simulated spectrogram
Verilog
39
star
19

s6soc

CMod-S6 SoC
Verilog
35
star
20

dbgbus

A collection of debugging busses developed and presented at zipcpu.com
Verilog
33
star
21

rtcclock

A Real Time Clock core for FPGA's
Verilog
22
star
22

arrowzip

A ZipCPU based demonstration of the MAX1000 FPGA board
Verilog
21
star
23

wbfmtx

A wishbone controlled FM transmitter hack
Verilog
21
star
24

icozip

A ZipCPU demonstration port for the icoboard
Verilog
17
star
25

xulalx25soc

A System on a Chip Implementation for the XuLA2-LX25 board
Verilog
16
star
26

wbpwmaudio

A wishbone controlled PWM (audio) controller
Verilog
15
star
27

videozip

A ZipCPU SoC for the Nexys Video board supporting video functionality
Verilog
14
star
28

wbspi

A collection of SPI related cores
Verilog
14
star
29

website

The ZipCPU blog
HTML
14
star
30

wbpmic

Wishbone controller for a MEMs microphone
Verilog
14
star
31

qoiimg

Quite OK image compression Verilog implementation
Verilog
14
star
32

fwmpy

A multiply core generator
C++
13
star
33

zipversa

A Versa Board implementation using the AutoFPGA/ZipCPU infrastructure
Verilog
13
star
34

wbhyperram

A cross platform, formally verified, open source, hyperRAM controller with simulator
11
star
35

axidmacheck

AXI DMA Check: A utility to measure DMA speeds in simulation
Verilog
10
star
36

wbicapetwo

Wishbone to ICAPE interface conversion
Verilog
8
star
37

tinyzip

A ZipCPU based demonstration for the TinyFPGA BX board
Verilog
8
star
38

wbsata

Wishbone SATA Controller
Verilog
8
star
39

tttt

A 4x4x4 Tic-Tac-Toe game suitable for porting to embedded hardware platforms
C
8
star
40

autofpga-demo

A demonstration of how AutoFPGA can compose a design from simple components
Verilog
8
star
41

debouncer

Digital logic necessary to debounce buttons
Verilog
8
star
42

kimos

Enclustra Mercury demonstration project
C
8
star
43

openz7

OpenZ7, an open source Zynq demo based on the Arty Z7-20
Verilog
6
star
44

zipstormmx

ZipSTORM-MX, an iCE40 ZipCPU demonstration project
Verilog
5
star
45

cputest-harness

A simulation test harness, containing serial port, QSPI flash, and an output done I/O--just provide the CPU
C++
4
star
46

xtimesheet

A very simple timesheet tracking program using text files and a GTK/Glade interface
C++
1
star