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 +++++++++++++++++++++++++++++++++++++++ ecp5/arch.h | 152 +++++++++++++++++++++++++------------------------------ 2 files changed, 176 insertions(+), 84 deletions(-) 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 diff --git a/ecp5/arch.h b/ecp5/arch.h index 600b20c0..2cb6d526 100644 --- a/ecp5/arch.h +++ b/ecp5/arch.h @@ -470,22 +470,22 @@ struct Arch : BaseCtx static const int max_loc_bels = 20; - int getGridDimX() const { return chip_info->width; }; - int getGridDimY() const { return chip_info->height; }; - int getTileBelDimZ(int, int) const { return max_loc_bels; }; - int getTilePipDimZ(int, int) const { return 1; }; - char getNameDelimiter() const { return '/'; } + int getGridDimX() const override { return chip_info->width; }; + int getGridDimY() const override { return chip_info->height; }; + int getTileBelDimZ(int, int) const override { return max_loc_bels; }; + int getTilePipDimZ(int, int) const override { return 1; }; + char getNameDelimiter() const override { return '/'; } // ------------------------------------------------- - BelId getBelByName(IdStringList name) const; + BelId getBelByName(IdStringList name) const override; template const LocationTypePOD *loc_info(Id &id) const { return &(chip_info->locations[chip_info->location_type[id.location.y * chip_info->width + id.location.x]]); } - IdStringList getBelName(BelId bel) const + IdStringList getBelName(BelId bel) const override { NPNR_ASSERT(bel != BelId()); std::array ids{x_ids.at(bel.location.x), y_ids.at(bel.location.y), @@ -493,14 +493,14 @@ struct Arch : BaseCtx return IdStringList(ids); } - uint32_t getBelChecksum(BelId bel) const { return bel.index; } + uint32_t getBelChecksum(BelId bel) const override { return bel.index; } int get_bel_flat_index(BelId bel) const { return (bel.location.y * chip_info->width + bel.location.x) * max_loc_bels + bel.index; } - void bindBel(BelId bel, CellInfo *cell, PlaceStrength strength) + void bindBel(BelId bel, CellInfo *cell, PlaceStrength strength) override { NPNR_ASSERT(bel != BelId()); int idx = get_bel_flat_index(bel); @@ -511,7 +511,7 @@ struct Arch : BaseCtx refreshUiBel(bel); } - void unbindBel(BelId bel) + void unbindBel(BelId bel) override { NPNR_ASSERT(bel != BelId()); int idx = get_bel_flat_index(bel); @@ -522,7 +522,7 @@ struct Arch : BaseCtx refreshUiBel(bel); } - Loc getBelLocation(BelId bel) const + Loc getBelLocation(BelId bel) const override { Loc loc; loc.x = bel.location.x; @@ -531,24 +531,24 @@ struct Arch : BaseCtx return loc; } - BelId getBelByLocation(Loc loc) const; + BelId getBelByLocation(Loc loc) const override; BelRange getBelsByTile(int x, int y) const; - bool getBelGlobalBuf(BelId bel) const { return getBelType(bel) == id_DCCA; } + bool getBelGlobalBuf(BelId bel) const override { return getBelType(bel) == id_DCCA; } - bool checkBelAvail(BelId bel) const + bool checkBelAvail(BelId bel) const override { NPNR_ASSERT(bel != BelId()); return bel_to_cell[get_bel_flat_index(bel)] == nullptr; } - CellInfo *getBoundBelCell(BelId bel) const + CellInfo *getBoundBelCell(BelId bel) const override { NPNR_ASSERT(bel != BelId()); return bel_to_cell[get_bel_flat_index(bel)]; } - CellInfo *getConflictingBelCell(BelId bel) const + CellInfo *getConflictingBelCell(BelId bel) const override { NPNR_ASSERT(bel != BelId()); return bel_to_cell[get_bel_flat_index(bel)]; @@ -567,7 +567,7 @@ struct Arch : BaseCtx return range; } - IdString getBelType(BelId bel) const + IdString getBelType(BelId bel) const override { NPNR_ASSERT(bel != BelId()); IdString id; @@ -581,7 +581,7 @@ struct Arch : BaseCtx return ret; } - WireId getBelPinWire(BelId bel, IdString pin) const; + WireId getBelPinWire(BelId bel, IdString pin) const override; BelPinRange getWireBelPins(WireId wire) const { @@ -598,9 +598,9 @@ struct Arch : BaseCtx // ------------------------------------------------- - WireId getWireByName(IdStringList name) const; + WireId getWireByName(IdStringList name) const override; - IdStringList getWireName(WireId wire) const + IdStringList getWireName(WireId wire) const override { NPNR_ASSERT(wire != WireId()); std::array ids{x_ids.at(wire.location.x), y_ids.at(wire.location.y), @@ -608,7 +608,7 @@ struct Arch : BaseCtx return IdStringList(ids); } - IdString getWireType(WireId wire) const + IdString getWireType(WireId wire) const override { NPNR_ASSERT(wire != WireId()); IdString id; @@ -618,9 +618,9 @@ struct Arch : BaseCtx std::vector> getWireAttrs(WireId) const; - uint32_t getWireChecksum(WireId wire) const { return wire.index; } + uint32_t getWireChecksum(WireId wire) const override { return wire.index; } - void bindWire(WireId wire, NetInfo *net, PlaceStrength strength) + void bindWire(WireId wire, NetInfo *net, PlaceStrength strength) override { NPNR_ASSERT(wire != WireId()); NPNR_ASSERT(wire_to_net[wire] == nullptr); @@ -630,7 +630,7 @@ struct Arch : BaseCtx refreshUiWire(wire); } - void unbindWire(WireId wire) + void unbindWire(WireId wire) override { NPNR_ASSERT(wire != WireId()); NPNR_ASSERT(wire_to_net[wire] != nullptr); @@ -650,13 +650,13 @@ struct Arch : BaseCtx refreshUiWire(wire); } - bool checkWireAvail(WireId wire) const + bool checkWireAvail(WireId wire) const override { NPNR_ASSERT(wire != WireId()); return wire_to_net.find(wire) == wire_to_net.end() || wire_to_net.at(wire) == nullptr; } - NetInfo *getBoundWireNet(WireId wire) const + NetInfo *getBoundWireNet(WireId wire) const override { NPNR_ASSERT(wire != WireId()); if (wire_to_net.find(wire) == wire_to_net.end()) @@ -665,18 +665,7 @@ struct Arch : BaseCtx return wire_to_net.at(wire); } - WireId getConflictingWireWire(WireId wire) const { return wire; } - - NetInfo *getConflictingWireNet(WireId wire) const - { - NPNR_ASSERT(wire != WireId()); - if (wire_to_net.find(wire) == wire_to_net.end()) - return nullptr; - else - return wire_to_net.at(wire); - } - - DelayInfo getWireDelay(WireId wire) const + DelayInfo getWireDelay(WireId wire) const override { DelayInfo delay; delay.min_delay = 0; @@ -714,10 +703,8 @@ struct Arch : BaseCtx // ------------------------------------------------- - PipId getPipByName(IdStringList name) const; - IdStringList getPipName(PipId pip) const; - - IdString getPipType(PipId pip) const { return IdString(); } + PipId getPipByName(IdStringList name) const override; + IdStringList getPipName(PipId pip) const override; std::vector> getPipAttrs(PipId) const { @@ -725,9 +712,9 @@ struct Arch : BaseCtx return ret; } - uint32_t getPipChecksum(PipId pip) const { return pip.index; } + uint32_t getPipChecksum(PipId pip) const override { return pip.index; } - void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) + void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) override { NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip_to_net[pip] == nullptr); @@ -744,7 +731,7 @@ struct Arch : BaseCtx net->wires[dst].strength = strength; } - void unbindPip(PipId pip) + void unbindPip(PipId pip) override { NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip_to_net[pip] != nullptr); @@ -760,13 +747,13 @@ struct Arch : BaseCtx pip_to_net[pip] = nullptr; } - bool checkPipAvail(PipId pip) const + bool checkPipAvail(PipId pip) const override { NPNR_ASSERT(pip != PipId()); return pip_to_net.find(pip) == pip_to_net.end() || pip_to_net.at(pip) == nullptr; } - NetInfo *getBoundPipNet(PipId pip) const + NetInfo *getBoundPipNet(PipId pip) const override { NPNR_ASSERT(pip != PipId()); if (pip_to_net.find(pip) == pip_to_net.end()) @@ -775,9 +762,7 @@ struct Arch : BaseCtx return pip_to_net.at(pip); } - WireId getConflictingPipWire(PipId pip) const { return WireId(); } - - NetInfo *getConflictingPipNet(PipId pip) const + NetInfo *getConflictingPipNet(PipId pip) const override { NPNR_ASSERT(pip != PipId()); if (pip_to_net.find(pip) == pip_to_net.end()) @@ -799,7 +784,7 @@ struct Arch : BaseCtx return range; } - WireId getPipSrcWire(PipId pip) const + WireId getPipSrcWire(PipId pip) const override { WireId wire; NPNR_ASSERT(pip != PipId()); @@ -808,7 +793,7 @@ struct Arch : BaseCtx return wire; } - WireId getPipDstWire(PipId pip) const + WireId getPipDstWire(PipId pip) const override { WireId wire; NPNR_ASSERT(pip != PipId()); @@ -817,7 +802,7 @@ struct Arch : BaseCtx return wire; } - DelayInfo getPipDelay(PipId pip) const + DelayInfo getPipDelay(PipId pip) const override { DelayInfo delay; NPNR_ASSERT(pip != PipId()); @@ -871,7 +856,7 @@ struct Arch : BaseCtx return chip_info->tiletype_names[loc_info(pip)->pip_data[pip.index].tile_type].get(); } - Loc getPipLocation(PipId pip) const + Loc getPipLocation(PipId pip) const override { Loc loc; loc.x = pip.location.x; @@ -889,12 +874,12 @@ struct Arch : BaseCtx std::string get_pio_function_name(BelId bel) const; BelId get_pio_by_function_name(const std::string &name) const; - PortType getBelPinType(BelId bel, IdString pin) const; + PortType getBelPinType(BelId bel, IdString pin) const override; // ------------------------------------------------- - GroupId getGroupByName(IdStringList name) const; - IdStringList getGroupName(GroupId group) const; + GroupId getGroupByName(IdStringList name) const override; + IdStringList getGroupName(GroupId group) const override; std::vector getGroups() const; std::vector getGroupBels(GroupId group) const; std::vector getGroupWires(GroupId group) const; @@ -903,46 +888,46 @@ struct Arch : BaseCtx // ------------------------------------------------- - delay_t estimateDelay(WireId src, WireId dst) const; - ArcBounds getRouteBoundingBox(WireId src, WireId dst) const; - delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const; - delay_t getDelayEpsilon() const { return 20; } - delay_t getRipupDelayPenalty() const; - float getDelayNS(delay_t v) const { return v * 0.001; } - DelayInfo getDelayFromNS(float ns) const + delay_t estimateDelay(WireId src, WireId dst) const override; + ArcBounds getRouteBoundingBox(WireId src, WireId dst) const override; + delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const override; + delay_t getDelayEpsilon() const override { return 20; } + delay_t getRipupDelayPenalty() const override; + float getDelayNS(delay_t v) const override { return v * 0.001; } + DelayInfo getDelayFromNS(float ns) const override { DelayInfo del; del.min_delay = delay_t(ns * 1000); del.max_delay = delay_t(ns * 1000); return del; } - uint32_t getDelayChecksum(delay_t v) const { return v; } - bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const; + uint32_t getDelayChecksum(delay_t v) const override { return v; } + bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const override; // ------------------------------------------------- - bool pack(); - bool place(); - bool route(); + bool pack() override; + bool place() override; + bool route() override; // ------------------------------------------------- std::vector getDecalGraphics(DecalId decal) const; - DecalXY getBelDecal(BelId bel) const; - DecalXY getWireDecal(WireId wire) const; - DecalXY getPipDecal(PipId pip) const; - DecalXY getGroupDecal(GroupId group) const; + DecalXY getBelDecal(BelId bel) const override; + DecalXY getWireDecal(WireId wire) const override; + DecalXY getPipDecal(PipId pip) const override; + DecalXY getGroupDecal(GroupId group) const override; // ------------------------------------------------- // Get the delay through a cell from one port to another, returning false // if no path exists - bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const; + bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const override; // Get the port class, also setting clockInfoCount to the number of TimingClockingInfos associated with a port - TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const; + TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const override; // Get the TimingClockingInfo of a port - TimingClockingInfo getPortClockingInfo(const CellInfo *cell, IdString port, int index) const; + TimingClockingInfo getPortClockingInfo(const CellInfo *cell, IdString port, int index) const override; // Return true if a port is a net bool is_global_net(const NetInfo *net) const; @@ -952,29 +937,28 @@ struct Arch : BaseCtx // ------------------------------------------------- // Placement validity checks - bool isValidBelForCellType(IdString cell_type, BelId bel) const { return cell_type == getBelType(bel); } const std::vector &getCellTypes() const { return cell_types; } std::vector getBelBuckets() const { return buckets; } - IdString getBelBucketName(BelBucketId bucket) const { return bucket.name; } + IdString getBelBucketName(BelBucketId bucket) const override { return bucket.name; } - BelBucketId getBelBucketByName(IdString name) const + BelBucketId getBelBucketByName(IdString name) const override { BelBucketId bucket; bucket.name = name; return bucket; } - BelBucketId getBelBucketForBel(BelId bel) const + BelBucketId getBelBucketForBel(BelId bel) const override { BelBucketId bucket; bucket.name = getBelType(bel); return bucket; } - BelBucketId getBelBucketForCellType(IdString cell_type) const + BelBucketId getBelBucketForCellType(IdString cell_type) const override { BelBucketId bucket; bucket.name = cell_type; @@ -992,13 +976,13 @@ struct Arch : BaseCtx return bels; } - bool isValidBelForCell(CellInfo *cell, BelId bel) const; - bool isBelLocationValid(BelId bel) const; + bool isValidBelForCell(CellInfo *cell, BelId bel) const override; + bool isBelLocationValid(BelId bel) const override; // Helper function for above bool slices_compatible(const std::vector &cells) const; - void assignArchInfo(); + void assignArchInfo() override; void permute_luts(); -- cgit v1.2.3