aboutsummaryrefslogtreecommitdiffstats
path: root/ice40
diff options
context:
space:
mode:
authorSergiusz Bazanski <q3k@q3k.org>2018-07-13 19:45:35 +0100
committerSergiusz Bazanski <q3k@q3k.org>2018-07-13 19:45:35 +0100
commita71b576de6c404572439e30a56c4ff19497523a2 (patch)
tree383832a79b1b4e44ea0581dde7c8e0c7839c69d8 /ice40
parentdc3256e62fce923a3dc703c521bea5a13cef4443 (diff)
downloadnextpnr-a71b576de6c404572439e30a56c4ff19497523a2.tar.gz
nextpnr-a71b576de6c404572439e30a56c4ff19497523a2.tar.bz2
nextpnr-a71b576de6c404572439e30a56c4ff19497523a2.zip
Slight simplification of proxy code
Diffstat (limited to 'ice40')
-rw-r--r--ice40/arch.cc108
-rw-r--r--ice40/arch.h53
2 files changed, 93 insertions, 68 deletions
diff --git a/ice40/arch.cc b/ice40/arch.cc
index af31e147..af6e922c 100644
--- a/ice40/arch.cc
+++ b/ice40/arch.cc
@@ -736,19 +736,19 @@ bool Arch::isGlobalNet(const NetInfo *net) const
bool ArchRProxyMethods::checkBelAvail(BelId bel) const
{
NPNR_ASSERT(bel != BelId());
- return parent_->bel_to_cell[bel.index] == IdString();
+ return bel_to_cell[bel.index] == IdString();
}
IdString ArchRProxyMethods::getBoundBelCell(BelId bel) const
{
NPNR_ASSERT(bel != BelId());
- return parent_->bel_to_cell[bel.index];
+ return bel_to_cell[bel.index];
}
IdString ArchRProxyMethods::getConflictingBelCell(BelId bel) const
{
NPNR_ASSERT(bel != BelId());
- return parent_->bel_to_cell[bel.index];
+ return bel_to_cell[bel.index];
}
WireId ArchRProxyMethods::getWireBelPin(BelId bel, PortPin pin) const
@@ -757,8 +757,8 @@ WireId ArchRProxyMethods::getWireBelPin(BelId bel, PortPin pin) const
NPNR_ASSERT(bel != BelId());
- int num_bel_wires = parent_->chip_info->bel_data[bel.index].num_bel_wires;
- const BelWirePOD *bel_wires = parent_->chip_info->bel_data[bel.index].bel_wires.get();
+ int num_bel_wires = chip_info->bel_data[bel.index].num_bel_wires;
+ const BelWirePOD *bel_wires = chip_info->bel_data[bel.index].bel_wires.get();
for (int i = 0; i < num_bel_wires; i++)
if (bel_wires[i].port == pin) {
@@ -773,13 +773,13 @@ WireId ArchRProxyMethods::getWireByName(IdString name) const
{
WireId ret;
- if (parent_->wire_by_name.empty()) {
- for (int i = 0; i < parent_->chip_info->num_wires; i++)
- parent_->wire_by_name[parent_->id(parent_->chip_info->wire_data[i].name.get())] = i;
+ if (wire_by_name.empty()) {
+ for (int i = 0; i < chip_info->num_wires; i++)
+ wire_by_name[parent_->id(chip_info->wire_data[i].name.get())] = i;
}
- auto it = parent_->wire_by_name.find(name);
- if (it != parent_->wire_by_name.end())
+ auto it = wire_by_name.find(name);
+ if (it != wire_by_name.end())
ret.index = it->second;
return ret;
@@ -788,35 +788,35 @@ WireId ArchRProxyMethods::getWireByName(IdString name) const
bool ArchRProxyMethods::checkWireAvail(WireId wire) const
{
NPNR_ASSERT(wire != WireId());
- return parent_->wire_to_net[wire.index] == IdString();
+ return wire_to_net[wire.index] == IdString();
}
IdString ArchRProxyMethods::getBoundWireNet(WireId wire) const
{
NPNR_ASSERT(wire != WireId());
- return parent_->wire_to_net[wire.index];
+ return wire_to_net[wire.index];
}
IdString ArchRProxyMethods::getConflictingWireNet(WireId wire) const
{
NPNR_ASSERT(wire != WireId());
- return parent_->wire_to_net[wire.index];
+ return wire_to_net[wire.index];
}
PipId ArchRProxyMethods::getPipByName(IdString name) const
{
PipId ret;
- if (parent_->pip_by_name.empty()) {
- for (int i = 0; i < parent_->chip_info->num_pips; i++) {
+ if (pip_by_name.empty()) {
+ for (int i = 0; i < chip_info->num_pips; i++) {
PipId pip;
pip.index = i;
- parent_->pip_by_name[parent_->getPipName(pip)] = i;
+ pip_by_name[parent_->getPipName(pip)] = i;
}
}
- auto it = parent_->pip_by_name.find(name);
- if (it != parent_->pip_by_name.end())
+ auto it = pip_by_name.find(name);
+ if (it != pip_by_name.end())
ret.index = it->second;
return ret;
@@ -825,32 +825,32 @@ PipId ArchRProxyMethods::getPipByName(IdString name) const
bool ArchRProxyMethods::checkPipAvail(PipId pip) const
{
NPNR_ASSERT(pip != PipId());
- return parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] == IdString();
+ return switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString();
}
IdString ArchRProxyMethods::getBoundPipNet(PipId pip) const
{
NPNR_ASSERT(pip != PipId());
- return parent_->pip_to_net[pip.index];
+ return pip_to_net[pip.index];
}
IdString ArchRProxyMethods::getConflictingPipNet(PipId pip) const
{
NPNR_ASSERT(pip != PipId());
- return parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index];
+ return switches_locked[chip_info->pip_data[pip.index].switch_index];
}
BelId ArchRProxyMethods::getBelByName(IdString name) const
{
BelId ret;
- if (parent_->bel_by_name.empty()) {
- for (int i = 0; i < parent_->chip_info->num_bels; i++)
- parent_->bel_by_name[parent_->id(parent_->chip_info->bel_data[i].name.get())] = i;
+ if (bel_by_name.empty()) {
+ for (int i = 0; i < chip_info->num_bels; i++)
+ bel_by_name[parent_->id(chip_info->bel_data[i].name.get())] = i;
}
- auto it = parent_->bel_by_name.find(name);
- if (it != parent_->bel_by_name.end())
+ auto it = bel_by_name.find(name);
+ if (it != bel_by_name.end())
ret.index = it->second;
return ret;
@@ -861,8 +861,8 @@ BelId ArchRProxyMethods::getBelByName(IdString name) const
void ArchRWProxyMethods::bindBel(BelId bel, IdString cell, PlaceStrength strength)
{
NPNR_ASSERT(bel != BelId());
- NPNR_ASSERT(parent_->bel_to_cell[bel.index] == IdString());
- parent_->bel_to_cell[bel.index] = cell;
+ 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);
@@ -871,19 +871,19 @@ void ArchRWProxyMethods::bindBel(BelId bel, IdString cell, PlaceStrength strengt
void ArchRWProxyMethods::unbindBel(BelId bel)
{
NPNR_ASSERT(bel != BelId());
- NPNR_ASSERT(parent_->bel_to_cell[bel.index] != IdString());
- parent_->cells[parent_->bel_to_cell[bel.index]]->bel = BelId();
- parent_->cells[parent_->bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE;
- parent_->bel_to_cell[bel.index] = IdString();
+ 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);
}
void ArchRWProxyMethods::bindWire(WireId wire, IdString net, PlaceStrength strength)
{
NPNR_ASSERT(wire != WireId());
- NPNR_ASSERT(parent_->wire_to_net[wire.index] == IdString());
+ NPNR_ASSERT(wire_to_net[wire.index] == IdString());
- parent_->wire_to_net[wire.index] = net;
+ wire_to_net[wire.index] = net;
parent_->nets[net]->wires[wire].pip = PipId();
parent_->nets[net]->wires[wire].strength = strength;
parent_->refreshUiWire(wire);
@@ -892,37 +892,37 @@ void ArchRWProxyMethods::bindWire(WireId wire, IdString net, PlaceStrength stren
void ArchRWProxyMethods::unbindWire(WireId wire)
{
NPNR_ASSERT(wire != WireId());
- NPNR_ASSERT(parent_->wire_to_net[wire.index] != IdString());
+ NPNR_ASSERT(wire_to_net[wire.index] != IdString());
- auto &net_wires = parent_->nets[parent_->wire_to_net[wire.index]]->wires;
+ auto &net_wires = parent_->nets[wire_to_net[wire.index]]->wires;
auto it = net_wires.find(wire);
NPNR_ASSERT(it != net_wires.end());
auto pip = it->second.pip;
if (pip != PipId()) {
- parent_->pip_to_net[pip.index] = IdString();
- parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] = IdString();
+ pip_to_net[pip.index] = IdString();
+ switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString();
parent_->refreshUiPip(pip);
}
net_wires.erase(it);
- parent_->wire_to_net[wire.index] = IdString();
+ wire_to_net[wire.index] = IdString();
parent_->refreshUiWire(wire);
}
void ArchRWProxyMethods::bindPip(PipId pip, IdString net, PlaceStrength strength)
{
NPNR_ASSERT(pip != PipId());
- NPNR_ASSERT(parent_->pip_to_net[pip.index] == IdString());
- NPNR_ASSERT(parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] == IdString());
+ NPNR_ASSERT(pip_to_net[pip.index] == IdString());
+ NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString());
- parent_->pip_to_net[pip.index] = net;
- parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] = net;
+ pip_to_net[pip.index] = net;
+ switches_locked[chip_info->pip_data[pip.index].switch_index] = net;
WireId dst;
- dst.index = parent_->chip_info->pip_data[pip.index].dst;
- NPNR_ASSERT(parent_->wire_to_net[dst.index] == IdString());
- parent_->wire_to_net[dst.index] = net;
+ dst.index = chip_info->pip_data[pip.index].dst;
+ NPNR_ASSERT(wire_to_net[dst.index] == IdString());
+ wire_to_net[dst.index] = net;
parent_->nets[net]->wires[dst].pip = pip;
parent_->nets[net]->wires[dst].strength = strength;
@@ -933,17 +933,17 @@ void ArchRWProxyMethods::bindPip(PipId pip, IdString net, PlaceStrength strength
void ArchRWProxyMethods::unbindPip(PipId pip)
{
NPNR_ASSERT(pip != PipId());
- NPNR_ASSERT(parent_->pip_to_net[pip.index] != IdString());
- NPNR_ASSERT(parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] != IdString());
+ NPNR_ASSERT(pip_to_net[pip.index] != IdString());
+ NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] != IdString());
WireId dst;
- dst.index = parent_->chip_info->pip_data[pip.index].dst;
- NPNR_ASSERT(parent_->wire_to_net[dst.index] != IdString());
- parent_->wire_to_net[dst.index] = IdString();
- parent_->nets[parent_->pip_to_net[pip.index]]->wires.erase(dst);
+ dst.index = chip_info->pip_data[pip.index].dst;
+ NPNR_ASSERT(wire_to_net[dst.index] != IdString());
+ wire_to_net[dst.index] = IdString();
+ parent_->nets[pip_to_net[pip.index]]->wires.erase(dst);
- parent_->pip_to_net[pip.index] = IdString();
- parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] = IdString();
+ pip_to_net[pip.index] = IdString();
+ switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString();
parent_->refreshUiPip(pip);
parent_->refreshUiWire(dst);
diff --git a/ice40/arch.h b/ice40/arch.h
index 8428dc29..da1e583a 100644
--- a/ice40/arch.h
+++ b/ice40/arch.h
@@ -339,7 +339,7 @@ class ArchRProxy;
/// Arch/Context
// Arch is the main state class of the PnR algorithms. It keeps note of mapped
// cells/nets, locked switches, etc.
-//
+//
// In order to mutate state in Arch, you can do one of two things:
// - directly call one of the wrapper methods to mutate state
// - get a read or readwrite proxy to the Arch, and call methods on it
@@ -419,7 +419,7 @@ public:
IdString getBoundPipNet(PipId pip) const;
IdString getBoundBelCell(BelId bel) const;
BelId getBelByName(IdString name) const;
-
+
// -------------------------------------------------
/// Methods to get chip info - don't need to use a wrapper, as these are
@@ -506,7 +506,7 @@ public:
range.e.cursor = chip_info->num_pips;
return range;
}
-
+
IdString getPipName(PipId pip) const;
uint32_t getPipChecksum(PipId pip) const { return pip.index; }
@@ -640,13 +640,27 @@ class ArchRProxyMethods {
friend class ArchRWProxy;
private:
const Arch *parent_;
- ArchRProxyMethods(const Arch *parent) : parent_(parent) {}
- ArchRProxyMethods(ArchRProxyMethods &&other) noexcept : parent_(other.parent_) {}
- ArchRProxyMethods(const ArchRProxyMethods &other) : parent_(other.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;
+ const std::vector<IdString> &pip_to_net;
+ const std::vector<IdString> &switches_locked;
+ 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 { }
-
+
/// Perform placement validity checks, returning false on failure (all implemented in arch_place.cc)
// Whether or not a given cell can be placed at a given Bel
@@ -667,7 +681,7 @@ public:
WireId getWireByName(IdString name) const;
WireId getWireBelPin(BelId bel, PortPin pin) const;
PipId getPipByName(IdString name) const;
-
+
IdString getConflictingWireNet(WireId wire) const;
IdString getConflictingPipNet(PipId pip) const;
IdString getConflictingBelCell(BelId bel) const;
@@ -709,9 +723,22 @@ class ArchRWProxyMethods {
friend class ArchRWProxy;
private:
Arch *parent_;
- ArchRWProxyMethods(Arch *parent) : parent_(parent) {}
- ArchRWProxyMethods(ArchRWProxyMethods &&other) : parent_(other.parent_) {}
- ArchRWProxyMethods(const ArchRWProxyMethods &other) : parent_(other.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;
+ std::vector<IdString> &pip_to_net;
+ std::vector<IdString> &switches_locked;
+ 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() {}
@@ -746,8 +773,6 @@ public:
lock_->unlock();
}
}
-
-
};
NEXTPNR_NAMESPACE_END