Skip to content

Commit

Permalink
Merge pull request #221 from stnolting/update_osflow_readme
Browse files Browse the repository at this point in the history
[setups/osflow] update README
  • Loading branch information
stnolting committed Dec 14, 2021
2 parents 71f3d26 + 9c85f47 commit a452662
Showing 1 changed file with 104 additions and 4 deletions.
108 changes: 104 additions & 4 deletions setups/osflow/README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,38 @@
# Exemplary FPAG Board Setups - Using Open Source Toolchains

* [Folder Structure](#Folder-Structure)
* [Prerequisites](#Prerequisites)
* [How To Run](#How-To-Run)
* [Porting to a new FPGA or Board](#Porting-to-a-new-FPGA-or-Board)

This folder provides the infrastructure for generating bitstream for various FPGAs using
open source toolchains. Synthesis based on [ghdl-yosys](https://github.com/ghdl/ghdl-yosys-plugin).
open-source toolchains. Synthesis is based on [ghdl-yosys](https://github.com/ghdl/ghdl-yosys-plugin).

:information_source: Note that the provided setups just implement very basic SoC configurations.
These setups are intended as minimal example (how to synthesize the processor) for a given FPGA + board
that can be used as starting point to build more complex user-defined SoCs.

## Folder Structure

* `.`: Main makefile (main entry point) and partial-makefiles for synthesis, place & route and bitstream generation
* `boards`: board-specific _partial makefiles_ (used in by main makefile `Makefile`) for generating bitstreams
* `boards`: board-specific _partial makefiles_ (used by main makefile "`Makefile`") for generating bitstreams
* `board_top`: board-specific top entities (board wrappers; may include FPGA-specific modules)
* `constraints`: physical constraints (mainly pin mappings)
* `devices`: FPGA-specific primitives and optimized processor modules (like memories)


## Prerequisites

:construction: **TODO - Under Construction** :construction:
:construction: TODO :construction:

* local installation of the tools
* using containers


## How To Run

:construction: TODO :construction:

The `Makefile` in this folder is the main entry point. To run the whole process of synthesis, place & route and bitstream
generation run:

Expand All @@ -42,4 +53,93 @@ targets are listed in the `boards/` folder where each partial-makefile correspon
[`rtl/processor_templates`](https://github.com/stnolting/neorv32/tree/master/rtl/processor_templates).


See https://github.com/stnolting/neorv32/blob/master/.github/workflows/Implementation.yml
## Porting to a new FPGA or Board

This sections illustrates how to add a new basic setup for a specific FPGA and board. This tutorial used the iCEBreaker
"MinimalBoot" setup as reference.

#### 1. Setup a board- and FPGA-specific top entity

1. Write a new top design unit that instantiates one of the provided processor templates from
[`rtl/processor_templates`](https://github.com/stnolting/neorv32/tree/master/rtl/processor_templates).
This new top unit can be a Verilog or VHDL file.
2. _Optional:_ You can also include FPGA-specific primitives like PLLs or block RAMs (but keep it simple). These components
need to be added to a FPGA-specific library in [`setups/osflow/devices`](https://github.com/stnolting/neorv32/tree/master/setups/osflow/devices).
3. Try to keep the external IO at a minimum even if the targeted FPGA boards provides cool features. Besides of clock and reset
you need to add at least one kind of IO interface like a UART, GPIO or PWM.
4. Give your new top entity file a specific name that includes the board's name and the instantiated processor template.
The name scheme is `neorv32_[board-name]_BoardTop_[template-name].[v/vhd]`.
5. Put this file in `setups/osflow/board_tops`.
6. Take a look at the iCEBreaker MinimalBoot top entity as a reference:
[`setups/osflow/board_tops/neorv32_iCEBreaker_BoardTop_MinimalBoot.vhd`](https://github.com/stnolting/neorv32/blob/master/setups/osflow/board_tops/neorv32_iCEBreaker_BoardTop_MinimalBoot.vhd)

#### 2. Pin mapping

1. Add a new constraints file to define the mapping between the your top unit's IO and the FPGA's physical pins.
You can add _all_ of the FPGA's physical pins even though just a subset is used by the new setup.
2. Name the new constraints file according to the board `[board-name].pcf`.
3. Put this file in `setups/osflow/constraints`.
4. Take a look at the iCEBreaker pin mapping as a reference:
[`setups/osflow/constraints/iCEBreaker.pcf`](https://github.com/stnolting/neorv32/blob/master/setups/osflow/constraints/iCEBreaker.pcf)

#### 3. Adding a board-specific makefile

1. Add a board-specific makefile to the `setups/osflow/boards` folder. Name the new constraints file according to the board `[board-name].mk`.
2. The makefile contains (at least) one target to build the final bitstream:
```makefile
.PHONY: all

all: bit
echo "! Built $(IMPL) for $(BOARD)"
```
3. Take a look at the iCEBreaker pin mapping as a reference:
[` setups/osflow/boards/iCEBreaker.mk`](https://github.com/stnolting/neorv32/blob/master/setups/osflow/boards/iCEBreaker.mk)

#### 4. Adding a new target to `index.mk`

1. Add a new conditional section to the boards management makefile `setups/osflow/boards/index.mk`.
2. This board-specific section sets variables that are required to run synthesis, mapping, place & route and bitstream generation:
* `CONSTRAINTS` defines the physical pin mapping file
* `PNRFLAGS` defines the FPGA-specific flags for mapping and place & route
* `IMPL` defines the setup's implementation name
```makefile
ifeq ($(BOARD),iCEBreaker)
$(info Setting constraints and implementation args for BOARD iCEBreaker)

CONSTRAINTS ?= $(PCF_PATH)/$(BOARD).pcf
PNRFLAGS ?= --up5k --package sg48 --ignore-loops --timing-allow-fail
IMPL ?= neorv32_$(BOARD)_$(ID)

endif
```

#### 5. Adding a new target to the main makefile

1. As final step add the new setup to the main osflow makefile `setups/osflow/Makefile`.
2. Use the board's name to create a new makefile target.
* The new target should set the final bitstream's name using the `BITSTREAM` variable.
* Alternative _memory_ HDL sources like FPGA-optimized module can be set using the `NEORV32_MEM_SRC` variable.
```makefile
iCEBreaker:
$(eval BITSTREAM ?= neorv32_$(BOARD)_$(DESIGN).bit)
$(eval NEORV32_MEM_SRC ?= devices/ice40/neorv32_imem.ice40up_spram.vhd devices/ice40/neorv32_dmem.ice40up_spram.vhd)
$(MAKE) \
BITSTREAM="$(BITSTREAM)" \
NEORV32_MEM_SRC="$(NEORV32_MEM_SRC)" \
run
```

#### 6. _Optional:_ Add the new setup to the automatic "Implementation" github workflow

If you like you can add the new setup to the automatic build environment of the project. The project's "Implementation"
workflow will generate bitstreams for all configured osflow setups on every repository push. This is used to check for
regressions and also to provide up-to-date bitstreams that can be used right away.

1. Add the new setup to the job matrix file `.github/generate-job-matrix.py`.
```python
{
'board': 'iCEBreaker',
'design': 'MinimalBoot',
'bitstream': 'neorv32_iCEBreaker_MinimalBoot.bit'
},
```

0 comments on commit a452662

Please sign in to comment.