From 85bb108ba40f9573571de0a785f9fbc91c4e1dd0 Mon Sep 17 00:00:00 2001 From: gatecat Date: Wed, 10 Feb 2021 11:54:54 +0000 Subject: [PATCH] Add getBelPinsForCellPin to Arch API This is a basic implementation, without considering "M of N" arrangements (e.g. for LUT permuation where you only want to route to 1 out of 4/6 sinks) or using a type other than IdString to identify bel pins. But this is also enough to start working out where in nextpnr will break due to removing the 1:1 cell:bel pin cardinality, as a next step. Signed-off-by: gatecat --- common/nextpnr.h | 8 ++++++++ docs/archapi.md | 7 +++++++ fpga_interchange/arch.h | 3 +++ generic/arch.cc | 2 ++ generic/arch.h | 2 ++ gowin/arch.cc | 2 ++ gowin/arch.h | 2 ++ 7 files changed, 26 insertions(+) diff --git a/common/nextpnr.h b/common/nextpnr.h index c43b9dc4..cf04f831 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -1093,6 +1093,7 @@ template struct ArchAPI : BaseCtx virtual WireId getBelPinWire(BelId bel, IdString pin) const = 0; virtual PortType getBelPinType(BelId bel, IdString pin) const = 0; virtual typename R::BelPinsRangeT getBelPins(BelId bel) const = 0; + virtual typename R::CellBelPinRangeT getBelPinsForCellPin(CellInfo *cell_info, IdString pin) const = 0; // Wire methods virtual typename R::AllWiresRangeT getWires() const = 0; virtual WireId getWireByName(IdStringList name) const = 0; @@ -1176,6 +1177,8 @@ template struct ArchAPI : BaseCtx // This contains the relevant range types for the default implementations of Arch functions struct BaseArchRanges { + // Bels + using CellBelPinRangeT = std::array; // Attributes using BelAttrsRangeT = std::vector>; using WireAttrsRangeT = std::vector>; @@ -1241,6 +1244,11 @@ template struct BaseArch : ArchAPI return empty_if_possible(); } + virtual typename R::CellBelPinRangeT getBelPinsForCellPin(CellInfo *cell_info, IdString pin) const override + { + return return_if_match, typename R::CellBelPinRangeT>({pin}); + } + // Wire methods virtual IdString getWireType(WireId wire) const override { return IdString(); } virtual typename R::WireAttrsRangeT getWireAttrs(WireId) const override diff --git a/docs/archapi.md b/docs/archapi.md index f6f184e0..2a38502c 100644 --- a/docs/archapi.md +++ b/docs/archapi.md @@ -13,6 +13,7 @@ The contents of `ArchRanges` is as follows: |`TileBelsRangeT` | `BelId` | |`BelAttrsRangeT` | std::pair | |`BelPinsRangeT` | `IdString` | +|`CellBelPinRangeT` | `IdString` | |`AllWiresRangeT` | `WireId` | |`DownhillPipRangeT` | `PipId` | |`UphillPipRangeT` | `PipId` | @@ -244,6 +245,12 @@ Return the type (input/output/inout) of the given bel pin. Return a list of all pins on that bel. +### CellBelPinRangeT getBelPinsForCellPin(CellInfo *cell_info, IdString pin) const + +Return the list of bel pin names that a given cell pin should be routed to. In most cases there will be a single bel pin for each cell pin; and output pins must _always_ have only one bel pin associated with them. + +*BaseArch default: returns a one-element array containing `pin`* + Wire Methods ------------ diff --git a/fpga_interchange/arch.h b/fpga_interchange/arch.h index fd2d16a2..e5c7551b 100644 --- a/fpga_interchange/arch.h +++ b/fpga_interchange/arch.h @@ -660,6 +660,7 @@ struct ArchRanges using TileBelsRangeT = BelRange; using BelAttrsRangeT = std::vector>; using BelPinsRangeT = IdStringRange; + using CellBelPinRangeT = std::array; // Wires using AllWiresRangeT = WireRange; using DownhillPipRangeT = DownhillPipRange; @@ -866,6 +867,8 @@ struct Arch : ArchAPI return str_range; } + std::array getBelPinsForCellPin(CellInfo *cell_info, IdString pin) const override { return {pin}; } + // ------------------------------------------------- WireId getWireByName(IdStringList name) const override; diff --git a/generic/arch.cc b/generic/arch.cc index 912f8a53..c51fbb84 100644 --- a/generic/arch.cc +++ b/generic/arch.cc @@ -339,6 +339,8 @@ std::vector Arch::getBelPins(BelId bel) const return ret; } +std::array Arch::getBelPinsForCellPin(CellInfo *cell_info, IdString pin) const { return {pin}; } + // --------------------------------------------------------------- WireId Arch::getWireByName(IdStringList name) const diff --git a/generic/arch.h b/generic/arch.h index 09fd8e34..e7d204ef 100644 --- a/generic/arch.h +++ b/generic/arch.h @@ -124,6 +124,7 @@ struct ArchRanges using TileBelsRangeT = const std::vector &; using BelAttrsRangeT = const std::map &; using BelPinsRangeT = std::vector; + using CellBelPinRangeT = std::array; // Wires using AllWiresRangeT = const std::vector &; using DownhillPipRangeT = const std::vector &; @@ -241,6 +242,7 @@ struct Arch : ArchAPI WireId getBelPinWire(BelId bel, IdString pin) const override; PortType getBelPinType(BelId bel, IdString pin) const override; std::vector getBelPins(BelId bel) const override; + std::array getBelPinsForCellPin(CellInfo *cell_info, IdString pin) const override; WireId getWireByName(IdStringList name) const override; IdStringList getWireName(WireId wire) const override; diff --git a/gowin/arch.cc b/gowin/arch.cc index d4e17a8a..8aeccfba 100644 --- a/gowin/arch.cc +++ b/gowin/arch.cc @@ -822,6 +822,8 @@ std::vector Arch::getBelPins(BelId bel) const return ret; } +std::array Arch::getBelPinsForCellPin(CellInfo *cell_info, IdString pin) const { return {pin}; } + // --------------------------------------------------------------- WireId Arch::getWireByName(IdStringList name) const diff --git a/gowin/arch.h b/gowin/arch.h index c5ef0a2e..eab75899 100644 --- a/gowin/arch.h +++ b/gowin/arch.h @@ -251,6 +251,7 @@ struct ArchRanges using TileBelsRangeT = const std::vector &; using BelAttrsRangeT = const std::map &; using BelPinsRangeT = std::vector; + using CellBelPinRangeT = std::array; // Wires using AllWiresRangeT = const std::vector &; using DownhillPipRangeT = const std::vector &; @@ -375,6 +376,7 @@ struct Arch : BaseArch WireId getBelPinWire(BelId bel, IdString pin) const override; PortType getBelPinType(BelId bel, IdString pin) const override; std::vector getBelPins(BelId bel) const override; + std::array getBelPinsForCellPin(CellInfo *cell_info, IdString pin) const override; WireId getWireByName(IdStringList name) const override; IdStringList getWireName(WireId wire) const override;