diff options
author | Sergiusz Bazanski <q3k@q3k.org> | 2018-07-14 11:10:31 +0100 |
---|---|---|
committer | Sergiusz Bazanski <q3k@q3k.org> | 2018-07-14 11:10:31 +0100 |
commit | 9b17fe385cf7e8d3025747b5f7c7822ac2d99920 (patch) | |
tree | 1822cebedf1e346defe28f0707de7332d45a92cc /ice40 | |
parent | a38b4fa1735bd0af78520f6d5320a264914fb838 (diff) | |
download | nextpnr-9b17fe385cf7e8d3025747b5f7c7822ac2d99920.tar.gz nextpnr-9b17fe385cf7e8d3025747b5f7c7822ac2d99920.tar.bz2 nextpnr-9b17fe385cf7e8d3025747b5f7c7822ac2d99920.zip |
Refactor proxies to nextpnr.
Diffstat (limited to 'ice40')
-rw-r--r-- | ice40/arch.cc | 77 | ||||
-rw-r--r-- | ice40/arch.h | 130 | ||||
-rw-r--r-- | ice40/arch_place.cc | 6 | ||||
-rw-r--r-- | ice40/place_legaliser.cc | 6 |
4 files changed, 63 insertions, 156 deletions
diff --git a/ice40/arch.cc b/ice40/arch.cc index 547dbcd6..790167e9 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -29,18 +29,6 @@ NEXTPNR_NAMESPACE_BEGIN -ArchRWProxy Arch::rwproxy(void) { - ArchRWProxy res(this); - return res; -} - -ArchRProxy Arch::rproxy(void) const { - ArchRProxy res(this); - return res; -} - -// ----------------------------------------------------------------------- - IdString Arch::belTypeToId(BelType type) const { if (type == TYPE_ICESTORM_LC) @@ -534,7 +522,7 @@ DecalXY Arch::getGroupDecal(GroupId group) const return decalxy; }; -std::vector<GraphicElement> ArchRProxyMethods::getDecalGraphics(DecalId decal) const +std::vector<GraphicElement> ArchReadMethods::getDecalGraphics(DecalId decal) const { std::vector<GraphicElement> ret; @@ -732,25 +720,25 @@ bool Arch::isGlobalNet(const NetInfo *net) const // ----------------------------------------------------------------------- -bool ArchRProxyMethods::checkBelAvail(BelId bel) const +bool ArchReadMethods::checkBelAvail(BelId bel) const { NPNR_ASSERT(bel != BelId()); return bel_to_cell[bel.index] == IdString(); } -IdString ArchRProxyMethods::getBoundBelCell(BelId bel) const +IdString ArchReadMethods::getBoundBelCell(BelId bel) const { NPNR_ASSERT(bel != BelId()); return bel_to_cell[bel.index]; } -IdString ArchRProxyMethods::getConflictingBelCell(BelId bel) const +IdString ArchReadMethods::getConflictingBelCell(BelId bel) const { NPNR_ASSERT(bel != BelId()); return bel_to_cell[bel.index]; } -WireId ArchRProxyMethods::getWireBelPin(BelId bel, PortPin pin) const +WireId ArchReadMethods::getWireBelPin(BelId bel, PortPin pin) const { WireId ret; @@ -768,7 +756,7 @@ WireId ArchRProxyMethods::getWireBelPin(BelId bel, PortPin pin) const return ret; } -WireId ArchRProxyMethods::getWireByName(IdString name) const +WireId ArchReadMethods::getWireByName(IdString name) const { WireId ret; @@ -784,25 +772,25 @@ WireId ArchRProxyMethods::getWireByName(IdString name) const return ret; } -bool ArchRProxyMethods::checkWireAvail(WireId wire) const +bool ArchReadMethods::checkWireAvail(WireId wire) const { NPNR_ASSERT(wire != WireId()); return wire_to_net[wire.index] == IdString(); } -IdString ArchRProxyMethods::getBoundWireNet(WireId wire) const +IdString ArchReadMethods::getBoundWireNet(WireId wire) const { NPNR_ASSERT(wire != WireId()); return wire_to_net[wire.index]; } -IdString ArchRProxyMethods::getConflictingWireNet(WireId wire) const +IdString ArchReadMethods::getConflictingWireNet(WireId wire) const { NPNR_ASSERT(wire != WireId()); return wire_to_net[wire.index]; } -PipId ArchRProxyMethods::getPipByName(IdString name) const +PipId ArchReadMethods::getPipByName(IdString name) const { PipId ret; @@ -821,25 +809,25 @@ PipId ArchRProxyMethods::getPipByName(IdString name) const return ret; } -bool ArchRProxyMethods::checkPipAvail(PipId pip) const +bool ArchReadMethods::checkPipAvail(PipId pip) const { NPNR_ASSERT(pip != PipId()); return switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString(); } -IdString ArchRProxyMethods::getBoundPipNet(PipId pip) const +IdString ArchReadMethods::getBoundPipNet(PipId pip) const { NPNR_ASSERT(pip != PipId()); return pip_to_net[pip.index]; } -IdString ArchRProxyMethods::getConflictingPipNet(PipId pip) const +IdString ArchReadMethods::getConflictingPipNet(PipId pip) const { NPNR_ASSERT(pip != PipId()); return switches_locked[chip_info->pip_data[pip.index].switch_index]; } -BelId ArchRProxyMethods::getBelByName(IdString name) const +BelId ArchReadMethods::getBelByName(IdString name) const { BelId ret; @@ -857,27 +845,27 @@ BelId ArchRProxyMethods::getBelByName(IdString name) const // ----------------------------------------------------------------------- -void ArchRWProxyMethods::bindBel(BelId bel, IdString cell, PlaceStrength strength) +void ArchMutateMethods::bindBel(BelId bel, IdString cell, PlaceStrength strength) { NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel_to_cell[bel.index] == IdString()); bel_to_cell[bel.index] = cell; parent_->cells[cell]->bel = bel; parent_->cells[cell]->belStrength = strength; - parent_->refreshUiBel(bel); + refreshUiBel(bel); } -void ArchRWProxyMethods::unbindBel(BelId bel) +void ArchMutateMethods::unbindBel(BelId bel) { NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel_to_cell[bel.index] != IdString()); parent_->cells[bel_to_cell[bel.index]]->bel = BelId(); parent_->cells[bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE; bel_to_cell[bel.index] = IdString(); - parent_->refreshUiBel(bel); + refreshUiBel(bel); } -void ArchRWProxyMethods::bindWire(WireId wire, IdString net, PlaceStrength strength) +void ArchMutateMethods::bindWire(WireId wire, IdString net, PlaceStrength strength) { NPNR_ASSERT(wire != WireId()); NPNR_ASSERT(wire_to_net[wire.index] == IdString()); @@ -885,10 +873,10 @@ void ArchRWProxyMethods::bindWire(WireId wire, IdString net, PlaceStrength stren wire_to_net[wire.index] = net; parent_->nets[net]->wires[wire].pip = PipId(); parent_->nets[net]->wires[wire].strength = strength; - parent_->refreshUiWire(wire); + refreshUiWire(wire); } -void ArchRWProxyMethods::unbindWire(WireId wire) +void ArchMutateMethods::unbindWire(WireId wire) { NPNR_ASSERT(wire != WireId()); NPNR_ASSERT(wire_to_net[wire.index] != IdString()); @@ -901,15 +889,15 @@ void ArchRWProxyMethods::unbindWire(WireId wire) if (pip != PipId()) { pip_to_net[pip.index] = IdString(); switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString(); - parent_->refreshUiPip(pip); + refreshUiPip(pip); } net_wires.erase(it); wire_to_net[wire.index] = IdString(); - parent_->refreshUiWire(wire); + refreshUiWire(wire); } -void ArchRWProxyMethods::bindPip(PipId pip, IdString net, PlaceStrength strength) +void ArchMutateMethods::bindPip(PipId pip, IdString net, PlaceStrength strength) { NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip_to_net[pip.index] == IdString()); @@ -925,11 +913,11 @@ void ArchRWProxyMethods::bindPip(PipId pip, IdString net, PlaceStrength strength parent_->nets[net]->wires[dst].pip = pip; parent_->nets[net]->wires[dst].strength = strength; - parent_->refreshUiPip(pip); - parent_->refreshUiWire(dst); + refreshUiPip(pip); + refreshUiWire(dst); } -void ArchRWProxyMethods::unbindPip(PipId pip) +void ArchMutateMethods::unbindPip(PipId pip) { NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip_to_net[pip.index] != IdString()); @@ -944,18 +932,13 @@ void ArchRWProxyMethods::unbindPip(PipId pip) pip_to_net[pip.index] = IdString(); switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString(); - parent_->refreshUiPip(pip); - parent_->refreshUiWire(dst); + refreshUiPip(pip); + refreshUiWire(dst); } -CellInfo *ArchRWProxyMethods::getCell(IdString cell) +CellInfo *ArchMutateMethods::getCell(IdString cell) { return parent_->cells.at(cell).get(); } -UIUpdatesRequired ArchRWProxyMethods::getUIUpdatesRequired(void) -{ - return parent_->getUIUpdatesRequired(); -} - NEXTPNR_NAMESPACE_END diff --git a/ice40/arch.h b/ice40/arch.h index 4311f4a5..5d4eaedf 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -22,9 +22,6 @@ #error Include "arch.h" via "nextpnr.h" only. #endif -#include <boost/thread/shared_lock_guard.hpp> -#include <boost/thread/shared_mutex.hpp> - NEXTPNR_NAMESPACE_BEGIN /**** Everything in this section must be kept in sync with chipdb.py ****/ @@ -330,11 +327,8 @@ struct ArchArgs /// Forward declare proxy classes for Arch. -class ArchRWProxyMethods; -class ArchRProxyMethods; -class ArchRWProxy; -class ArchRProxy; - +class ArchMutateMethods; +class ArchReadMethods; /// Arch/Context // Arch is the main state class of the PnR algorithms. It keeps note of mapped @@ -347,11 +341,8 @@ class ArchRProxy; class Arch : public BaseCtx { // We let proxy methods access our state. - friend class ArchRWProxyMethods; - friend class ArchRProxyMethods; - // We let proxy objects access our mutex. - friend class ArchRWProxy; - friend class ArchRProxy; + friend class ArchMutateMethods; + friend class ArchReadMethods; private: // All of the following... std::vector<IdString> bel_to_cell; @@ -362,9 +353,6 @@ private: mutable std::unordered_map<IdString, int> wire_by_name; mutable std::unordered_map<IdString, int> pip_by_name; - // ... are guarded by the following lock: - mutable boost::shared_mutex mtx_; - public: const ChipInfoPOD *chip_info; const PackageInfoPOD *package_info; @@ -372,15 +360,6 @@ public: ArchArgs args; Arch(ArchArgs args); - // Get a readwrite proxy to arch - this will keep a readwrite lock on the - // entire architecture until the proxy object goes out of scope. - ArchRWProxy rwproxy(void); - // Get a read-only proxy to arch - this will keep a read lock on the - // entire architecture until the proxy object goes out of scope. Other read - // locks can be taken while this one still exists. Ie., the UI can draw - // elements while the PnR is going a RO operation. - ArchRProxy rproxy(void) const; - std::string getChipName(); IdString archId() const { return id("ice40"); } @@ -632,22 +611,9 @@ public: }; // Read-only methods on Arch that require state access. -class ArchRProxyMethods { - // We let proxy objects access our private constructors. - friend class ArchRProxy; - friend class ArchRWProxy; +class ArchReadMethods : public BaseReadCtx { private: const Arch *parent_; - ArchRProxyMethods(const Arch *parent) : parent_(parent), chip_info(parent->chip_info), - bel_to_cell(parent->bel_to_cell), wire_to_net(parent->wire_to_net), - pip_to_net(parent->pip_to_net), switches_locked(parent->switches_locked), - bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), - pip_by_name(parent->pip_by_name) {} - ArchRProxyMethods(ArchRProxyMethods &&other) noexcept : ArchRProxyMethods(other.parent_) {} - ArchRProxyMethods(const ArchRProxyMethods &other) : ArchRProxyMethods(other.parent_) {} - - // Let methods access hot members directly without having to go through - // parent_. const ChipInfoPOD *chip_info; const std::vector<IdString> &bel_to_cell; const std::vector<IdString> &wire_to_net; @@ -656,8 +622,17 @@ private: std::unordered_map<IdString, int> &bel_by_name; std::unordered_map<IdString, int> &wire_by_name; std::unordered_map<IdString, int> &pip_by_name; + public: - ~ArchRProxyMethods() noexcept { } + ~ArchReadMethods() noexcept { } + ArchReadMethods(const Arch *parent) : BaseReadCtx(parent), parent_(parent), + chip_info(parent->chip_info), bel_to_cell(parent->bel_to_cell), + wire_to_net(parent->wire_to_net), pip_to_net(parent->pip_to_net), + switches_locked(parent->switches_locked), + bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), + pip_by_name(parent->pip_by_name) {} + ArchReadMethods(ArchReadMethods &&other) noexcept : ArchReadMethods(other.parent_) {} + ArchReadMethods(const ArchReadMethods &other) : ArchReadMethods(other.parent_) {} /// Perform placement validity checks, returning false on failure (all implemented in arch_place.cc) @@ -693,44 +668,11 @@ public: std::vector<GraphicElement> getDecalGraphics(DecalId decal) const; }; -// A proxy object that keeps an Arch shared/readonly lock until it goes out -// of scope. All const/read-only ArchRProxyMethods are available on it. -class ArchRProxy : public ArchRProxyMethods { - friend class Arch; - friend class ArchRWProxy; -private: - boost::shared_mutex *lock_; - ArchRProxy(const Arch *parent) : ArchRProxyMethods(parent), lock_(&parent->mtx_) - { - lock_->lock_shared(); - } - -public: - ~ArchRProxy() { - if (lock_ != nullptr) { - lock_->unlock_shared(); - } - } - ArchRProxy(ArchRProxy &&other) : ArchRProxyMethods(other), lock_(other.lock_) - { - other.lock_ = nullptr; - } -}; - // State mutating methods on Arch. -class ArchRWProxyMethods { - // We let proxy objects access our private constructors. - friend class ArchRWProxy; +class ArchMutateMethods : public BaseMutateCtx { + friend class MutateContext; private: Arch *parent_; - ArchRWProxyMethods(Arch *parent) : parent_(parent), chip_info(parent->chip_info), - bel_to_cell(parent->bel_to_cell), wire_to_net(parent->wire_to_net), - pip_to_net(parent->pip_to_net), switches_locked(parent->switches_locked), - bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), - pip_by_name(parent->pip_by_name) {} - ArchRWProxyMethods(ArchRWProxyMethods &&other) : ArchRWProxyMethods(other.parent_) {} - ArchRWProxyMethods(const ArchRWProxyMethods &other) : ArchRWProxyMethods(other.parent_) {} - const ChipInfoPOD *chip_info; std::vector<IdString> &bel_to_cell; std::vector<IdString> &wire_to_net; @@ -739,8 +681,17 @@ private: std::unordered_map<IdString, int> &bel_by_name; std::unordered_map<IdString, int> &wire_by_name; std::unordered_map<IdString, int> &pip_by_name; + public: - ~ArchRWProxyMethods() {} + ArchMutateMethods(Arch *parent) : BaseMutateCtx(parent), parent_(parent), + chip_info(parent->chip_info), bel_to_cell(parent->bel_to_cell), + wire_to_net(parent->wire_to_net), pip_to_net(parent->pip_to_net), + switches_locked(parent->switches_locked), + bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), + pip_by_name(parent->pip_by_name) {} + ArchMutateMethods(ArchMutateMethods &&other) : ArchMutateMethods(other.parent_) {} + ArchMutateMethods(const ArchMutateMethods &other) : ArchMutateMethods(other.parent_) {} + ~ArchMutateMethods() {} void unbindWire(WireId wire); void unbindPip(PipId pip); @@ -750,33 +701,6 @@ public: void bindBel(BelId bel, IdString cell, PlaceStrength strength); // Returned pointer is valid as long as Proxy object exists. CellInfo *getCell(IdString cell); - - - // Methods to be used by UI for detecting whether we need to redraw. - UIUpdatesRequired getUIUpdatesRequired(void); -}; - -// A proxy object that keeps an Arch readwrite lock until it goes out of scope. -// All ArchRProxyMethods and ArchRWProxyMethods are available on it. -class ArchRWProxy : public ArchRProxyMethods, public ArchRWProxyMethods { - friend class Arch; -private: - boost::shared_mutex *lock_; - ArchRWProxy(Arch *parent) : ArchRProxyMethods(parent), ArchRWProxyMethods(parent), lock_(&parent->mtx_) { - lock_->lock(); - } - -public: - ArchRWProxy(ArchRWProxy &&other) : ArchRProxyMethods(other), ArchRWProxyMethods(other), lock_(other.lock_) - { - other.lock_ = nullptr; - } - ~ArchRWProxy() - { - if (lock_ != nullptr) { - lock_->unlock(); - } - } }; NEXTPNR_NAMESPACE_END diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc index cb7c44b8..42efceab 100644 --- a/ice40/arch_place.cc +++ b/ice40/arch_place.cc @@ -25,7 +25,7 @@ NEXTPNR_NAMESPACE_BEGIN -bool ArchRProxyMethods::logicCellsCompatible(const std::vector<const CellInfo *> &cells) const +bool ArchReadMethods::logicCellsCompatible(const std::vector<const CellInfo *> &cells) const { bool dffs_exist = false, dffs_neg = false; const NetInfo *cen = nullptr, *clk = nullptr, *sr = nullptr; @@ -76,7 +76,7 @@ bool ArchRProxyMethods::logicCellsCompatible(const std::vector<const CellInfo *> return locals_count <= 32; } -bool ArchRProxyMethods::isBelLocationValid(BelId bel) const +bool ArchReadMethods::isBelLocationValid(BelId bel) const { if (parent_->getBelType(bel) == TYPE_ICESTORM_LC) { std::vector<const CellInfo *> bel_cells; @@ -97,7 +97,7 @@ bool ArchRProxyMethods::isBelLocationValid(BelId bel) const } } -bool ArchRProxyMethods::isValidBelForCell(CellInfo *cell, BelId bel) const +bool ArchReadMethods::isValidBelForCell(CellInfo *cell, BelId bel) const { if (cell->type == parent_->id_icestorm_lc) { NPNR_ASSERT(parent_->getBelType(bel) == TYPE_ICESTORM_LC); diff --git a/ice40/place_legaliser.cc b/ice40/place_legaliser.cc index 10a6f3ff..fcb47cfd 100644 --- a/ice40/place_legaliser.cc +++ b/ice40/place_legaliser.cc @@ -253,7 +253,7 @@ class PlacementLegaliser } // Find Bel closest to a location, meeting chain requirements - std::tuple<int, int, int> find_closest_bel(ArchRWProxy &proxy, float target_x, float target_y, CellChain &chain) + std::tuple<int, int, int> find_closest_bel(MutateContext &proxy, float target_x, float target_y, CellChain &chain) { std::tuple<int, int, int> best_origin = std::make_tuple(-1, -1, -1); wirelen_t best_wirelength = std::numeric_limits<wirelen_t>::max(); @@ -283,7 +283,7 @@ class PlacementLegaliser } // Split a carry chain into multiple legal chains - std::vector<CellChain> split_carry_chain(const ArchRProxy &proxy, CellChain &carryc) + std::vector<CellChain> split_carry_chain(const ReadContext &proxy, CellChain &carryc) { bool start_of_chain = true; std::vector<CellChain> chains; @@ -335,7 +335,7 @@ class PlacementLegaliser } // Place a logic cell at a given grid location, handling rip-up etc - void place_lc(ArchRWProxy &proxy, CellInfo *cell, int x, int y, int z) + void place_lc(MutateContext &proxy, CellInfo *cell, int x, int y, int z) { auto &loc = logic_bels.at(x).at(y).at(z); NPNR_ASSERT(!loc.second); |