aboutsummaryrefslogtreecommitdiffstats
path: root/backends/intersynth/intersynth.cc
diff options
context:
space:
mode:
Diffstat (limited to 'backends/intersynth/intersynth.cc')
0 files changed, 0 insertions, 0 deletions
> 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
# nextpnr Coding Notes

This document aims to provide an overview into the philosophy behind nextpnr's codebase and some tips and tricks for developers.

## See also

 - [FAQ](faq.md) - overview of terminology
 - [Arch API](archapi.md) - reference for the using and implementing the Architecture API
 - [Netlist Structure](netlist.md) - reference for the netlist data structures
 - [Python API](python.md) - Python API overview for netlist access, constraints, etc
 - [Generic Architecture](generic.md) - using the Python API to create architectures

## nextpnr Architectures

An architecture in nextpnr is described first and foremost as code. The exact details are given in the [Arch API reference](archapi.md); this aims to explain the core concept.

By choosing this approach; this gives architectures significant flexibility to use more advanced database representations than a simple flat database - for example deduplicated approaches that store similar tiles only once.

Architectures can also implement custom algorithms for packing (or other initial netlist transformations) and specialized parts of placement and routing such as global clock networks. This is because architectures provide the `pack()`, `place()` and `route()` functions, although the latter two will normally use generic algorithms (such as HeAP and router1) to do most of the work.

Another important function provided by architectures is placement validity checking. This allows the placer to check whether or not a given cell placement is valid. An example of this is for iCE40, where 8 logic cells in a tile share one clock signal - this is checked here.

This function allows architectures in nextpnr to do significantly less packing than in traditional FPGA CAD flows. Although `pack()` could pack entire tiles, it is more idiomatic to pack to logic cells (e.g. single LUT and FF or two LUTFFs) or even smaller units like the LUTs and FFs themselves (in this case all the "packer" would do is convert LUTs and FFs to a common type if needed.)

Additionally to this; architectures provide functions for checking the availability and conflicts between resources (e.g. `checkBelAvail`, `checkPipAvail`, etc). This enables arbitrary constraints between resource availability to be defined, for example:

 - where a group of pips share bitstream bits, only one can be used at a time