From 8f76af40db830e023b7c6627f927b492a1e16ec2 Mon Sep 17 00:00:00 2001 From: "D. Shah" Date: Wed, 3 Feb 2021 11:38:53 +0000 Subject: nextpnr: Add base virtual functions for non-range Arch API This makes the Arch API clearer and also allows a base implementation of functions to reduce the amount of complexity to get a basic Arch up and running. Currently this only implements these for functions that don't return a range. Range-returning functions will require more work in order due to the current 'duck typing' approach (probably a struct that contains the range types combined with templating.) Signed-off-by: D. Shah --- common/nextpnr.h | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index 2445bed1..7ffda0dc 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -1006,6 +1006,114 @@ struct BaseCtx void archInfoToAttributes(); void attributesToArchInfo(); + + // -------------------------------------------------------------- + // Arch API base + + // Basic config + virtual int getGridDimX() const = 0; + virtual int getGridDimY() const = 0; + virtual int getTileBelDimZ(int x, int y) const = 0; + virtual int getTilePipDimZ(int x, int y) const { return 1; } + virtual char getNameDelimiter() const { return ' '; } + + // Bel methods + virtual BelId getBelByName(IdStringList name) const = 0; + virtual IdStringList getBelName(BelId bel) const = 0; + virtual uint32_t getBelChecksum(BelId bel) const { return uint32_t(std::hash()(bel)); } + virtual void bindBel(BelId bel, CellInfo *cell, PlaceStrength strength) = 0; + virtual void unbindBel(BelId bel) = 0; + virtual Loc getBelLocation(BelId bel) const = 0; + virtual BelId getBelByLocation(Loc loc) const = 0; + virtual bool getBelGlobalBuf(BelId bel) const { return false; } + virtual bool checkBelAvail(BelId bel) const = 0; + virtual CellInfo *getBoundBelCell(BelId bel) const = 0; + virtual CellInfo *getConflictingBelCell(BelId bel) const = 0; + virtual IdString getBelType(BelId bel) const = 0; + virtual WireId getBelPinWire(BelId bel, IdString pin) const = 0; + virtual PortType getBelPinType(BelId bel, IdString pin) const = 0; + + // Wire methods + virtual WireId getWireByName(IdStringList name) const = 0; + virtual IdStringList getWireName(WireId wire) const = 0; + virtual IdString getWireType(WireId wire) const { return IdString(); } + virtual uint32_t getWireChecksum(WireId wire) const { return uint32_t(std::hash()(wire)); } + virtual void bindWire(WireId wire, NetInfo *net, PlaceStrength strength) = 0; + virtual void unbindWire(WireId wire) = 0; + virtual bool checkWireAvail(WireId wire) const = 0; + virtual NetInfo *getBoundWireNet(WireId wire) const = 0; + virtual WireId getConflictingWireWire(WireId wire) const { return wire; }; + virtual NetInfo *getConflictingWireNet(WireId wire) const { return getBoundWireNet(wire); } + virtual DelayInfo getWireDelay(WireId wire) const = 0; + + // Pip methods + virtual PipId getPipByName(IdStringList name) const = 0; + virtual IdStringList getPipName(PipId pip) const = 0; + virtual IdString getPipType(PipId pip) const { return IdString(); } + virtual uint32_t getPipChecksum(PipId pip) const { return uint32_t(std::hash()(pip)); } + virtual void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) = 0; + virtual void unbindPip(PipId pip) = 0; + virtual bool checkPipAvail(PipId pip) const = 0; + virtual NetInfo *getBoundPipNet(PipId pip) const = 0; + virtual WireId getConflictingPipWire(PipId pip) const { return WireId(); } + virtual NetInfo *getConflictingPipNet(PipId pip) const { return nullptr; } + virtual WireId getPipSrcWire(PipId pip) const = 0; + virtual WireId getPipDstWire(PipId pip) const = 0; + virtual DelayInfo getPipDelay(PipId pip) const = 0; + virtual Loc getPipLocation(PipId pip) const = 0; + + // Group methods + virtual GroupId getGroupByName(IdStringList name) const = 0; + virtual IdStringList getGroupName(GroupId group) const = 0; + virtual delay_t estimateDelay(WireId src, WireId dst) const = 0; + virtual ArcBounds getRouteBoundingBox(WireId src, WireId dst) const = 0; + + // Delay methods + virtual delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const = 0; + virtual delay_t getDelayEpsilon() const = 0; + virtual delay_t getRipupDelayPenalty() const = 0; + virtual float getDelayNS(delay_t v) const = 0; + virtual DelayInfo getDelayFromNS(float ns) const = 0; + virtual uint32_t getDelayChecksum(delay_t v) const = 0; + virtual bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const + { + return false; + } + + // Decal methods + virtual DecalXY getBelDecal(BelId bel) const { return DecalXY(); } + virtual DecalXY getWireDecal(WireId wire) const { return DecalXY(); } + virtual DecalXY getPipDecal(PipId pip) const { return DecalXY(); } + virtual DecalXY getGroupDecal(GroupId group) const { return DecalXY(); } + + // Cell timing methods + virtual bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const + { + return false; + } + virtual TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const + { + return TMG_IGNORE; + } + virtual TimingClockingInfo getPortClockingInfo(const CellInfo *cell, IdString port, int index) const + { + NPNR_ASSERT_FALSE("unreachable"); + } + + // Placement validity checks + virtual bool isValidBelForCellType(IdString cell_type, BelId bel) const { return cell_type == getBelType(bel); } + virtual IdString getBelBucketName(BelBucketId bucket) const = 0; + virtual BelBucketId getBelBucketByName(IdString name) const = 0; + virtual BelBucketId getBelBucketForBel(BelId bel) const = 0; + virtual BelBucketId getBelBucketForCellType(IdString cell_type) const = 0; + virtual bool isValidBelForCell(CellInfo *cell, BelId bel) const { return true; } + virtual bool isBelLocationValid(BelId bel) const { return true; } + + // Flow methods + virtual bool pack() = 0; + virtual bool place() = 0; + virtual bool route() = 0; + virtual void assignArchInfo(){}; }; NEXTPNR_NAMESPACE_END -- cgit v1.2.3 From cfa9a9daec648384a7337a504759ec81ba9d5870 Mon Sep 17 00:00:00 2001 From: "D. Shah" Date: Wed, 3 Feb 2021 12:10:53 +0000 Subject: nextpnr: Use templates to specify range types Signed-off-by: D. Shah --- common/nextpnr.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index 7ffda0dc..298fe26b 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -1006,7 +1006,10 @@ struct BaseCtx void archInfoToAttributes(); void attributesToArchInfo(); +}; +template struct ArchBase : BaseCtx +{ // -------------------------------------------------------------- // Arch API base @@ -1018,6 +1021,7 @@ struct BaseCtx virtual char getNameDelimiter() const { return ' '; } // Bel methods + virtual typename R::AllBelsRange getBels() const = 0; virtual BelId getBelByName(IdStringList name) const = 0; virtual IdStringList getBelName(BelId bel) const = 0; virtual uint32_t getBelChecksum(BelId bel) const { return uint32_t(std::hash()(bel)); } @@ -1025,19 +1029,26 @@ struct BaseCtx virtual void unbindBel(BelId bel) = 0; virtual Loc getBelLocation(BelId bel) const = 0; virtual BelId getBelByLocation(Loc loc) const = 0; + virtual typename R::TileBelsRange getBelsByTile(int x, int y) const = 0; virtual bool getBelGlobalBuf(BelId bel) const { return false; } virtual bool checkBelAvail(BelId bel) const = 0; virtual CellInfo *getBoundBelCell(BelId bel) const = 0; virtual CellInfo *getConflictingBelCell(BelId bel) const = 0; virtual IdString getBelType(BelId bel) const = 0; + virtual typename R::BelAttrsRange getBelAttrs(BelId bel) const = 0; virtual WireId getBelPinWire(BelId bel, IdString pin) const = 0; virtual PortType getBelPinType(BelId bel, IdString pin) const = 0; // Wire methods + virtual typename R::AllWiresRange getWires() const = 0; virtual WireId getWireByName(IdStringList name) const = 0; virtual IdStringList getWireName(WireId wire) const = 0; virtual IdString getWireType(WireId wire) const { return IdString(); } + virtual typename R::WireAttrsRange getWireAttrs(WireId) const = 0; virtual uint32_t getWireChecksum(WireId wire) const { return uint32_t(std::hash()(wire)); } + virtual typename R::DownhillPipRange getPipsDownhill(WireId wire) const = 0; + virtual typename R::UphillPipRange getPipsUphill(WireId wire) const = 0; + virtual typename R::WireBelPinRange getWireBelPins(WireId wire) const = 0; virtual void bindWire(WireId wire, NetInfo *net, PlaceStrength strength) = 0; virtual void unbindWire(WireId wire) = 0; virtual bool checkWireAvail(WireId wire) const = 0; @@ -1047,9 +1058,11 @@ struct BaseCtx virtual DelayInfo getWireDelay(WireId wire) const = 0; // Pip methods + virtual typename R::AllPipsRange getPips() const = 0; virtual PipId getPipByName(IdStringList name) const = 0; virtual IdStringList getPipName(PipId pip) const = 0; virtual IdString getPipType(PipId pip) const { return IdString(); } + virtual typename R::PipAttrsRange getPipAttrs(PipId) const = 0; virtual uint32_t getPipChecksum(PipId pip) const { return uint32_t(std::hash()(pip)); } virtual void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) = 0; virtual void unbindPip(PipId pip) = 0; @@ -1067,6 +1080,11 @@ struct BaseCtx virtual IdStringList getGroupName(GroupId group) const = 0; virtual delay_t estimateDelay(WireId src, WireId dst) const = 0; virtual ArcBounds getRouteBoundingBox(WireId src, WireId dst) const = 0; + virtual typename R::AllGroupsRange getGroups() const = 0; + virtual typename R::GroupBelsRange getGroupBels(GroupId group) const = 0; + virtual typename R::GroupWiresRange getGroupWires(GroupId group) const = 0; + virtual typename R::GroupPipsRange getGroupPips(GroupId group) const = 0; + virtual typename R::GroupGroupsRange getGroupGroups(GroupId group) const = 0; // Delay methods virtual delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const = 0; @@ -1108,6 +1126,9 @@ struct BaseCtx virtual BelBucketId getBelBucketForCellType(IdString cell_type) const = 0; virtual bool isValidBelForCell(CellInfo *cell, BelId bel) const { return true; } virtual bool isBelLocationValid(BelId bel) const { return true; } + virtual typename R::CellTypeRange getCellTypes() const = 0; + virtual typename R::BelBucketRange getBelBuckets() const = 0; + virtual typename R::BucketBelRange getBelsInBucket(BelBucketId bucket) const = 0; // Flow methods virtual bool pack() = 0; -- cgit v1.2.3 From ba5568d501decd77352b7afd3897336e99abbdd4 Mon Sep 17 00:00:00 2001 From: "D. Shah" Date: Wed, 3 Feb 2021 17:04:32 +0000 Subject: nextpnr: Example of shared wire/bel/pip binding code Currently not actually being tested Signed-off-by: D. Shah --- common/nextpnr.h | 119 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 106 insertions(+), 13 deletions(-) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index 298fe26b..ad89046c 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -1025,15 +1025,37 @@ template struct ArchBase : BaseCtx virtual BelId getBelByName(IdStringList name) const = 0; virtual IdStringList getBelName(BelId bel) const = 0; virtual uint32_t getBelChecksum(BelId bel) const { return uint32_t(std::hash()(bel)); } - virtual void bindBel(BelId bel, CellInfo *cell, PlaceStrength strength) = 0; - virtual void unbindBel(BelId bel) = 0; + virtual void bindBel(BelId bel, CellInfo *cell, PlaceStrength strength) + { + NPNR_ASSERT(bel != BelId()); + auto &entry = base_bel2cell[bel]; + NPNR_ASSERT(entry == nullptr); + cell->bel = bel; + cell->belStrength = strength; + entry = cell; + refreshUiBel(bel); + } + virtual void unbindBel(BelId bel) + { + NPNR_ASSERT(bel != BelId()); + auto &entry = base_bel2cell[bel]; + NPNR_ASSERT(entry != nullptr); + entry->bel = BelId(); + entry->belStrength = STRENGTH_NONE; + entry = nullptr; + refreshUiBel(bel); + } virtual Loc getBelLocation(BelId bel) const = 0; virtual BelId getBelByLocation(Loc loc) const = 0; virtual typename R::TileBelsRange getBelsByTile(int x, int y) const = 0; virtual bool getBelGlobalBuf(BelId bel) const { return false; } - virtual bool checkBelAvail(BelId bel) const = 0; - virtual CellInfo *getBoundBelCell(BelId bel) const = 0; - virtual CellInfo *getConflictingBelCell(BelId bel) const = 0; + virtual bool checkBelAvail(BelId bel) const { return getBoundBelCell(bel) == nullptr; }; + virtual CellInfo *getBoundBelCell(BelId bel) const + { + auto fnd = base_bel2cell.find(bel); + return fnd == base_bel2cell.end() ? nullptr : fnd->second; + } + virtual CellInfo *getConflictingBelCell(BelId bel) const { return getBoundBelCell(bel); } virtual IdString getBelType(BelId bel) const = 0; virtual typename R::BelAttrsRange getBelAttrs(BelId bel) const = 0; virtual WireId getBelPinWire(BelId bel, IdString pin) const = 0; @@ -1049,10 +1071,43 @@ template struct ArchBase : BaseCtx virtual typename R::DownhillPipRange getPipsDownhill(WireId wire) const = 0; virtual typename R::UphillPipRange getPipsUphill(WireId wire) const = 0; virtual typename R::WireBelPinRange getWireBelPins(WireId wire) const = 0; - virtual void bindWire(WireId wire, NetInfo *net, PlaceStrength strength) = 0; - virtual void unbindWire(WireId wire) = 0; - virtual bool checkWireAvail(WireId wire) const = 0; - virtual NetInfo *getBoundWireNet(WireId wire) const = 0; + virtual void bindWire(WireId wire, NetInfo *net, PlaceStrength strength) + { + NPNR_ASSERT(wire != WireId()); + auto &w2n_entry = base_wire2net[wire]; + NPNR_ASSERT(w2n_entry == nullptr); + net->wires[wire].pip = PipId(); + net->wires[wire].strength = strength; + w2n_entry = net; + refreshUiWire(wire); + } + virtual void unbindWire(WireId wire) + { + NPNR_ASSERT(wire != WireId()); + auto &w2n_entry = base_wire2net[wire]; + NPNR_ASSERT(w2n_entry != nullptr); + + auto &net_wires = w2n_entry->wires; + auto it = net_wires.find(wire); + NPNR_ASSERT(it != net_wires.end()); + + auto pip = it->second.pip; + if (pip != PipId()) { + base_pip2net[pip] = nullptr; + } + + net_wires.erase(it); + base_wire2net[wire] = nullptr; + + w2n_entry = nullptr; + refreshUiWire(wire); + } + virtual bool checkWireAvail(WireId wire) const { return getBoundWireNet(wire) == nullptr; } + virtual NetInfo *getBoundWireNet(WireId wire) const + { + auto fnd = base_wire2net.find(wire); + return fnd == base_wire2net.end() ? nullptr : fnd->second; + } virtual WireId getConflictingWireWire(WireId wire) const { return wire; }; virtual NetInfo *getConflictingWireNet(WireId wire) const { return getBoundWireNet(wire); } virtual DelayInfo getWireDelay(WireId wire) const = 0; @@ -1064,10 +1119,40 @@ template struct ArchBase : BaseCtx virtual IdString getPipType(PipId pip) const { return IdString(); } virtual typename R::PipAttrsRange getPipAttrs(PipId) const = 0; virtual uint32_t getPipChecksum(PipId pip) const { return uint32_t(std::hash()(pip)); } - virtual void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) = 0; - virtual void unbindPip(PipId pip) = 0; - virtual bool checkPipAvail(PipId pip) const = 0; - virtual NetInfo *getBoundPipNet(PipId pip) const = 0; + virtual void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) + { + NPNR_ASSERT(pip != PipId()); + auto &p2n_entry = base_pip2net[pip]; + NPNR_ASSERT(p2n_entry == nullptr); + p2n_entry = net; + + WireId dst = getPipDstWire(pip); + auto &w2n_entry = base_wire2net[dst]; + NPNR_ASSERT(w2n_entry == nullptr); + w2n_entry = net; + net->wires[dst].pip = pip; + net->wires[dst].strength = strength; + } + virtual void unbindPip(PipId pip) + { + NPNR_ASSERT(pip != PipId()); + auto &p2n_entry = base_pip2net[pip]; + NPNR_ASSERT(p2n_entry != nullptr); + WireId dst = getPipDstWire(pip); + + auto &w2n_entry = base_wire2net[dst]; + NPNR_ASSERT(w2n_entry != nullptr); + w2n_entry = nullptr; + + p2n_entry->wires.erase(dst); + p2n_entry = nullptr; + } + virtual bool checkPipAvail(PipId pip) const { return getBoundPipNet(pip) == nullptr; } + virtual NetInfo *getBoundPipNet(PipId pip) const + { + auto fnd = base_pip2net.find(pip); + return fnd == base_pip2net.end() ? nullptr : fnd->second; + } virtual WireId getConflictingPipWire(PipId pip) const { return WireId(); } virtual NetInfo *getConflictingPipNet(PipId pip) const { return nullptr; } virtual WireId getPipSrcWire(PipId pip) const = 0; @@ -1135,6 +1220,14 @@ template struct ArchBase : BaseCtx virtual bool place() = 0; virtual bool route() = 0; virtual void assignArchInfo(){}; + + // -------------------------------------------------------------- + // These structures are used to provide default implementations of bel/wire/pip binding. Arches might want to + // replace them with their own, for example to use faster access structures than unordered_map. Arches might also + // want to add extra checks around these functions + std::unordered_map base_bel2cell; + std::unordered_map base_wire2net; + std::unordered_map base_pip2net; }; NEXTPNR_NAMESPACE_END -- cgit v1.2.3 From b866601b6398f90967c8ab120f9b9806869f94c4 Mon Sep 17 00:00:00 2001 From: "D. Shah" Date: Wed, 3 Feb 2021 19:43:33 +0000 Subject: Fix now-illegal use of reinterpret_cast Signed-off-by: D. Shah --- common/nextpnr.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index ad89046c..263c8e13 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -841,6 +841,8 @@ struct BaseCtx // Context meta data std::unordered_map attrs; + Context *as_ctx = nullptr; + BaseCtx() { idstring_str_to_idx = new std::unordered_map; @@ -914,9 +916,9 @@ struct BaseCtx IdString id(const char *s) const { return IdString(this, s); } - Context *getCtx() { return reinterpret_cast(this); } + Context *getCtx() { return as_ctx; } - const Context *getCtx() const { return reinterpret_cast(this); } + const Context *getCtx() const { return as_ctx; } const char *nameOf(IdString name) const { return name.c_str(this); } @@ -1245,7 +1247,7 @@ struct Context : Arch, DeterministicRNG // Should we disable printing of the location of nets in the critical path? bool disable_critical_path_source_print = false; - Context(ArchArgs args) : Arch(args) {} + Context(ArchArgs args) : Arch(args) { BaseCtx::as_ctx = this; } // -------------------------------------------------------------- -- cgit v1.2.3 From d4363b7ee593ee84957dbe60969cf694903d70ad Mon Sep 17 00:00:00 2001 From: "D. Shah" Date: Wed, 3 Feb 2021 19:51:39 +0000 Subject: ecp5: Use common wire/pip binding Signed-off-by: D. Shah --- common/nextpnr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index 263c8e13..4063999d 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -1156,7 +1156,7 @@ template struct ArchBase : BaseCtx return fnd == base_pip2net.end() ? nullptr : fnd->second; } virtual WireId getConflictingPipWire(PipId pip) const { return WireId(); } - virtual NetInfo *getConflictingPipNet(PipId pip) const { return nullptr; } + virtual NetInfo *getConflictingPipNet(PipId pip) const { return getBoundPipNet(pip); } virtual WireId getPipSrcWire(PipId pip) const = 0; virtual WireId getPipDstWire(PipId pip) const = 0; virtual DelayInfo getPipDelay(PipId pip) const = 0; -- cgit v1.2.3 From 6d794abf495be78c6d1a2a69af432021c1eabfad Mon Sep 17 00:00:00 2001 From: "D. Shah" Date: Thu, 4 Feb 2021 10:56:19 +0000 Subject: Add a few more functions to ArchBase Signed-off-by: D. Shah --- common/nextpnr.h | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index 4063999d..e2e87cbc 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -99,6 +99,8 @@ inline void assert_fail_impl_str(std::string message, const char *expr_str, cons #define NPNR_ASSERT_FALSE(msg) (assert_fail_impl(msg, "false", __FILE__, __LINE__)) #define NPNR_ASSERT_FALSE_STR(msg) (assert_fail_impl_str(msg, "false", __FILE__, __LINE__)) +#define STRINGIFY(x) #x + struct BaseCtx; struct Context; @@ -1016,6 +1018,8 @@ template struct ArchBase : BaseCtx // Arch API base // Basic config + virtual std::string getChipName() const = 0; + virtual IdString archId() const { id(STRINGIFY(ARCHNAME)); } virtual int getGridDimX() const = 0; virtual int getGridDimY() const = 0; virtual int getTileBelDimZ(int x, int y) const = 0; @@ -1163,15 +1167,16 @@ template struct ArchBase : BaseCtx virtual Loc getPipLocation(PipId pip) const = 0; // Group methods - virtual GroupId getGroupByName(IdStringList name) const = 0; - virtual IdStringList getGroupName(GroupId group) const = 0; + virtual GroupId getGroupByName(IdStringList name) const { return GroupId(); }; + virtual IdStringList getGroupName(GroupId group) const { return IdStringList(); }; virtual delay_t estimateDelay(WireId src, WireId dst) const = 0; virtual ArcBounds getRouteBoundingBox(WireId src, WireId dst) const = 0; virtual typename R::AllGroupsRange getGroups() const = 0; - virtual typename R::GroupBelsRange getGroupBels(GroupId group) const = 0; - virtual typename R::GroupWiresRange getGroupWires(GroupId group) const = 0; - virtual typename R::GroupPipsRange getGroupPips(GroupId group) const = 0; - virtual typename R::GroupGroupsRange getGroupGroups(GroupId group) const = 0; + // Default implementation of these assumes no groups so never called + virtual typename R::GroupBelsRange getGroupBels(GroupId group) const { NPNR_ASSERT_FALSE("unreachable"); }; + virtual typename R::GroupWiresRange getGroupWires(GroupId group) const { NPNR_ASSERT_FALSE("unreachable"); }; + virtual typename R::GroupPipsRange getGroupPips(GroupId group) const { NPNR_ASSERT_FALSE("unreachable"); }; + virtual typename R::GroupGroupsRange getGroupGroups(GroupId group) const { NPNR_ASSERT_FALSE("unreachable"); }; // Delay methods virtual delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const = 0; @@ -1186,6 +1191,7 @@ template struct ArchBase : BaseCtx } // Decal methods + virtual typename R::DecalGfxRange getDecalGraphics(DecalId decal) const { NPNR_ASSERT_FALSE("unreachable"); }; virtual DecalXY getBelDecal(BelId bel) const { return DecalXY(); } virtual DecalXY getWireDecal(WireId wire) const { return DecalXY(); } virtual DecalXY getPipDecal(PipId pip) const { return DecalXY(); } @@ -1209,8 +1215,8 @@ template struct ArchBase : BaseCtx virtual bool isValidBelForCellType(IdString cell_type, BelId bel) const { return cell_type == getBelType(bel); } virtual IdString getBelBucketName(BelBucketId bucket) const = 0; virtual BelBucketId getBelBucketByName(IdString name) const = 0; - virtual BelBucketId getBelBucketForBel(BelId bel) const = 0; - virtual BelBucketId getBelBucketForCellType(IdString cell_type) const = 0; + virtual BelBucketId getBelBucketForBel(BelId bel) const { return getBelBucketForCellType(getBelType(bel)); }; + virtual BelBucketId getBelBucketForCellType(IdString cell_type) const { return getBelBucketByName(cell_type); }; virtual bool isValidBelForCell(CellInfo *cell, BelId bel) const { return true; } virtual bool isBelLocationValid(BelId bel) const { return true; } virtual typename R::CellTypeRange getCellTypes() const = 0; -- cgit v1.2.3 From ed8e3c83d97d775f912266c701ebf17e416cc50b Mon Sep 17 00:00:00 2001 From: "D. Shah" Date: Thu, 4 Feb 2021 11:21:16 +0000 Subject: Add default implementation of some range-returning functions Signed-off-by: D. Shah --- common/nextpnr.h | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index e2e87cbc..a97deaa3 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -1012,6 +1012,19 @@ struct BaseCtx void attributesToArchInfo(); }; +// For several functions; such as bel/wire/pip attributes; the trivial implementation is to return an empty vector +// But an arch might want to do something fancy with a custom range type that doesn't provide a constructor +// So some cursed C++ is needed to return an empty object if possible; or error out if not; is needed +template typename std::enable_if::value, Tc>::type empty_if_possible() +{ + return Tc(); +} +template typename std::enable_if::value, Tc>::type empty_if_possible() +{ + NPNR_ASSERT_FALSE("attempting to use default implementation of range-returning function with range type lacking " + "default constructor!"); +} + template struct ArchBase : BaseCtx { // -------------------------------------------------------------- @@ -1019,7 +1032,7 @@ template struct ArchBase : BaseCtx // Basic config virtual std::string getChipName() const = 0; - virtual IdString archId() const { id(STRINGIFY(ARCHNAME)); } + virtual IdString archId() const { return id(STRINGIFY(ARCHNAME)); } virtual int getGridDimX() const = 0; virtual int getGridDimY() const = 0; virtual int getTileBelDimZ(int x, int y) const = 0; @@ -1063,7 +1076,10 @@ template struct ArchBase : BaseCtx } virtual CellInfo *getConflictingBelCell(BelId bel) const { return getBoundBelCell(bel); } virtual IdString getBelType(BelId bel) const = 0; - virtual typename R::BelAttrsRange getBelAttrs(BelId bel) const = 0; + virtual typename R::BelAttrsRange getBelAttrs(BelId bel) const + { + return empty_if_possible(); + } virtual WireId getBelPinWire(BelId bel, IdString pin) const = 0; virtual PortType getBelPinType(BelId bel, IdString pin) const = 0; @@ -1072,7 +1088,10 @@ template struct ArchBase : BaseCtx virtual WireId getWireByName(IdStringList name) const = 0; virtual IdStringList getWireName(WireId wire) const = 0; virtual IdString getWireType(WireId wire) const { return IdString(); } - virtual typename R::WireAttrsRange getWireAttrs(WireId) const = 0; + virtual typename R::WireAttrsRange getWireAttrs(WireId) const + { + return empty_if_possible(); + } virtual uint32_t getWireChecksum(WireId wire) const { return uint32_t(std::hash()(wire)); } virtual typename R::DownhillPipRange getPipsDownhill(WireId wire) const = 0; virtual typename R::UphillPipRange getPipsUphill(WireId wire) const = 0; @@ -1123,7 +1142,10 @@ template struct ArchBase : BaseCtx virtual PipId getPipByName(IdStringList name) const = 0; virtual IdStringList getPipName(PipId pip) const = 0; virtual IdString getPipType(PipId pip) const { return IdString(); } - virtual typename R::PipAttrsRange getPipAttrs(PipId) const = 0; + virtual typename R::PipAttrsRange getPipAttrs(PipId) const + { + return empty_if_possible(); + } virtual uint32_t getPipChecksum(PipId pip) const { return uint32_t(std::hash()(pip)); } virtual void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) { @@ -1171,7 +1193,7 @@ template struct ArchBase : BaseCtx virtual IdStringList getGroupName(GroupId group) const { return IdStringList(); }; virtual delay_t estimateDelay(WireId src, WireId dst) const = 0; virtual ArcBounds getRouteBoundingBox(WireId src, WireId dst) const = 0; - virtual typename R::AllGroupsRange getGroups() const = 0; + virtual typename R::AllGroupsRange getGroups() const { return empty_if_possible(); } // Default implementation of these assumes no groups so never called virtual typename R::GroupBelsRange getGroupBels(GroupId group) const { NPNR_ASSERT_FALSE("unreachable"); }; virtual typename R::GroupWiresRange getGroupWires(GroupId group) const { NPNR_ASSERT_FALSE("unreachable"); }; -- cgit v1.2.3 From 297cd026b9e87ce40ebf781cb86608b43cfbdd55 Mon Sep 17 00:00:00 2001 From: "D. Shah" Date: Thu, 4 Feb 2021 11:57:08 +0000 Subject: Add default implementation of bel bucket functions Signed-off-by: D. Shah --- common/nextpnr.h | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 89 insertions(+), 5 deletions(-) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index a97deaa3..e950ad69 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -1012,6 +1012,7 @@ struct BaseCtx void attributesToArchInfo(); }; +namespace { // For several functions; such as bel/wire/pip attributes; the trivial implementation is to return an empty vector // But an arch might want to do something fancy with a custom range type that doesn't provide a constructor // So some cursed C++ is needed to return an empty object if possible; or error out if not; is needed @@ -1025,6 +1026,44 @@ template typename std::enable_if::value "default constructor!"); } +// Provide a default implementation of bel bucket name if typedef'd to IdString +template +typename std::enable_if::value, IdString>::type bbid_to_name(Tbbid id) +{ + return id; +} +template +typename std::enable_if::value, IdString>::type bbid_to_name(Tbbid id) +{ + NPNR_ASSERT_FALSE("getBelBucketName must be implemented when BelBucketId is a type other than IdString!"); +} +template +typename std::enable_if::value, BelBucketId>::type bbid_from_name(IdString name) +{ + return name; +} +template +typename std::enable_if::value, BelBucketId>::type bbid_from_name(IdString name) +{ + NPNR_ASSERT_FALSE("getBelBucketByName must be implemented when BelBucketId is a type other than IdString!"); +} + +// For the cell type and bel type ranges; we want to return our stored vectors only if the type matches +template +typename std::enable_if::value, Tret>::type return_if_match(Tret r) +{ + return r; +} + +template +typename std::enable_if::value, Tret>::type return_if_match(Tret r) +{ + NPNR_ASSERT_FALSE("default implementations of cell type and bel bucket range functions only available when the " + "respective range types are 'const std::vector&'"); +} + +} // namespace + template struct ArchBase : BaseCtx { // -------------------------------------------------------------- @@ -1235,15 +1274,27 @@ template struct ArchBase : BaseCtx // Placement validity checks virtual bool isValidBelForCellType(IdString cell_type, BelId bel) const { return cell_type == getBelType(bel); } - virtual IdString getBelBucketName(BelBucketId bucket) const = 0; - virtual BelBucketId getBelBucketByName(IdString name) const = 0; + virtual IdString getBelBucketName(BelBucketId bucket) const { return bbid_to_name(bucket); } + virtual BelBucketId getBelBucketByName(IdString name) const { return bbid_from_name(name); } virtual BelBucketId getBelBucketForBel(BelId bel) const { return getBelBucketForCellType(getBelType(bel)); }; virtual BelBucketId getBelBucketForCellType(IdString cell_type) const { return getBelBucketByName(cell_type); }; virtual bool isValidBelForCell(CellInfo *cell, BelId bel) const { return true; } virtual bool isBelLocationValid(BelId bel) const { return true; } - virtual typename R::CellTypeRange getCellTypes() const = 0; - virtual typename R::BelBucketRange getBelBuckets() const = 0; - virtual typename R::BucketBelRange getBelsInBucket(BelBucketId bucket) const = 0; + virtual typename R::CellTypeRange getCellTypes() const + { + NPNR_ASSERT(cell_types_initialised); + return return_if_match &, typename R::CellTypeRange>(cell_types); + } + virtual typename R::BelBucketRange getBelBuckets() const + { + NPNR_ASSERT(bel_buckets_initialised); + return return_if_match &, typename R::BelBucketRange>(bel_buckets); + } + virtual typename R::BucketBelRange getBelsInBucket(BelBucketId bucket) const + { + NPNR_ASSERT(bel_buckets_initialised); + return return_if_match &, typename R::BucketBelRange>(bucket_bels.at(bucket)); + } // Flow methods virtual bool pack() = 0; @@ -1258,6 +1309,39 @@ template struct ArchBase : BaseCtx std::unordered_map base_bel2cell; std::unordered_map base_wire2net; std::unordered_map base_pip2net; + + // For the default cell/bel bucket implementations + std::vector cell_types; + std::vector bel_buckets; + std::unordered_map> bucket_bels; + + // Arches that want to use the default cell types and bel buckets *must* call these functions in their constructor + bool cell_types_initialised = false; + bool bel_buckets_initialised = false; + void init_cell_types() + { + std::unordered_set bel_types; + for (auto bel : getBels()) + bel_types.insert(getBelType(bel)); + std::copy(bel_types.begin(), bel_types.end(), std::back_inserter(cell_types)); + std::sort(cell_types.begin(), cell_types.end()); + cell_types_initialised = true; + } + void init_bel_buckets() + { + for (auto cell_type : getCellTypes()) { + auto bucket = getBelBucketForCellType(cell_type); + bucket_bels[bucket]; // create empty bucket + } + for (auto bel : getBels()) { + auto bucket = getBelBucketForBel(bel); + bucket_bels[bucket].push_back(bel); + } + for (auto &b : bucket_bels) + bel_buckets.push_back(b.first); + std::sort(bel_buckets.begin(), bel_buckets.end()); + bel_buckets_initialised = true; + } }; NEXTPNR_NAMESPACE_END -- cgit v1.2.3 From b4227f586c59ca959d1bfe0d01c4c04b601fa30f Mon Sep 17 00:00:00 2001 From: "D. Shah" Date: Thu, 4 Feb 2021 12:07:11 +0000 Subject: Rename ArchBase to BaseArch for consistency with BaseCtx Signed-off-by: D. Shah --- common/nextpnr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index e950ad69..cb3f6e9f 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -1064,7 +1064,7 @@ typename std::enable_if::value, Tret>::type return_if_ma } // namespace -template struct ArchBase : BaseCtx +template struct BaseArch : BaseCtx { // -------------------------------------------------------------- // Arch API base -- cgit v1.2.3 From a8a27299ae46143c9fadb1d9153a964492525f4a Mon Sep 17 00:00:00 2001 From: "D. Shah" Date: Fri, 5 Feb 2021 11:23:07 +0000 Subject: Add pure-virtual ArchAPI interface This splits out the pure-virtual definition of the architecture API into ArchAPI; leaving BaseArch to only provide default implementations (which can now be completely opted out of by deriving from ArchAPI instead of BaseArch). Signed-off-by: D. Shah --- common/nextpnr.h | 302 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 198 insertions(+), 104 deletions(-) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index cb3f6e9f..7de5233b 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -1064,26 +1064,128 @@ typename std::enable_if::value, Tret>::type return_if_ma } // namespace -template struct BaseArch : BaseCtx +// The specification of the Arch API (pure virtual) +template struct ArchAPI : BaseCtx { - // -------------------------------------------------------------- - // Arch API base - // Basic config + virtual IdString archId() const = 0; virtual std::string getChipName() const = 0; - virtual IdString archId() const { return id(STRINGIFY(ARCHNAME)); } virtual int getGridDimX() const = 0; virtual int getGridDimY() const = 0; virtual int getTileBelDimZ(int x, int y) const = 0; - virtual int getTilePipDimZ(int x, int y) const { return 1; } - virtual char getNameDelimiter() const { return ' '; } - + virtual int getTilePipDimZ(int x, int y) const = 0; + virtual char getNameDelimiter() const = 0; // Bel methods virtual typename R::AllBelsRange getBels() const = 0; - virtual BelId getBelByName(IdStringList name) const = 0; virtual IdStringList getBelName(BelId bel) const = 0; - virtual uint32_t getBelChecksum(BelId bel) const { return uint32_t(std::hash()(bel)); } - virtual void bindBel(BelId bel, CellInfo *cell, PlaceStrength strength) + virtual BelId getBelByName(IdStringList name) const = 0; + virtual uint32_t getBelChecksum(BelId bel) const = 0; + virtual void bindBel(BelId bel, CellInfo *cell, PlaceStrength strength) = 0; + virtual void unbindBel(BelId bel) = 0; + virtual Loc getBelLocation(BelId bel) const = 0; + virtual BelId getBelByLocation(Loc loc) const = 0; + virtual typename R::TileBelsRange getBelsByTile(int x, int y) const = 0; + virtual bool getBelGlobalBuf(BelId bel) const = 0; + virtual bool checkBelAvail(BelId bel) const = 0; + virtual CellInfo *getBoundBelCell(BelId bel) const = 0; + virtual CellInfo *getConflictingBelCell(BelId bel) const = 0; + virtual IdString getBelType(BelId bel) const = 0; + virtual typename R::BelAttrsRange getBelAttrs(BelId bel) const = 0; + virtual WireId getBelPinWire(BelId bel, IdString pin) const = 0; + virtual PortType getBelPinType(BelId bel, IdString pin) const = 0; + // Wire methods + virtual typename R::AllWiresRange getWires() const = 0; + virtual WireId getWireByName(IdStringList name) const = 0; + virtual IdStringList getWireName(WireId wire) const = 0; + virtual IdString getWireType(WireId wire) const = 0; + virtual typename R::WireAttrsRange getWireAttrs(WireId) const = 0; + virtual typename R::DownhillPipRange getPipsDownhill(WireId wire) const = 0; + virtual typename R::UphillPipRange getPipsUphill(WireId wire) const = 0; + virtual typename R::WireBelPinRange getWireBelPins(WireId wire) const = 0; + virtual uint32_t getWireChecksum(WireId wire) const = 0; + virtual void bindWire(WireId wire, NetInfo *net, PlaceStrength strength) = 0; + virtual void unbindWire(WireId wire) = 0; + virtual bool checkWireAvail(WireId wire) const = 0; + virtual NetInfo *getBoundWireNet(WireId wire) const = 0; + virtual WireId getConflictingWireWire(WireId wire) const = 0; + virtual NetInfo *getConflictingWireNet(WireId wire) const = 0; + virtual DelayInfo getWireDelay(WireId wire) const = 0; + // Pip methods + virtual typename R::AllPipsRange getPips() const = 0; + virtual PipId getPipByName(IdStringList name) const = 0; + virtual IdStringList getPipName(PipId pip) const = 0; + virtual IdString getPipType(PipId pip) const = 0; + virtual typename R::PipAttrsRange getPipAttrs(PipId) const = 0; + virtual uint32_t getPipChecksum(PipId pip) const = 0; + virtual void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) = 0; + virtual void unbindPip(PipId pip) = 0; + virtual bool checkPipAvail(PipId pip) const = 0; + virtual NetInfo *getBoundPipNet(PipId pip) const = 0; + virtual WireId getConflictingPipWire(PipId pip) const = 0; + virtual NetInfo *getConflictingPipNet(PipId pip) const = 0; + virtual WireId getPipSrcWire(PipId pip) const = 0; + virtual WireId getPipDstWire(PipId pip) const = 0; + virtual DelayInfo getPipDelay(PipId pip) const = 0; + virtual Loc getPipLocation(PipId pip) const = 0; + // Group methods + virtual GroupId getGroupByName(IdStringList name) const = 0; + virtual IdStringList getGroupName(GroupId group) const = 0; + virtual typename R::AllGroupsRange getGroups() const = 0; + virtual typename R::GroupBelsRange getGroupBels(GroupId group) const = 0; + virtual typename R::GroupWiresRange getGroupWires(GroupId group) const = 0; + virtual typename R::GroupPipsRange getGroupPips(GroupId group) const = 0; + virtual typename R::GroupGroupsRange getGroupGroups(GroupId group) const = 0; + // Delay Methods + virtual delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const = 0; + virtual delay_t getDelayEpsilon() const = 0; + virtual delay_t getRipupDelayPenalty() const = 0; + virtual float getDelayNS(delay_t v) const = 0; + virtual DelayInfo getDelayFromNS(float ns) const = 0; + virtual uint32_t getDelayChecksum(delay_t v) const = 0; + virtual bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const = 0; + virtual delay_t estimateDelay(WireId src, WireId dst) const = 0; + virtual ArcBounds getRouteBoundingBox(WireId src, WireId dst) const = 0; + // Decal methods + virtual typename R::DecalGfxRange getDecalGraphics(DecalId decal) const = 0; + virtual DecalXY getBelDecal(BelId bel) const = 0; + virtual DecalXY getWireDecal(WireId wire) const = 0; + virtual DecalXY getPipDecal(PipId pip) const = 0; + virtual DecalXY getGroupDecal(GroupId group) const = 0; + // Cell timing methods + virtual bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const = 0; + virtual TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const = 0; + virtual TimingClockingInfo getPortClockingInfo(const CellInfo *cell, IdString port, int index) const = 0; + // Placement validity checks + virtual bool isValidBelForCellType(IdString cell_type, BelId bel) const = 0; + virtual IdString getBelBucketName(BelBucketId bucket) const = 0; + virtual BelBucketId getBelBucketByName(IdString name) const = 0; + virtual BelBucketId getBelBucketForBel(BelId bel) const = 0; + virtual BelBucketId getBelBucketForCellType(IdString cell_type) const = 0; + virtual bool isValidBelForCell(CellInfo *cell, BelId bel) const = 0; + virtual bool isBelLocationValid(BelId bel) const = 0; + virtual typename R::CellTypeRange getCellTypes() const = 0; + virtual typename R::BelBucketRange getBelBuckets() const = 0; + virtual typename R::BucketBelRange getBelsInBucket(BelBucketId bucket) const = 0; + // Flow methods + virtual bool pack() = 0; + virtual bool place() = 0; + virtual bool route() = 0; + virtual void assignArchInfo() = 0; +}; + +template struct BaseArch : ArchAPI +{ + // -------------------------------------------------------------- + // Default, trivial, implementations of Arch API functions for arches that don't need complex behaviours + + // Basic config + virtual IdString archId() const override { return this->id(STRINGIFY(ARCHNAME)); } + virtual int getTilePipDimZ(int x, int y) const override { return 1; } + virtual char getNameDelimiter() const override { return ' '; } + + // Bel methods + virtual uint32_t getBelChecksum(BelId bel) const override { return uint32_t(std::hash()(bel)); } + virtual void bindBel(BelId bel, CellInfo *cell, PlaceStrength strength) override { NPNR_ASSERT(bel != BelId()); auto &entry = base_bel2cell[bel]; @@ -1091,9 +1193,9 @@ template struct BaseArch : BaseCtx cell->bel = bel; cell->belStrength = strength; entry = cell; - refreshUiBel(bel); + this->refreshUiBel(bel); } - virtual void unbindBel(BelId bel) + virtual void unbindBel(BelId bel) override { NPNR_ASSERT(bel != BelId()); auto &entry = base_bel2cell[bel]; @@ -1101,41 +1203,31 @@ template struct BaseArch : BaseCtx entry->bel = BelId(); entry->belStrength = STRENGTH_NONE; entry = nullptr; - refreshUiBel(bel); + this->refreshUiBel(bel); } - virtual Loc getBelLocation(BelId bel) const = 0; - virtual BelId getBelByLocation(Loc loc) const = 0; - virtual typename R::TileBelsRange getBelsByTile(int x, int y) const = 0; - virtual bool getBelGlobalBuf(BelId bel) const { return false; } - virtual bool checkBelAvail(BelId bel) const { return getBoundBelCell(bel) == nullptr; }; - virtual CellInfo *getBoundBelCell(BelId bel) const + + virtual bool getBelGlobalBuf(BelId bel) const override { return false; } + virtual bool checkBelAvail(BelId bel) const override { return getBoundBelCell(bel) == nullptr; }; + virtual CellInfo *getBoundBelCell(BelId bel) const override { auto fnd = base_bel2cell.find(bel); return fnd == base_bel2cell.end() ? nullptr : fnd->second; } - virtual CellInfo *getConflictingBelCell(BelId bel) const { return getBoundBelCell(bel); } - virtual IdString getBelType(BelId bel) const = 0; - virtual typename R::BelAttrsRange getBelAttrs(BelId bel) const + virtual CellInfo *getConflictingBelCell(BelId bel) const override { return getBoundBelCell(bel); } + virtual typename R::BelAttrsRange getBelAttrs(BelId bel) const override { return empty_if_possible(); } - virtual WireId getBelPinWire(BelId bel, IdString pin) const = 0; - virtual PortType getBelPinType(BelId bel, IdString pin) const = 0; // Wire methods - virtual typename R::AllWiresRange getWires() const = 0; - virtual WireId getWireByName(IdStringList name) const = 0; - virtual IdStringList getWireName(WireId wire) const = 0; - virtual IdString getWireType(WireId wire) const { return IdString(); } - virtual typename R::WireAttrsRange getWireAttrs(WireId) const + virtual IdString getWireType(WireId wire) const override { return IdString(); } + virtual typename R::WireAttrsRange getWireAttrs(WireId) const override { return empty_if_possible(); } - virtual uint32_t getWireChecksum(WireId wire) const { return uint32_t(std::hash()(wire)); } - virtual typename R::DownhillPipRange getPipsDownhill(WireId wire) const = 0; - virtual typename R::UphillPipRange getPipsUphill(WireId wire) const = 0; - virtual typename R::WireBelPinRange getWireBelPins(WireId wire) const = 0; - virtual void bindWire(WireId wire, NetInfo *net, PlaceStrength strength) + virtual uint32_t getWireChecksum(WireId wire) const override { return uint32_t(std::hash()(wire)); } + + virtual void bindWire(WireId wire, NetInfo *net, PlaceStrength strength) override { NPNR_ASSERT(wire != WireId()); auto &w2n_entry = base_wire2net[wire]; @@ -1143,9 +1235,9 @@ template struct BaseArch : BaseCtx net->wires[wire].pip = PipId(); net->wires[wire].strength = strength; w2n_entry = net; - refreshUiWire(wire); + this->refreshUiWire(wire); } - virtual void unbindWire(WireId wire) + virtual void unbindWire(WireId wire) override { NPNR_ASSERT(wire != WireId()); auto &w2n_entry = base_wire2net[wire]; @@ -1164,48 +1256,44 @@ template struct BaseArch : BaseCtx base_wire2net[wire] = nullptr; w2n_entry = nullptr; - refreshUiWire(wire); + this->refreshUiWire(wire); } - virtual bool checkWireAvail(WireId wire) const { return getBoundWireNet(wire) == nullptr; } - virtual NetInfo *getBoundWireNet(WireId wire) const + virtual bool checkWireAvail(WireId wire) const override { return getBoundWireNet(wire) == nullptr; } + virtual NetInfo *getBoundWireNet(WireId wire) const override { auto fnd = base_wire2net.find(wire); return fnd == base_wire2net.end() ? nullptr : fnd->second; } - virtual WireId getConflictingWireWire(WireId wire) const { return wire; }; - virtual NetInfo *getConflictingWireNet(WireId wire) const { return getBoundWireNet(wire); } - virtual DelayInfo getWireDelay(WireId wire) const = 0; + virtual WireId getConflictingWireWire(WireId wire) const override { return wire; }; + virtual NetInfo *getConflictingWireNet(WireId wire) const override { return getBoundWireNet(wire); } // Pip methods - virtual typename R::AllPipsRange getPips() const = 0; - virtual PipId getPipByName(IdStringList name) const = 0; - virtual IdStringList getPipName(PipId pip) const = 0; virtual IdString getPipType(PipId pip) const { return IdString(); } - virtual typename R::PipAttrsRange getPipAttrs(PipId) const + virtual typename R::PipAttrsRange getPipAttrs(PipId) const override { return empty_if_possible(); } - virtual uint32_t getPipChecksum(PipId pip) const { return uint32_t(std::hash()(pip)); } - virtual void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) + virtual uint32_t getPipChecksum(PipId pip) const override { return uint32_t(std::hash()(pip)); } + virtual void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) override { NPNR_ASSERT(pip != PipId()); auto &p2n_entry = base_pip2net[pip]; NPNR_ASSERT(p2n_entry == nullptr); p2n_entry = net; - WireId dst = getPipDstWire(pip); + WireId dst = this->getPipDstWire(pip); auto &w2n_entry = base_wire2net[dst]; NPNR_ASSERT(w2n_entry == nullptr); w2n_entry = net; net->wires[dst].pip = pip; net->wires[dst].strength = strength; } - virtual void unbindPip(PipId pip) + virtual void unbindPip(PipId pip) override { NPNR_ASSERT(pip != PipId()); auto &p2n_entry = base_pip2net[pip]; NPNR_ASSERT(p2n_entry != nullptr); - WireId dst = getPipDstWire(pip); + WireId dst = this->getPipDstWire(pip); auto &w2n_entry = base_wire2net[dst]; NPNR_ASSERT(w2n_entry != nullptr); @@ -1214,93 +1302,99 @@ template struct BaseArch : BaseCtx p2n_entry->wires.erase(dst); p2n_entry = nullptr; } - virtual bool checkPipAvail(PipId pip) const { return getBoundPipNet(pip) == nullptr; } - virtual NetInfo *getBoundPipNet(PipId pip) const + virtual bool checkPipAvail(PipId pip) const override { return getBoundPipNet(pip) == nullptr; } + virtual NetInfo *getBoundPipNet(PipId pip) const override { auto fnd = base_pip2net.find(pip); return fnd == base_pip2net.end() ? nullptr : fnd->second; } - virtual WireId getConflictingPipWire(PipId pip) const { return WireId(); } - virtual NetInfo *getConflictingPipNet(PipId pip) const { return getBoundPipNet(pip); } - virtual WireId getPipSrcWire(PipId pip) const = 0; - virtual WireId getPipDstWire(PipId pip) const = 0; - virtual DelayInfo getPipDelay(PipId pip) const = 0; - virtual Loc getPipLocation(PipId pip) const = 0; + virtual WireId getConflictingPipWire(PipId pip) const override { return WireId(); } + virtual NetInfo *getConflictingPipNet(PipId pip) const override { return getBoundPipNet(pip); } // Group methods - virtual GroupId getGroupByName(IdStringList name) const { return GroupId(); }; - virtual IdStringList getGroupName(GroupId group) const { return IdStringList(); }; - virtual delay_t estimateDelay(WireId src, WireId dst) const = 0; - virtual ArcBounds getRouteBoundingBox(WireId src, WireId dst) const = 0; - virtual typename R::AllGroupsRange getGroups() const { return empty_if_possible(); } + virtual GroupId getGroupByName(IdStringList name) const override { return GroupId(); }; + virtual IdStringList getGroupName(GroupId group) const override { return IdStringList(); }; + virtual typename R::AllGroupsRange getGroups() const override + { + return empty_if_possible(); + } // Default implementation of these assumes no groups so never called - virtual typename R::GroupBelsRange getGroupBels(GroupId group) const { NPNR_ASSERT_FALSE("unreachable"); }; - virtual typename R::GroupWiresRange getGroupWires(GroupId group) const { NPNR_ASSERT_FALSE("unreachable"); }; - virtual typename R::GroupPipsRange getGroupPips(GroupId group) const { NPNR_ASSERT_FALSE("unreachable"); }; - virtual typename R::GroupGroupsRange getGroupGroups(GroupId group) const { NPNR_ASSERT_FALSE("unreachable"); }; + virtual typename R::GroupBelsRange getGroupBels(GroupId group) const override { NPNR_ASSERT_FALSE("unreachable"); }; + virtual typename R::GroupWiresRange getGroupWires(GroupId group) const override + { + NPNR_ASSERT_FALSE("unreachable"); + }; + virtual typename R::GroupPipsRange getGroupPips(GroupId group) const override { NPNR_ASSERT_FALSE("unreachable"); }; + virtual typename R::GroupGroupsRange getGroupGroups(GroupId group) const override + { + NPNR_ASSERT_FALSE("unreachable"); + }; // Delay methods - virtual delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const = 0; - virtual delay_t getDelayEpsilon() const = 0; - virtual delay_t getRipupDelayPenalty() const = 0; - virtual float getDelayNS(delay_t v) const = 0; - virtual DelayInfo getDelayFromNS(float ns) const = 0; - virtual uint32_t getDelayChecksum(delay_t v) const = 0; - virtual bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const + virtual bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const override { return false; } // Decal methods - virtual typename R::DecalGfxRange getDecalGraphics(DecalId decal) const { NPNR_ASSERT_FALSE("unreachable"); }; - virtual DecalXY getBelDecal(BelId bel) const { return DecalXY(); } - virtual DecalXY getWireDecal(WireId wire) const { return DecalXY(); } - virtual DecalXY getPipDecal(PipId pip) const { return DecalXY(); } - virtual DecalXY getGroupDecal(GroupId group) const { return DecalXY(); } + virtual typename R::DecalGfxRange getDecalGraphics(DecalId decal) const override + { + NPNR_ASSERT_FALSE("unreachable"); + }; + virtual DecalXY getBelDecal(BelId bel) const override { return DecalXY(); } + virtual DecalXY getWireDecal(WireId wire) const override { return DecalXY(); } + virtual DecalXY getPipDecal(PipId pip) const override { return DecalXY(); } + virtual DecalXY getGroupDecal(GroupId group) const override { return DecalXY(); } // Cell timing methods - virtual bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const + virtual bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const override { return false; } - virtual TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const + virtual TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const override { return TMG_IGNORE; } - virtual TimingClockingInfo getPortClockingInfo(const CellInfo *cell, IdString port, int index) const + virtual TimingClockingInfo getPortClockingInfo(const CellInfo *cell, IdString port, int index) const override { NPNR_ASSERT_FALSE("unreachable"); } // Placement validity checks - virtual bool isValidBelForCellType(IdString cell_type, BelId bel) const { return cell_type == getBelType(bel); } - virtual IdString getBelBucketName(BelBucketId bucket) const { return bbid_to_name(bucket); } - virtual BelBucketId getBelBucketByName(IdString name) const { return bbid_from_name(name); } - virtual BelBucketId getBelBucketForBel(BelId bel) const { return getBelBucketForCellType(getBelType(bel)); }; - virtual BelBucketId getBelBucketForCellType(IdString cell_type) const { return getBelBucketByName(cell_type); }; - virtual bool isValidBelForCell(CellInfo *cell, BelId bel) const { return true; } - virtual bool isBelLocationValid(BelId bel) const { return true; } - virtual typename R::CellTypeRange getCellTypes() const + virtual bool isValidBelForCellType(IdString cell_type, BelId bel) const override + { + return cell_type == this->getBelType(bel); + } + virtual IdString getBelBucketName(BelBucketId bucket) const override { return bbid_to_name(bucket); } + virtual BelBucketId getBelBucketByName(IdString name) const override { return bbid_from_name(name); } + virtual BelBucketId getBelBucketForBel(BelId bel) const override + { + return getBelBucketForCellType(this->getBelType(bel)); + }; + virtual BelBucketId getBelBucketForCellType(IdString cell_type) const override + { + return getBelBucketByName(cell_type); + }; + virtual bool isValidBelForCell(CellInfo *cell, BelId bel) const override { return true; } + virtual bool isBelLocationValid(BelId bel) const override { return true; } + virtual typename R::CellTypeRange getCellTypes() const override { NPNR_ASSERT(cell_types_initialised); return return_if_match &, typename R::CellTypeRange>(cell_types); } - virtual typename R::BelBucketRange getBelBuckets() const + virtual typename R::BelBucketRange getBelBuckets() const override { NPNR_ASSERT(bel_buckets_initialised); return return_if_match &, typename R::BelBucketRange>(bel_buckets); } - virtual typename R::BucketBelRange getBelsInBucket(BelBucketId bucket) const + virtual typename R::BucketBelRange getBelsInBucket(BelBucketId bucket) const override { NPNR_ASSERT(bel_buckets_initialised); return return_if_match &, typename R::BucketBelRange>(bucket_bels.at(bucket)); } // Flow methods - virtual bool pack() = 0; - virtual bool place() = 0; - virtual bool route() = 0; - virtual void assignArchInfo(){}; + virtual void assignArchInfo() override{}; // -------------------------------------------------------------- // These structures are used to provide default implementations of bel/wire/pip binding. Arches might want to @@ -1321,20 +1415,20 @@ template struct BaseArch : BaseCtx void init_cell_types() { std::unordered_set bel_types; - for (auto bel : getBels()) - bel_types.insert(getBelType(bel)); + for (auto bel : this->getBels()) + bel_types.insert(this->getBelType(bel)); std::copy(bel_types.begin(), bel_types.end(), std::back_inserter(cell_types)); std::sort(cell_types.begin(), cell_types.end()); cell_types_initialised = true; } void init_bel_buckets() { - for (auto cell_type : getCellTypes()) { - auto bucket = getBelBucketForCellType(cell_type); + for (auto cell_type : this->getCellTypes()) { + auto bucket = this->getBelBucketForCellType(cell_type); bucket_bels[bucket]; // create empty bucket } - for (auto bel : getBels()) { - auto bucket = getBelBucketForBel(bel); + for (auto bel : this->getBels()) { + auto bucket = this->getBelBucketForBel(bel); bucket_bels[bucket].push_back(bel); } for (auto &b : bucket_bels) -- cgit v1.2.3 From 59c3db46cabf9914b01451ac724ba3da33fe6f42 Mon Sep 17 00:00:00 2001 From: "D. Shah" Date: Fri, 5 Feb 2021 11:36:19 +0000 Subject: ice40: Switch to BaseArch Signed-off-by: D. Shah --- common/nextpnr.h | 1 + 1 file changed, 1 insertion(+) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index 7de5233b..78ac2e71 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -1093,6 +1093,7 @@ template struct ArchAPI : BaseCtx virtual typename R::BelAttrsRange getBelAttrs(BelId bel) const = 0; virtual WireId getBelPinWire(BelId bel, IdString pin) const = 0; virtual PortType getBelPinType(BelId bel, IdString pin) const = 0; + virtual typename R::BelPinsRange getBelPins(BelId bel) const = 0; // Wire methods virtual typename R::AllWiresRange getWires() const = 0; virtual WireId getWireByName(IdStringList name) const = 0; -- cgit v1.2.3 From 3e631fe2f415adeb0205eff866aaea74b8ef3ed8 Mon Sep 17 00:00:00 2001 From: "D. Shah" Date: Fri, 5 Feb 2021 18:41:35 +0000 Subject: Add archArgs and archArgsToId to Arch API Signed-off-by: D. Shah --- common/nextpnr.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index 78ac2e71..43c092f8 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -1070,6 +1070,8 @@ template struct ArchAPI : BaseCtx // Basic config virtual IdString archId() const = 0; virtual std::string getChipName() const = 0; + virtual typename R::ArchArgsType archArgs() const = 0; + virtual IdString archArgsToId(typename R::ArchArgsType args) const = 0; virtual int getGridDimX() const = 0; virtual int getGridDimY() const = 0; virtual int getTileBelDimZ(int x, int y) const = 0; @@ -1181,6 +1183,7 @@ template struct BaseArch : ArchAPI // Basic config virtual IdString archId() const override { return this->id(STRINGIFY(ARCHNAME)); } + virtual IdString archArgsToId(typename R::ArchArgsType args) const { return IdString(); } virtual int getTilePipDimZ(int x, int y) const override { return 1; } virtual char getNameDelimiter() const override { return ' '; } -- cgit v1.2.3 From efca63862c571e47cd449a6c5121ef07bf6de13f Mon Sep 17 00:00:00 2001 From: "D. Shah" Date: Mon, 8 Feb 2021 10:29:50 +0000 Subject: Use 'T' postfix to disambiguate LHS and RHS of using Arches might otherwise have range types named ambigiously with the entry in ArchRanges. Signed-off-by: D. Shah --- common/nextpnr.h | 90 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 48 insertions(+), 42 deletions(-) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index 43c092f8..58bff892 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -1070,15 +1070,15 @@ template struct ArchAPI : BaseCtx // Basic config virtual IdString archId() const = 0; virtual std::string getChipName() const = 0; - virtual typename R::ArchArgsType archArgs() const = 0; - virtual IdString archArgsToId(typename R::ArchArgsType args) const = 0; + virtual typename R::ArchArgsT archArgs() const = 0; + virtual IdString archArgsToId(typename R::ArchArgsT args) const = 0; virtual int getGridDimX() const = 0; virtual int getGridDimY() const = 0; virtual int getTileBelDimZ(int x, int y) const = 0; virtual int getTilePipDimZ(int x, int y) const = 0; virtual char getNameDelimiter() const = 0; // Bel methods - virtual typename R::AllBelsRange getBels() const = 0; + virtual typename R::AllBelsRangeT getBels() const = 0; virtual IdStringList getBelName(BelId bel) const = 0; virtual BelId getBelByName(IdStringList name) const = 0; virtual uint32_t getBelChecksum(BelId bel) const = 0; @@ -1086,25 +1086,25 @@ template struct ArchAPI : BaseCtx virtual void unbindBel(BelId bel) = 0; virtual Loc getBelLocation(BelId bel) const = 0; virtual BelId getBelByLocation(Loc loc) const = 0; - virtual typename R::TileBelsRange getBelsByTile(int x, int y) const = 0; + virtual typename R::TileBelsRangeT getBelsByTile(int x, int y) const = 0; virtual bool getBelGlobalBuf(BelId bel) const = 0; virtual bool checkBelAvail(BelId bel) const = 0; virtual CellInfo *getBoundBelCell(BelId bel) const = 0; virtual CellInfo *getConflictingBelCell(BelId bel) const = 0; virtual IdString getBelType(BelId bel) const = 0; - virtual typename R::BelAttrsRange getBelAttrs(BelId bel) const = 0; + virtual typename R::BelAttrsRangeT getBelAttrs(BelId bel) const = 0; virtual WireId getBelPinWire(BelId bel, IdString pin) const = 0; virtual PortType getBelPinType(BelId bel, IdString pin) const = 0; - virtual typename R::BelPinsRange getBelPins(BelId bel) const = 0; + virtual typename R::BelPinsRangeT getBelPins(BelId bel) const = 0; // Wire methods - virtual typename R::AllWiresRange getWires() const = 0; + virtual typename R::AllWiresRangeT getWires() const = 0; virtual WireId getWireByName(IdStringList name) const = 0; virtual IdStringList getWireName(WireId wire) const = 0; virtual IdString getWireType(WireId wire) const = 0; - virtual typename R::WireAttrsRange getWireAttrs(WireId) const = 0; - virtual typename R::DownhillPipRange getPipsDownhill(WireId wire) const = 0; - virtual typename R::UphillPipRange getPipsUphill(WireId wire) const = 0; - virtual typename R::WireBelPinRange getWireBelPins(WireId wire) const = 0; + virtual typename R::WireAttrsRangeT getWireAttrs(WireId) const = 0; + virtual typename R::DownhillPipRangeT getPipsDownhill(WireId wire) const = 0; + virtual typename R::UphillPipRangeT getPipsUphill(WireId wire) const = 0; + virtual typename R::WireBelPinRangeT getWireBelPins(WireId wire) const = 0; virtual uint32_t getWireChecksum(WireId wire) const = 0; virtual void bindWire(WireId wire, NetInfo *net, PlaceStrength strength) = 0; virtual void unbindWire(WireId wire) = 0; @@ -1114,11 +1114,11 @@ template struct ArchAPI : BaseCtx virtual NetInfo *getConflictingWireNet(WireId wire) const = 0; virtual DelayInfo getWireDelay(WireId wire) const = 0; // Pip methods - virtual typename R::AllPipsRange getPips() const = 0; + virtual typename R::AllPipsRangeT getPips() const = 0; virtual PipId getPipByName(IdStringList name) const = 0; virtual IdStringList getPipName(PipId pip) const = 0; virtual IdString getPipType(PipId pip) const = 0; - virtual typename R::PipAttrsRange getPipAttrs(PipId) const = 0; + virtual typename R::PipAttrsRangeT getPipAttrs(PipId) const = 0; virtual uint32_t getPipChecksum(PipId pip) const = 0; virtual void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) = 0; virtual void unbindPip(PipId pip) = 0; @@ -1133,11 +1133,11 @@ template struct ArchAPI : BaseCtx // Group methods virtual GroupId getGroupByName(IdStringList name) const = 0; virtual IdStringList getGroupName(GroupId group) const = 0; - virtual typename R::AllGroupsRange getGroups() const = 0; - virtual typename R::GroupBelsRange getGroupBels(GroupId group) const = 0; - virtual typename R::GroupWiresRange getGroupWires(GroupId group) const = 0; - virtual typename R::GroupPipsRange getGroupPips(GroupId group) const = 0; - virtual typename R::GroupGroupsRange getGroupGroups(GroupId group) const = 0; + virtual typename R::AllGroupsRangeT getGroups() const = 0; + virtual typename R::GroupBelsRangeT getGroupBels(GroupId group) const = 0; + virtual typename R::GroupWiresRangeT getGroupWires(GroupId group) const = 0; + virtual typename R::GroupPipsRangeT getGroupPips(GroupId group) const = 0; + virtual typename R::GroupGroupsRangeT getGroupGroups(GroupId group) const = 0; // Delay Methods virtual delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const = 0; virtual delay_t getDelayEpsilon() const = 0; @@ -1149,7 +1149,7 @@ template struct ArchAPI : BaseCtx virtual delay_t estimateDelay(WireId src, WireId dst) const = 0; virtual ArcBounds getRouteBoundingBox(WireId src, WireId dst) const = 0; // Decal methods - virtual typename R::DecalGfxRange getDecalGraphics(DecalId decal) const = 0; + virtual typename R::DecalGfxRangeT getDecalGraphics(DecalId decal) const = 0; virtual DecalXY getBelDecal(BelId bel) const = 0; virtual DecalXY getWireDecal(WireId wire) const = 0; virtual DecalXY getPipDecal(PipId pip) const = 0; @@ -1166,9 +1166,9 @@ template struct ArchAPI : BaseCtx virtual BelBucketId getBelBucketForCellType(IdString cell_type) const = 0; virtual bool isValidBelForCell(CellInfo *cell, BelId bel) const = 0; virtual bool isBelLocationValid(BelId bel) const = 0; - virtual typename R::CellTypeRange getCellTypes() const = 0; - virtual typename R::BelBucketRange getBelBuckets() const = 0; - virtual typename R::BucketBelRange getBelsInBucket(BelBucketId bucket) const = 0; + virtual typename R::CellTypeRangeT getCellTypes() const = 0; + virtual typename R::BelBucketRangeT getBelBuckets() const = 0; + virtual typename R::BucketBelRangeT getBelsInBucket(BelBucketId bucket) const = 0; // Flow methods virtual bool pack() = 0; virtual bool place() = 0; @@ -1183,7 +1183,7 @@ template struct BaseArch : ArchAPI // Basic config virtual IdString archId() const override { return this->id(STRINGIFY(ARCHNAME)); } - virtual IdString archArgsToId(typename R::ArchArgsType args) const { return IdString(); } + virtual IdString archArgsToId(typename R::ArchArgsT args) const { return IdString(); } virtual int getTilePipDimZ(int x, int y) const override { return 1; } virtual char getNameDelimiter() const override { return ' '; } @@ -1218,16 +1218,16 @@ template struct BaseArch : ArchAPI return fnd == base_bel2cell.end() ? nullptr : fnd->second; } virtual CellInfo *getConflictingBelCell(BelId bel) const override { return getBoundBelCell(bel); } - virtual typename R::BelAttrsRange getBelAttrs(BelId bel) const override + virtual typename R::BelAttrsRangeT getBelAttrs(BelId bel) const override { - return empty_if_possible(); + return empty_if_possible(); } // Wire methods virtual IdString getWireType(WireId wire) const override { return IdString(); } - virtual typename R::WireAttrsRange getWireAttrs(WireId) const override + virtual typename R::WireAttrsRangeT getWireAttrs(WireId) const override { - return empty_if_possible(); + return empty_if_possible(); } virtual uint32_t getWireChecksum(WireId wire) const override { return uint32_t(std::hash()(wire)); } @@ -1273,9 +1273,9 @@ template struct BaseArch : ArchAPI // Pip methods virtual IdString getPipType(PipId pip) const { return IdString(); } - virtual typename R::PipAttrsRange getPipAttrs(PipId) const override + virtual typename R::PipAttrsRangeT getPipAttrs(PipId) const override { - return empty_if_possible(); + return empty_if_possible(); } virtual uint32_t getPipChecksum(PipId pip) const override { return uint32_t(std::hash()(pip)); } virtual void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) override @@ -1318,18 +1318,24 @@ template struct BaseArch : ArchAPI // Group methods virtual GroupId getGroupByName(IdStringList name) const override { return GroupId(); }; virtual IdStringList getGroupName(GroupId group) const override { return IdStringList(); }; - virtual typename R::AllGroupsRange getGroups() const override + virtual typename R::AllGroupsRangeT getGroups() const override { - return empty_if_possible(); + return empty_if_possible(); } // Default implementation of these assumes no groups so never called - virtual typename R::GroupBelsRange getGroupBels(GroupId group) const override { NPNR_ASSERT_FALSE("unreachable"); }; - virtual typename R::GroupWiresRange getGroupWires(GroupId group) const override + virtual typename R::GroupBelsRangeT getGroupBels(GroupId group) const override { NPNR_ASSERT_FALSE("unreachable"); }; - virtual typename R::GroupPipsRange getGroupPips(GroupId group) const override { NPNR_ASSERT_FALSE("unreachable"); }; - virtual typename R::GroupGroupsRange getGroupGroups(GroupId group) const override + virtual typename R::GroupWiresRangeT getGroupWires(GroupId group) const override + { + NPNR_ASSERT_FALSE("unreachable"); + }; + virtual typename R::GroupPipsRangeT getGroupPips(GroupId group) const override + { + NPNR_ASSERT_FALSE("unreachable"); + }; + virtual typename R::GroupGroupsRangeT getGroupGroups(GroupId group) const override { NPNR_ASSERT_FALSE("unreachable"); }; @@ -1341,7 +1347,7 @@ template struct BaseArch : ArchAPI } // Decal methods - virtual typename R::DecalGfxRange getDecalGraphics(DecalId decal) const override + virtual typename R::DecalGfxRangeT getDecalGraphics(DecalId decal) const override { NPNR_ASSERT_FALSE("unreachable"); }; @@ -1381,20 +1387,20 @@ template struct BaseArch : ArchAPI }; virtual bool isValidBelForCell(CellInfo *cell, BelId bel) const override { return true; } virtual bool isBelLocationValid(BelId bel) const override { return true; } - virtual typename R::CellTypeRange getCellTypes() const override + virtual typename R::CellTypeRangeT getCellTypes() const override { NPNR_ASSERT(cell_types_initialised); - return return_if_match &, typename R::CellTypeRange>(cell_types); + return return_if_match &, typename R::CellTypeRangeT>(cell_types); } - virtual typename R::BelBucketRange getBelBuckets() const override + virtual typename R::BelBucketRangeT getBelBuckets() const override { NPNR_ASSERT(bel_buckets_initialised); - return return_if_match &, typename R::BelBucketRange>(bel_buckets); + return return_if_match &, typename R::BelBucketRangeT>(bel_buckets); } - virtual typename R::BucketBelRange getBelsInBucket(BelBucketId bucket) const override + virtual typename R::BucketBelRangeT getBelsInBucket(BelBucketId bucket) const override { NPNR_ASSERT(bel_buckets_initialised); - return return_if_match &, typename R::BucketBelRange>(bucket_bels.at(bucket)); + return return_if_match &, typename R::BucketBelRangeT>(bucket_bels.at(bucket)); } // Flow methods -- cgit v1.2.3 From 2932dc3985181afbf88a87e58ee27dfcca433625 Mon Sep 17 00:00:00 2001 From: gatecat Date: Mon, 8 Feb 2021 17:03:22 +0000 Subject: Make BaseCtx destructor virtual Signed-off-by: gatecat --- common/nextpnr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index 58bff892..2ecbaf0e 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -858,7 +858,7 @@ struct BaseCtx constraintObjects.push_back(wildcard); } - ~BaseCtx() + virtual ~BaseCtx() { delete idstring_str_to_idx; delete idstring_idx_to_str; -- cgit v1.2.3