diff options
Diffstat (limited to 'ecp5')
-rw-r--r-- | ecp5/arch.cc | 14 | ||||
-rw-r--r-- | ecp5/arch.h | 339 | ||||
-rw-r--r-- | ecp5/arch_pybindings.h | 12 | ||||
-rw-r--r-- | ecp5/archdefs.h | 19 |
4 files changed, 116 insertions, 268 deletions
diff --git a/ecp5/arch.cc b/ecp5/arch.cc index 1f19ee86..cf1745ff 100644 --- a/ecp5/arch.cc +++ b/ecp5/arch.cc @@ -105,18 +105,8 @@ Arch::Arch(ArchArgs args) : args(args) bel_to_cell.resize(chip_info->height * chip_info->width * max_loc_bels, nullptr); - std::unordered_set<IdString> bel_types; - for (BelId bel : getBels()) { - bel_types.insert(getBelType(bel)); - } - - for (IdString bel_type : bel_types) { - cell_types.push_back(bel_type); - - BelBucketId bucket; - bucket.name = bel_type; - buckets.push_back(bucket); - } + BaseArch::init_cell_types(); + BaseArch::init_bel_buckets(); for (int i = 0; i < chip_info->width; i++) x_ids.push_back(id(stringf("X%d", i))); diff --git a/ecp5/arch.h b/ecp5/arch.h index 248c8cc4..49582a6e 100644 --- a/ecp5/arch.h +++ b/ecp5/arch.h @@ -435,7 +435,38 @@ template <> struct hash<NEXTPNR_NAMESPACE_PREFIX DelayKey> } // namespace std NEXTPNR_NAMESPACE_BEGIN -struct Arch : BaseCtx +struct ArchRanges +{ + using ArchArgsT = ArchArgs; + // Bels + using AllBelsRangeT = BelRange; + using TileBelsRangeT = BelRange; + using BelAttrsRangeT = std::vector<std::pair<IdString, std::string>>; + using BelPinsRangeT = std::vector<IdString>; + // Wires + using AllWiresRangeT = WireRange; + using DownhillPipRangeT = PipRange; + using UphillPipRangeT = PipRange; + using WireBelPinRangeT = BelPinRange; + using WireAttrsRangeT = std::vector<std::pair<IdString, std::string>>; + // Pips + using AllPipsRangeT = AllPipRange; + using PipAttrsRangeT = std::vector<std::pair<IdString, std::string>>; + // Groups + using AllGroupsRangeT = std::vector<GroupId>; + using GroupBelsRangeT = std::vector<BelId>; + using GroupWiresRangeT = std::vector<WireId>; + using GroupPipsRangeT = std::vector<PipId>; + using GroupGroupsRangeT = std::vector<GroupId>; + // Decals + using DecalGfxRangeT = std::vector<GraphicElement>; + // Placement validity + using CellTypeRangeT = const std::vector<IdString> &; + using BelBucketRangeT = const std::vector<BelBucketId> &; + using BucketBelRangeT = const std::vector<BelId> &; +}; + +struct Arch : BaseArch<ArchRanges> { const ChipInfoPOD *chip_info; const PackageInfoPOD *package_info; @@ -444,8 +475,6 @@ struct Arch : BaseCtx mutable std::unordered_map<IdStringList, PipId> pip_by_name; std::vector<CellInfo *> bel_to_cell; - std::unordered_map<WireId, NetInfo *> wire_to_net; - std::unordered_map<PipId, NetInfo *> pip_to_net; std::unordered_map<WireId, int> wire_fanout; // fast access to X and Y IdStrings for building object names @@ -459,33 +488,32 @@ struct Arch : BaseCtx static bool is_available(ArchArgs::ArchArgsTypes chip); static std::vector<std::string> get_supported_packages(ArchArgs::ArchArgsTypes chip); - std::string getChipName() const; + std::string getChipName() const override; std::string get_full_chip_name() const; - IdString archId() const { return id("ecp5"); } - ArchArgs archArgs() const { return args; } - IdString archArgsToId(ArchArgs args) const; + ArchArgs archArgs() const override { return args; } + IdString archArgsToId(ArchArgs args) const override; // ------------------------------------------------- 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 <typename Id> 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<IdString, 3> ids{x_ids.at(bel.location.x), y_ids.at(bel.location.y), @@ -493,14 +521,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 +539,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 +550,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,30 +559,30 @@ struct Arch : BaseCtx return loc; } - BelId getBelByLocation(Loc loc) const; - BelRange getBelsByTile(int x, int y) const; + BelId getBelByLocation(Loc loc) const override; + BelRange getBelsByTile(int x, int y) const override; - 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)]; } - BelRange getBels() const + BelRange getBels() const override { BelRange range; range.b.cursor_tile = 0; @@ -567,7 +595,7 @@ struct Arch : BaseCtx return range; } - IdString getBelType(BelId bel) const + IdString getBelType(BelId bel) const override { NPNR_ASSERT(bel != BelId()); IdString id; @@ -575,15 +603,9 @@ struct Arch : BaseCtx return id; } - std::vector<std::pair<IdString, std::string>> getBelAttrs(BelId) const - { - std::vector<std::pair<IdString, std::string>> ret; - return ret; - } - - WireId getBelPinWire(BelId bel, IdString pin) const; + WireId getBelPinWire(BelId bel, IdString pin) const override; - BelPinRange getWireBelPins(WireId wire) const + BelPinRange getWireBelPins(WireId wire) const override { BelPinRange range; NPNR_ASSERT(wire != WireId()); @@ -598,9 +620,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<IdString, 3> ids{x_ids.at(wire.location.x), y_ids.at(wire.location.y), @@ -608,7 +630,7 @@ struct Arch : BaseCtx return IdStringList(ids); } - IdString getWireType(WireId wire) const + IdString getWireType(WireId wire) const override { NPNR_ASSERT(wire != WireId()); IdString id; @@ -616,67 +638,27 @@ struct Arch : BaseCtx return id; } - std::vector<std::pair<IdString, std::string>> getWireAttrs(WireId) const; + std::vector<std::pair<IdString, std::string>> getWireAttrs(WireId) const override; - 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 unbindWire(WireId wire) override { NPNR_ASSERT(wire != WireId()); - NPNR_ASSERT(wire_to_net[wire] == nullptr); - wire_to_net[wire] = net; - net->wires[wire].pip = PipId(); - net->wires[wire].strength = strength; - refreshUiWire(wire); - } + NPNR_ASSERT(base_wire2net[wire] != nullptr); - void unbindWire(WireId wire) - { - NPNR_ASSERT(wire != WireId()); - NPNR_ASSERT(wire_to_net[wire] != nullptr); - - auto &net_wires = wire_to_net[wire]->wires; + auto &net_wires = base_wire2net[wire]->wires; auto it = net_wires.find(wire); NPNR_ASSERT(it != net_wires.end()); - auto pip = it->second.pip; + // As well as the default rules; need to handle fanout counting if (pip != PipId()) { wire_fanout[getPipSrcWire(pip)]--; - pip_to_net[pip] = nullptr; } - - net_wires.erase(it); - wire_to_net[wire] = nullptr; - refreshUiWire(wire); - } - - bool checkWireAvail(WireId wire) const - { - NPNR_ASSERT(wire != WireId()); - return wire_to_net.find(wire) == wire_to_net.end() || wire_to_net.at(wire) == nullptr; + BaseArch::unbindWire(wire); } - NetInfo *getBoundWireNet(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); - } - - 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; @@ -684,7 +666,7 @@ struct Arch : BaseCtx return delay; } - WireRange getWires() const + WireRange getWires() const override { WireRange range; range.b.cursor_tile = 0; @@ -714,79 +696,24 @@ struct Arch : BaseCtx // ------------------------------------------------- - PipId getPipByName(IdStringList name) const; - IdStringList getPipName(PipId pip) const; + PipId getPipByName(IdStringList name) const override; + IdStringList getPipName(PipId pip) const override; - IdString getPipType(PipId pip) const { return IdString(); } + uint32_t getPipChecksum(PipId pip) const override { return pip.index; } - std::vector<std::pair<IdString, std::string>> getPipAttrs(PipId) const + void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) override { - std::vector<std::pair<IdString, std::string>> ret; - return ret; - } - - uint32_t getPipChecksum(PipId pip) const { return pip.index; } - - void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) - { - NPNR_ASSERT(pip != PipId()); - NPNR_ASSERT(pip_to_net[pip] == nullptr); - - pip_to_net[pip] = net; wire_fanout[getPipSrcWire(pip)]++; - - WireId dst; - dst.index = loc_info(pip)->pip_data[pip.index].dst_idx; - dst.location = pip.location + loc_info(pip)->pip_data[pip.index].rel_dst_loc; - NPNR_ASSERT(wire_to_net[dst] == nullptr); - wire_to_net[dst] = net; - net->wires[dst].pip = pip; - net->wires[dst].strength = strength; + BaseArch::bindPip(pip, net, strength); } - void unbindPip(PipId pip) + void unbindPip(PipId pip) override { - NPNR_ASSERT(pip != PipId()); - NPNR_ASSERT(pip_to_net[pip] != nullptr); wire_fanout[getPipSrcWire(pip)]--; - - WireId dst; - dst.index = loc_info(pip)->pip_data[pip.index].dst_idx; - dst.location = pip.location + loc_info(pip)->pip_data[pip.index].rel_dst_loc; - NPNR_ASSERT(wire_to_net[dst] != nullptr); - wire_to_net[dst] = nullptr; - pip_to_net[pip]->wires.erase(dst); - - pip_to_net[pip] = nullptr; + BaseArch::unbindPip(pip); } - bool checkPipAvail(PipId pip) const - { - 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 - { - NPNR_ASSERT(pip != PipId()); - if (pip_to_net.find(pip) == pip_to_net.end()) - return nullptr; - else - return pip_to_net.at(pip); - } - - WireId getConflictingPipWire(PipId pip) const { return WireId(); } - - NetInfo *getConflictingPipNet(PipId pip) const - { - NPNR_ASSERT(pip != PipId()); - if (pip_to_net.find(pip) == pip_to_net.end()) - return nullptr; - else - return pip_to_net.at(pip); - } - - AllPipRange getPips() const + AllPipRange getPips() const override { AllPipRange range; range.b.cursor_tile = 0; @@ -799,7 +726,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 +735,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 +744,7 @@ struct Arch : BaseCtx return wire; } - DelayInfo getPipDelay(PipId pip) const + DelayInfo getPipDelay(PipId pip) const override { DelayInfo delay; NPNR_ASSERT(pip != PipId()); @@ -834,7 +761,7 @@ struct Arch : BaseCtx return delay; } - PipRange getPipsDownhill(WireId wire) const + PipRange getPipsDownhill(WireId wire) const override { PipRange range; NPNR_ASSERT(wire != WireId()); @@ -845,7 +772,7 @@ struct Arch : BaseCtx return range; } - PipRange getPipsUphill(WireId wire) const + PipRange getPipsUphill(WireId wire) const override { PipRange range; NPNR_ASSERT(wire != WireId()); @@ -871,7 +798,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,60 +816,60 @@ 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; - std::vector<GroupId> getGroups() const; - std::vector<BelId> getGroupBels(GroupId group) const; - std::vector<WireId> getGroupWires(GroupId group) const; - std::vector<PipId> getGroupPips(GroupId group) const; - std::vector<GroupId> getGroupGroups(GroupId group) const; + GroupId getGroupByName(IdStringList name) const override; + IdStringList getGroupName(GroupId group) const override; + std::vector<GroupId> getGroups() const override; + std::vector<BelId> getGroupBels(GroupId group) const override; + std::vector<WireId> getGroupWires(GroupId group) const override; + std::vector<PipId> getGroupPips(GroupId group) const override; + std::vector<GroupId> getGroupGroups(GroupId group) const override; // ------------------------------------------------- - 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<GraphicElement> getDecalGraphics(DecalId decal) const; + std::vector<GraphicElement> getDecalGraphics(DecalId decal) const override; - 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,53 +879,13 @@ struct Arch : BaseCtx // ------------------------------------------------- // Placement validity checks - bool isValidBelForCellType(IdString cell_type, BelId bel) const { return cell_type == getBelType(bel); } - - const std::vector<IdString> &getCellTypes() const { return cell_types; } - - std::vector<BelBucketId> getBelBuckets() const { return buckets; } - - IdString getBelBucketName(BelBucketId bucket) const { return bucket.name; } - - BelBucketId getBelBucketByName(IdString name) const - { - BelBucketId bucket; - bucket.name = name; - return bucket; - } - - BelBucketId getBelBucketForBel(BelId bel) const - { - BelBucketId bucket; - bucket.name = getBelType(bel); - return bucket; - } - - BelBucketId getBelBucketForCellType(IdString cell_type) const - { - BelBucketId bucket; - bucket.name = cell_type; - return bucket; - } - - std::vector<BelId> getBelsInBucket(BelBucketId bucket) const - { - std::vector<BelId> bels; - for (BelId bel : getBels()) { - if (getBelType(bel) == bucket.name) { - bels.push_back(bel); - } - } - 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<const CellInfo *> &cells) const; - void assignArchInfo(); + void assignArchInfo() override; void permute_luts(); diff --git a/ecp5/arch_pybindings.h b/ecp5/arch_pybindings.h index 4228f12b..f2a7dabe 100644 --- a/ecp5/arch_pybindings.h +++ b/ecp5/arch_pybindings.h @@ -76,18 +76,6 @@ template <> struct string_converter<PipId> } }; -template <> struct string_converter<BelBucketId> -{ - BelBucketId from_str(Context *ctx, std::string name) { return ctx->getBelBucketByName(ctx->id(name)); } - - std::string to_str(Context *ctx, BelBucketId id) - { - if (id == BelBucketId()) - throw bad_wrap(); - return ctx->getBelBucketName(id).str(ctx); - } -}; - template <> struct string_converter<BelPin> { BelPin from_str(Context *ctx, std::string name) diff --git a/ecp5/archdefs.h b/ecp5/archdefs.h index 3bc75ab4..c8fdf892 100644 --- a/ecp5/archdefs.h +++ b/ecp5/archdefs.h @@ -126,14 +126,7 @@ struct PipId } }; -struct BelBucketId -{ - IdString name; - - bool operator==(const BelBucketId &other) const { return (name == other.name); } - bool operator!=(const BelBucketId &other) const { return (name != other.name); } - bool operator<(const BelBucketId &other) const { return name < other.name; } -}; +typedef IdString BelBucketId; struct GroupId { @@ -271,14 +264,4 @@ template <> struct hash<NEXTPNR_NAMESPACE_PREFIX DecalId> } }; -template <> struct hash<NEXTPNR_NAMESPACE_PREFIX BelBucketId> -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX BelBucketId &partition) const noexcept - { - std::size_t seed = 0; - boost::hash_combine(seed, hash<NEXTPNR_NAMESPACE_PREFIX IdString>()(partition.name)); - return seed; - } -}; - } // namespace std |