From 0adde4aede134f5ed37d1fc0f081a7eaf325c7ee Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Thu, 28 Jan 2021 02:14:34 -0500 Subject: machxo2: Implement 4 more Wire/Pip API functions. --- machxo2/arch.cc | 24 ------------- machxo2/arch.h | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 94 insertions(+), 32 deletions(-) diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 9ac4f3ae..0f1a0670 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -300,18 +300,6 @@ WireId Arch::getWireByName(IdString name) const return ret; } -uint32_t Arch::getWireChecksum(WireId wire) const -{ - // FIXME - return 0; -} - -void Arch::bindWire(WireId wire, NetInfo *net, PlaceStrength strength) {} - -void Arch::unbindWire(WireId wire) {} - -bool Arch::checkWireAvail(WireId wire) const { return false; } - NetInfo *Arch::getBoundWireNet(WireId wire) const { return nullptr; } NetInfo *Arch::getConflictingWireNet(WireId wire) const { return nullptr; } @@ -363,18 +351,6 @@ IdString Arch::getPipName(PipId pip) const return id("X" + std::to_string(x) + "/Y" + std::to_string(y) + "/" + src_name + ".->." + dst_name); } -uint32_t Arch::getPipChecksum(PipId wire) const -{ - // FIXME - return 0; -} - -void Arch::bindPip(PipId pip, NetInfo *net, PlaceStrength strength) {} - -void Arch::unbindPip(PipId pip) {} - -bool Arch::checkPipAvail(PipId pip) const { return false; } - NetInfo *Arch::getBoundPipNet(PipId pip) const { return nullptr; } NetInfo *Arch::getConflictingPipNet(PipId pip) const { return nullptr; } diff --git a/machxo2/arch.h b/machxo2/arch.h index e645f225..b87d622c 100644 --- a/machxo2/arch.h +++ b/machxo2/arch.h @@ -463,6 +463,9 @@ struct Arch : BaseCtx const PackageInfoPOD *package_info; std::vector bel_to_cell; + std::unordered_map wire_to_net; + std::unordered_map pip_to_net; + mutable std::unordered_map bel_by_name; mutable std::unordered_map wire_by_name; mutable std::unordered_map pip_by_name; @@ -635,10 +638,50 @@ struct Arch : BaseCtx return ret; } - uint32_t getWireChecksum(WireId wire) const; - void bindWire(WireId wire, NetInfo *net, PlaceStrength strength); - void unbindWire(WireId wire); - bool checkWireAvail(WireId wire) const; + uint32_t getWireChecksum(WireId wire) const { return wire.index; } + + void bindWire(WireId wire, NetInfo *net, PlaceStrength strength) + { + NPNR_ASSERT(wire != WireId()); + NPNR_ASSERT(wire_to_net[wire] == nullptr); + wire_to_net[wire] = net; + + // Needs to be set; bindWires is meant for source wires attached + // to a Bel. + net->wires[wire].pip = PipId(); + net->wires[wire].strength = strength; + refreshUiWire(wire); + } + + void unbindWire(WireId wire) + { + NPNR_ASSERT(wire != WireId()); + NPNR_ASSERT(wire_to_net[wire] != nullptr); + + auto &net_wires = wire_to_net[wire]->wires; + auto it = net_wires.find(wire); + NPNR_ASSERT(it != net_wires.end()); + + // If we have unbound a wire, then the upstream pip is no longer + // used either. + auto pip = it->second.pip; + if (pip != PipId()) { + // TODO: fanout + // 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; + } + NetInfo *getBoundWireNet(WireId wire) const; WireId getConflictingWireWire(WireId wire) const { return wire; } NetInfo *getConflictingWireNet(WireId wire) const; @@ -658,10 +701,53 @@ struct Arch : BaseCtx return ret; } - uint32_t getPipChecksum(PipId pip) const; - void bindPip(PipId pip, NetInfo *net, PlaceStrength strength); - void unbindPip(PipId pip); - bool checkPipAvail(PipId pip) const; + 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 = tileInfo(pip)->pips_data[pip.index].dst_idx; + dst.location = pip.location + tileInfo(pip)->pips_data[pip.index].dst; + NPNR_ASSERT(wire_to_net[dst] == nullptr); + + // Since NetInfo::wires holds info about uphill pips, bind info about + // this pip to the downhill wire. + wire_to_net[dst] = net; + net->wires[dst].pip = pip; + net->wires[dst].strength = strength; + } + + void unbindPip(PipId pip) + { + NPNR_ASSERT(pip != PipId()); + NPNR_ASSERT(pip_to_net[pip] == nullptr); + + // wire_fanout[getPipSrcWire(pip)]--; + + WireId dst; + dst.index = tileInfo(pip)->pips_data[pip.index].dst_idx; + dst.location = pip.location + tileInfo(pip)->pips_data[pip.index].dst; + NPNR_ASSERT(wire_to_net[dst] != nullptr); + + // If we unbind a pip, then the downstream wire is no longer in use + // either. + wire_to_net[dst] = nullptr; + pip_to_net[pip]->wires.erase(dst); + pip_to_net[pip] = nullptr; + } + + 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; WireId getConflictingPipWire(PipId pip) const; NetInfo *getConflictingPipNet(PipId pip) const; -- cgit v1.2.3