diff --git a/README.md b/README.md index b0b56225..bf169613 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,6 @@ nextpnr -- a portable FPGA place and route tool nextpnr aims to be a vendor neutral, timing driven, FOSS FPGA place and route tool. -nextpnr was [started by SymbioticEDA](https://www.symbioticeda.com/) as an -experimental replacement for the existing Arachne-PNR base toolchain (hence the -name *next*pnr). Focusing on supporting timing driven place and route for -multiple FPGA architectures from the ground up, the experiment has proven -successful and we believe nextpnr is on its way to being a suitable -replacement for all users of Arachne-PNR. - Currently nextpnr supports; * Lattice iCE40 devices supported by [Project IceStorm](http://www.clifford.at/icestorm/), * *(experimental)* Lattice ECP5 devices supported by [Project Trellis](https://github.com/SymbiFlow/prjtrellis), @@ -22,11 +15,14 @@ FPGAs supported in the future. We would love your help in developing this awesome new project. Here is a screenshot of nextpnr for iCE40. Build instructions and -[getting started notes](#getting-started) and an [FAQ](#FAQ) can be found -below. +[getting started notes](#getting-started) can be found below. +See also: +- [F.A.Q.](docs/faq.md) +- [Architecture API](docs/archapi.md) + Prerequisites ------------- @@ -150,133 +146,6 @@ Testing - `-DSANITIZE_UNDEFINED=ON` - Running valgrind example `valgrind --leak-check=yes --tool=memcheck ./nextpnr-ice40 --json ice40/blinky.json` - -FAQ ---- - -### Which tool chain should I use and why? - - * If you wish to do new **research** into FPGA architectures, place and route - algorithms or other similar topics, we suggest you look at using - [Verilog to Routing](https://verilogtorouting.org). - - * If you are developing FPGA code in **Verilog** for a **Lattice iCE40** and - need an open source toolchain, we suggest you use nextpnr. - - * If you are developing FPGA code in **Verilog** for a **Lattice iCE40** with - the **existing Arachne-PNR toolchain**, we suggest you start thinking about - migrating to nextpnr. - - * If you are developing Verilog FPGA code targeted at the Lattice ECP5 and - need an open source toolchain, you may consider the **extremely - experimental** ECP5 support in nextpnr. - - * If you are developing FPGA code in **VHDL** you will need to use either a - version of [Yosys with Verific support]() or the vendor provided tools due - to the lack of open source VHDL support in Yosys. - -### Why didn't you just improve [Arachne-PNR](https://github.com/cseed/arachne-pnr)? - -[Arachne-PNR](https://github.com/cseed/arachne-pnr) was originally developed as -part of [Project IceStorm](http://www.clifford.at/icestorm/) to demonstrate it -was possible to create an open source place and route tool for the iCE40 FPGAs -that actually produced valid bitstreams. - -For it's original purpose it has served the community extremely well. However, -it was never designed to support multiple different FPGA devices, nor more -complicated timing driven routing used by most commercial place and route -tools. - -It felt like extending Arachne-PNR was not going to be the best path forward, so -[SymbioticEDA](https://www.symbioticeda.com/) decided to invest in an -experiment around creating a replacement. nextpnr is the result of that -experiment and we believe well on it's way to being a direct replacement for -Arachne-PNR (and hence why it is called *next*pnr). - -### Arachne-PNR does X better! - -If you have a use case which prevents you from switching to nextpnr from -Arachne, we want to hear about it! Please create an issue following the -[Arachne-PNR regression template]() and we will do our best to solve the problem! - -We want nextpnr to be a suitable replacement for anyone who is currently a user -of Arachne. - -### Why are you not just contributing to [Verilog to Routing](https://verilogtorouting.org)? - -We believe that [Verilog to Routing](https://verilogtorouting.org) is a great -tool and many of the nextpnr developers have made (and continue to make) -contributions to the project. - -VtR is an extremely flexible tool but focuses on research around FPGA -architecture and algorithm development. If your goal is research, then we very -much encourage you to look into VtR further! - -nextpnr takes a different approach by focusing on users developing FPGA code -for current FPGAs. - -We also believe that support for real architectures will enable interesting new -research. nextpnr (like all place and route systems). depends heavily on -research groups like the VtR developers to investigate and push forward FPGA -algorithms in new and exciting ways. - -#### What is VPR? - -VPR is the "place and route" tool from Verilog To Routing. It has a similar -role in an FPGA development flow as nextpnr. - -### What about [SymbiFlow](http://symbiflow.github.io)? - -We expect that as nextpnr matures, it will become a key part of the -[SymbiFlow](http://github.com/SymbiFlow). For now, while still in a more -experimental state SymbioticEDA will continue to host the project. - -For the moment SymbiFlow is continuing to concentrate on extending Verilog to -Routing tool to work with real world architectures. - -### Who is working on this project? - -nextpnr was -[started as an experiment by SymbioticEDA](https://www.symbioticeda.com/) but -hopes to grow beyond being both just an experiment and developed by a single -company. Like Linux grew from Linus Torvalds experiment in creating his own -operating system to something contributed too by many different companies, are -hope is the same will happen here. - -The project has already accepted a number of contributions from people not -employed by SymbioticEDA and now with the public release encourages the -community to contribute too. - - -### What is [Project Trellis](https://github.com/SymbiFlow/prjtrellis)? - -[Project Trellis](https://github.com/SymbiFlow/prjtrellis) is the effort to -document the bitstream format for the Lattice ECP5 series of FPGAs. It also -includes tooling around bitstream creation. - -Project Trellis is used by nextpnr to enable support for creation of bitstreams -for these parts. - -### What is [Project X-Ray](https://github.com/SymbiFlow/prjxray)? - -[Project X-Ray](https://github.com/SymbiFlow/prjxray) is the effort to document -the bitstream format for the Xilinx Series 7 series of FPGAs. It also includes -tooling around bitstream generation for these parts. - -While nextpnr currently does **not** support these Xilinx parts, we expect it -will soon by using Project X Ray in a similar manner to Project Trellis. - -### What is [Project IceStorm](http://www.clifford.at/icestorm/)? - -[Project IceStorm](http://www.clifford.at/icestorm/) was both a project to -document the bitstream for the Lattice iCE40 series of parts **and** a full -flow including Yosys and Arachne-PNR for converting Verilog into a bitstream for -these parts. - -As the open source community now has support for multiple different FPGA parts, -in the nextpnr documentation we generally use Project IceStorm to mean the -tools that fulfil the same role as Project Trellis or Project X-Ray. - Links and references -------------------- diff --git a/docs/archapi.md b/docs/archapi.md new file mode 100644 index 00000000..4cd4d963 --- /dev/null +++ b/docs/archapi.md @@ -0,0 +1,282 @@ +Each architecture must implement the following types and APIs. + +The syntax `const_range` is used to denote anything that has a `begin()` and `end()` method that return const forward iterators. This can be a `std::list`, `std::vector`, a (const) reference to those, or anything else that behaves in a similar way. + +archdefs.h +========== + +The architecture-specific `archdefs.h` must define the following types. + +With the exception of `ArchNetInfo` and `ArchCellInfo`, the following types should be "lightweight" enough so that passing them by value is sensible. + +### delay_t + +A scalar type that is used to represent delays. May be an integer or float type. + +### DelayInfo + +A struct representing the delay across a timing arc. Must provide a `+` operator for getting the combined delay of two arcs, and the following methods to access concrete timings: + +``` +delay_t minRaiseDelay() const { return delay; } +delay_t maxRaiseDelay() const { return delay; } + +delay_t minFallDelay() const { return delay; } +delay_t maxFallDelay() const { return delay; } + +delay_t minDelay() const { return delay; } +delay_t maxDelay() const { return delay; } +``` + +### BelType + +A type representing a bel type name. `BelType()` must construct a unique null-value. Must provide `==` and `!=` operators and a specialization for `std::hash`. + +### PortPin + +A type representing a port or pin name. `PortPin()` must construct a unique null-value. Must provide `==` and `!=` operators and a specialization for `std::hash`. + +### BelId + +A type representing a bel name. `BelId()` must construct a unique null-value. Must provide `==` and `!=` operators and a specialization for `std::hash`. + +### WireId + +A type representing a wire name. `WireId()` must construct a unique null-value. Must provide `==` and `!=` operators and a specialization for `std::hash`. + +### PipId + +A type representing a pip name. `PipId()` must construct a unique null-value. Must provide `==` and `!=` operators and a specialization for `std::hash`. + +### GroupId + +A type representing a group name. `GroupId()` must construct a unique null-value. Must provide `==` and `!=` operators and a specialization for `std::hash`. + +### DecalId + +A type representing a reference to a graphical decal. `DecalId()` must construct a unique null-value. Must provide `==` and `!=` operators and a specialization for `std::hash`. + +### ArchNetInfo + +The global `NetInfo` type derives from this one. Can be used to add arch-specific data (caches of information derived from wire attributes, bound wires and pips, and other net state). Must be declared as empty struct if unused. + +### ArchCellInfo + +The global `CellInfo` type derives from this one. Can be used to add arch-specific data (caches of information derived from cell attributes and parameters, bound bel, and other cell state). Must be declared as empty struct if unused. + +arch.h +====== + +Each architecture must provide their own implementation of the `Arch` struct in `arch.h`. `Arch` must derive from `BaseCtx` and must provide the following methods: + +General Methods +--------------- + +### Arch(ArchArgs args) + +Constructor. ArchArgs is a architecture-specific type (usually a struct also defined in `arch.h`). + +### std::string getChipName() const + +Return a string representation of the ArchArgs that was used to construct this object. + +### IdString belTypeToId(BelType type) const + +Convert a `BelType` to an `IdString`. + +### IdString portPinToId(PortPin type) const + +Convert a `PortPin` to an `IdString`. + +### BelType belTypeFromId(IdString id) const + +Convert `IdString` to `BelType`. + +### PortPin portPinFromId(IdString id) const + +Convert `IdString` to `PortPin`. + +### int getGridDimX() const + +Get grid X dimension. All bels must have Y coordinates in the range `0 .. getGridDimX()-1` (inclusive). + +### int getGridDimY() const + +Get grid Y dimension. All bels must have Y coordinates in the range `0 .. getGridDimY()-1` (inclusive). + +### int getTileDimZ(int x, int y) const + +Get Z dimension for the specified tile. All bels with the specified X and Y coordinates must have a Z coordinate in the range `0 .. getTileDimZ(X,Y)-1` (inclusive). + +Bel Methods +----------- + +### BelId getBelByName(IdString name) const + +Lookup a bel by its name. + +### IdString getBelName(BelId bel) const + +Get the name for a bel. (Bel names must be unique.) + +### Loc getBelLocation(BelId bel) const + +Get the X/Y/Z location of a given bel. + +### BelId getBelByLocation(Loc loc) const + +Lookup a bel by its X/Y/Z location. + +### const_range\ getBelsByTile(int x, int y) const + +Return a list of all bels at the give X/Y location. + +### bool getBelGlobalBuf(BelId bel) const + +Returns true if the given bel is a global buffer. A global buffer does not "pull in" other cells it drives to be close to the location of the global buffer. + +### uint32_t getBelChecksum(BelId bel) const + +Return a checksum for the state of a bel. (Used to calculate the design checksum.) + +### void bindBel(BelId bel, IdString cell, PlaceStrength strength) + +Bind a given bel to a given cell with the given strength. + +### void unbindBel(BelId bel) + +Unbind a bel. + +### bool checkBelAvail(BelId bel) const + +Returns true if the bel is available. A bel can be unavailable because it is bound, or because it is exclusive to some other resource that is bound. + +### IdString getBoundBelCell(BelId bel) const + +Return the cell the given bel is bound to, or `IdString()` if the bel is not bound. + +### IdString getConflictingBelCell(BelId bel) const + +If the bel is unavailable, and unbinding a single cell would make it available, then this method must return the name of that cell. + +### const_range\ getBels() const + +Return a list of all bels on the device. + +### BelType getBelType(BelId bel) const + +Return the type of a given bel. + +### WireId getBelPinWire(BelId bel, PortPin pin) const + +Return the wire connected to the given bel pin. + +### PortType getBelPinType(BelId bel, PortPin pin) const + +Return the type (input/output/inout) of the given bel pin. + +### const_range\ getBelPins(BelId bel) const + +Return a list of all pins on that bel. + +Wire Methods +------------ + +``` +WireId getWireByName(IdString name) const +IdString getWireName(WireId wire) const +IdString getWireType(WireId wire) const +uint32_t getWireChecksum(WireId wire) const +void bindWire(WireId wire, IdString net, PlaceStrength strength) +void unbindWire(WireId wire) +bool checkWireAvail(WireId wire) const +IdString getBoundWireNet(WireId wire) const +IdString getConflictingWireNet(WireId wire) const +DelayInfo getWireDelay(WireId wire) const +const_range getWires() const +const_range getWireBelPins(WireId wire) const +``` + +Pip Methods +----------- + +``` +PipId getPipByName(IdString name) const +IdString getPipName(PipId pip) const +IdString getPipType(PipId pip) const +uint32_t getPipChecksum(PipId pip) const +void bindPip(PipId pip, IdString net, PlaceStrength strength) +void unbindPip(PipId pip) +bool checkPipAvail(PipId pip) const +IdString getBoundPipNet(PipId pip) const +IdString getConflictingPipNet(PipId pip) const +const_range getPips() const +WireId getPipSrcWire(PipId pip) const +WireId getPipDstWire(PipId pip) const +DelayInfo getPipDelay(PipId pip) const +const_range getPipsDownhill(WireId wire) const +const_range getPipsUphill(WireId wire) const +const_range getWireAliases(WireId wire) const +``` + +Group Methods +------------- + +``` +GroupId getGroupByName(IdString name) const +IdString getGroupName(GroupId group) const +const_range getGroups() const +const_range getGroupBels(GroupId group) const +const_range getGroupWires(GroupId group) const +const_range getGroupPips(GroupId group) const +const_range getGroupGroups(GroupId group) const +``` + +Delay Methods +------------- + +``` +delay_t estimateDelay(WireId src, WireId dst) const +delay_t getDelayEpsilon() const +delay_t getRipupDelayPenalty() const +float getDelayNS(delay_t v) const +uint32_t getDelayChecksum(delay_t v) const +``` + +Flow Methods +------------ + +``` +bool pack() +bool place() +bool route() +``` + +Graphics Methods +---------------- + +``` +const_range getDecalGraphics(DecalId decal) const +DecalXY getFrameDecal() const +DecalXY getBelDecal(BelId bel) const +DecalXY getWireDecal(WireId wire) const +DecalXY getPipDecal(PipId pip) const +DecalXY getGroupDecal(GroupId group) const +``` + +Cell Delay Methods +------------------ + +``` +bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const +IdString getPortClock(const CellInfo *cell, IdString port) const +bool isClockPort(const CellInfo *cell, IdString port) const +``` + +Placer Methods +-------------- + +``` +bool isValidBelForCell(CellInfo *cell, BelId bel) const +bool isBelLocationValid(BelId bel) const +``` diff --git a/docs/faq.md b/docs/faq.md new file mode 100644 index 00000000..50cd1376 --- /dev/null +++ b/docs/faq.md @@ -0,0 +1,128 @@ +FAQ +=== + +Nextpnr and other tools +----------------------- + +### Which tool chain should I use and why? + + * If you wish to do new **research** into FPGA architectures, place and route + algorithms or other similar topics, we suggest you look at using + [Verilog to Routing](https://verilogtorouting.org). + + * If you are developing FPGA code in **Verilog** for a **Lattice iCE40** and + need an open source toolchain, we suggest you use nextpnr. + + * If you are developing FPGA code in **Verilog** for a **Lattice iCE40** with + the **existing Arachne-PNR toolchain**, we suggest you start thinking about + migrating to nextpnr. + + * If you are developing Verilog FPGA code targeted at the Lattice ECP5 and + need an open source toolchain, you may consider the **extremely + experimental** ECP5 support in nextpnr. + + * If you are developing FPGA code in **VHDL** you will need to use either a + version of [Yosys with Verific support]() or the vendor provided tools due + to the lack of open source VHDL support in Yosys. + +### Why didn't you just improve [Arachne-PNR](https://github.com/cseed/arachne-pnr)? + +[Arachne-PNR](https://github.com/cseed/arachne-pnr) was originally developed as +part of [Project IceStorm](http://www.clifford.at/icestorm/) to demonstrate it +was possible to create an open source place and route tool for the iCE40 FPGAs +that actually produced valid bitstreams. + +For it's original purpose it has served the community extremely well. However, +it was never designed to support multiple different FPGA devices, nor more +complicated timing driven routing used by most commercial place and route +tools. + +It felt like extending Arachne-PNR was not going to be the best path forward, so +[SymbioticEDA](https://www.symbioticeda.com/) decided to invest in an +experiment around creating a replacement. nextpnr is the result of that +experiment and we believe well on it's way to being a direct replacement for +Arachne-PNR (and hence why it is called *next*pnr). + +### Arachne-PNR does X better! + +If you have a use case which prevents you from switching to nextpnr from +Arachne, we want to hear about it! Please create an issue following the +[Arachne-PNR regression template]() and we will do our best to solve the problem! + +We want nextpnr to be a suitable replacement for anyone who is currently a user +of Arachne. + +### Why are you not just contributing to [Verilog to Routing](https://verilogtorouting.org)? + +We believe that [Verilog to Routing](https://verilogtorouting.org) is a great +tool and many of the nextpnr developers have made (and continue to make) +contributions to the project. + +VtR is an extremely flexible tool but focuses on research around FPGA +architecture and algorithm development. If your goal is research, then we very +much encourage you to look into VtR further! + +nextpnr takes a different approach by focusing on users developing FPGA code +for current FPGAs. + +We also believe that support for real architectures will enable interesting new +research. nextpnr (like all place and route systems). depends heavily on +research groups like the VtR developers to investigate and push forward FPGA +algorithms in new and exciting ways. + +#### What is VPR? + +VPR is the "place and route" tool from Verilog To Routing. It has a similar +role in an FPGA development flow as nextpnr. + +### What about [SymbiFlow](http://symbiflow.github.io)? + +We expect that as nextpnr matures, it will become a key part of the +[SymbiFlow](http://github.com/SymbiFlow). For now, while still in a more +experimental state SymbioticEDA will continue to host the project. + +For the moment SymbiFlow is continuing to concentrate on extending Verilog to +Routing tool to work with real world architectures. + +### Who is working on this project? + +nextpnr was +[started as an experiment by SymbioticEDA](https://www.symbioticeda.com/) but +hopes to grow beyond being both just an experiment and developed by a single +company. Like Linux grew from Linus Torvalds experiment in creating his own +operating system to something contributed too by many different companies, are +hope is the same will happen here. + +The project has already accepted a number of contributions from people not +employed by SymbioticEDA and now with the public release encourages the +community to contribute too. + + +### What is [Project Trellis](https://github.com/SymbiFlow/prjtrellis)? + +[Project Trellis](https://github.com/SymbiFlow/prjtrellis) is the effort to +document the bitstream format for the Lattice ECP5 series of FPGAs. It also +includes tooling around bitstream creation. + +Project Trellis is used by nextpnr to enable support for creation of bitstreams +for these parts. + +### What is [Project X-Ray](https://github.com/SymbiFlow/prjxray)? + +[Project X-Ray](https://github.com/SymbiFlow/prjxray) is the effort to document +the bitstream format for the Xilinx Series 7 series of FPGAs. It also includes +tooling around bitstream generation for these parts. + +While nextpnr currently does **not** support these Xilinx parts, we expect it +will soon by using Project X Ray in a similar manner to Project Trellis. + +### What is [Project IceStorm](http://www.clifford.at/icestorm/)? + +[Project IceStorm](http://www.clifford.at/icestorm/) was both a project to +document the bitstream for the Lattice iCE40 series of parts **and** a full +flow including Yosys and Arachne-PNR for converting Verilog into a bitstream for +these parts. + +As the open source community now has support for multiple different FPGA parts, +in the nextpnr documentation we generally use Project IceStorm to mean the +tools that fulfil the same role as Project Trellis or Project X-Ray.