aboutsummaryrefslogtreecommitdiffstats
path: root/ice40
diff options
context:
space:
mode:
authorSergiusz Bazanski <q3k@q3k.org>2018-07-14 11:10:31 +0100
committerSergiusz Bazanski <q3k@q3k.org>2018-07-14 11:10:31 +0100
commit9b17fe385cf7e8d3025747b5f7c7822ac2d99920 (patch)
tree1822cebedf1e346defe28f0707de7332d45a92cc /ice40
parenta38b4fa1735bd0af78520f6d5320a264914fb838 (diff)
downloadnextpnr-9b17fe385cf7e8d3025747b5f7c7822ac2d99920.tar.gz
nextpnr-9b17fe385cf7e8d3025747b5f7c7822ac2d99920.tar.bz2
nextpnr-9b17fe385cf7e8d3025747b5f7c7822ac2d99920.zip
Refactor proxies to nextpnr.
Diffstat (limited to 'ice40')
-rw-r--r--ice40/arch.cc77
-rw-r--r--ice40/arch.h130
-rw-r--r--ice40/arch_place.cc6
-rw-r--r--ice40/place_legaliser.cc6
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);