From 3352ff4abbcac563e08d78ed8aa77728d00284a8 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 11:46:32 +0100 Subject: [PATCH] Move read methods to ReadMethods, remove some legacy access to Arch --- common/nextpnr.cc | 9 ++-- ecp5/arch.cc | 105 ++++++++++++++++++++++++++++++++++------- ecp5/arch.h | 92 ++---------------------------------- ecp5/arch_pybindings.h | 18 +++++-- ecp5/bitstream.cc | 5 +- gui/designwidget.cc | 26 +++++----- ice40/arch.h | 1 + ice40/picorv32.sh | 8 ++-- 8 files changed, 135 insertions(+), 129 deletions(-) diff --git a/common/nextpnr.cc b/common/nextpnr.cc index 33230db0..01c1397e 100644 --- a/common/nextpnr.cc +++ b/common/nextpnr.cc @@ -170,20 +170,21 @@ uint32_t Context::checksum() const void Context::check() const { + auto &&proxy = rproxy(); for (auto &n : nets) { auto ni = n.second.get(); NPNR_ASSERT(n.first == ni->name); for (auto &w : ni->wires) { - NPNR_ASSERT(n.first == getBoundWireNet(w.first)); + NPNR_ASSERT(n.first == proxy.getBoundWireNet(w.first)); if (w.second.pip != PipId()) { NPNR_ASSERT(w.first == getPipDstWire(w.second.pip)); - NPNR_ASSERT(n.first == getBoundPipNet(w.second.pip)); + NPNR_ASSERT(n.first == proxy.getBoundPipNet(w.second.pip)); } } } for (auto w : getWires()) { - IdString net = getBoundWireNet(w); + IdString net = proxy.getBoundWireNet(w); if (net != IdString()) { NPNR_ASSERT(nets.at(net)->wires.count(w)); } @@ -192,7 +193,7 @@ void Context::check() const for (auto &c : cells) { NPNR_ASSERT(c.first == c.second->name); if (c.second->bel != BelId()) - NPNR_ASSERT(getBoundBelCell(c.second->bel) == c.first); + NPNR_ASSERT(proxy.getBoundBelCell(c.second->bel) == c.first); for (auto &port : c.second->ports) { NetInfo *net = port.second.net; if (net != nullptr) { diff --git a/ecp5/arch.cc b/ecp5/arch.cc index 51f4db84..5c5689f0 100644 --- a/ecp5/arch.cc +++ b/ecp5/arch.cc @@ -151,7 +151,7 @@ IdString Arch::archArgsToId(ArchArgs args) const // ----------------------------------------------------------------------- -BelId Arch::getBelByName(IdString name) const +BelId ArchReadMethods::getBelByName(IdString name) const { BelId ret; auto it = bel_by_name.find(name); @@ -160,9 +160,9 @@ BelId Arch::getBelByName(IdString name) const Location loc; std::string basename; - std::tie(loc.x, loc.y, basename) = split_identifier_name(name.str(this)); + std::tie(loc.x, loc.y, basename) = split_identifier_name(name.str(parent_)); ret.location = loc; - const LocationTypePOD *loci = locInfo(ret); + const LocationTypePOD *loci = parent_->locInfo(ret); for (int i = 0; i < loci->num_bels; i++) { if (std::strcmp(loci->bel_data[i].name.get(), basename.c_str()) == 0) { ret.index = i; @@ -185,14 +185,14 @@ BelRange Arch::getBelsAtSameTile(BelId bel) const return br; } -WireId Arch::getWireBelPin(BelId bel, PortPin pin) const +WireId ArchReadMethods::getWireBelPin(BelId bel, PortPin pin) const { WireId ret; NPNR_ASSERT(bel != BelId()); - int num_bel_wires = locInfo(bel)->bel_data[bel.index].num_bel_wires; - const BelWirePOD *bel_wires = locInfo(bel)->bel_data[bel.index].bel_wires.get(); + int num_bel_wires = parent_->locInfo(bel)->bel_data[bel.index].num_bel_wires; + const BelWirePOD *bel_wires = parent_->locInfo(bel)->bel_data[bel.index].bel_wires.get(); for (int i = 0; i < num_bel_wires; i++) if (bel_wires[i].port == pin) { ret.location = bel.location + bel_wires[i].rel_wire_loc; @@ -205,7 +205,7 @@ WireId Arch::getWireBelPin(BelId bel, PortPin pin) const // ----------------------------------------------------------------------- -WireId Arch::getWireByName(IdString name) const +WireId ArchReadMethods::getWireByName(IdString name) const { WireId ret; auto it = wire_by_name.find(name); @@ -214,9 +214,9 @@ WireId Arch::getWireByName(IdString name) const Location loc; std::string basename; - std::tie(loc.x, loc.y, basename) = split_identifier_name(name.str(this)); + std::tie(loc.x, loc.y, basename) = split_identifier_name(name.str(parent_)); ret.location = loc; - const LocationTypePOD *loci = locInfo(ret); + const LocationTypePOD *loci = parent_->locInfo(ret); for (int i = 0; i < loci->num_wires; i++) { if (std::strcmp(loci->wire_data[i].name.get(), basename.c_str()) == 0) { ret.index = i; @@ -233,7 +233,7 @@ WireId Arch::getWireByName(IdString name) const // ----------------------------------------------------------------------- -PipId Arch::getPipByName(IdString name) const +PipId ArchReadMethods::getPipByName(IdString name) const { auto it = pip_by_name.find(name); if (it != pip_by_name.end()) @@ -242,13 +242,13 @@ PipId Arch::getPipByName(IdString name) const PipId ret; Location loc; std::string basename; - std::tie(loc.x, loc.y, basename) = split_identifier_name(name.str(this)); - const LocationTypePOD *loci = locInfo(ret); + std::tie(loc.x, loc.y, basename) = split_identifier_name(name.str(parent_)); + const LocationTypePOD *loci = parent_->locInfo(ret); for (int i = 0; i < loci->num_pips; i++) { PipId curr; curr.location = loc; curr.index = i; - pip_by_name[getPipName(curr)] = curr; + pip_by_name[parent_->getPipName(curr)] = curr; } return pip_by_name[name]; } @@ -296,7 +296,7 @@ bool Arch::route() { return router1(getCtx()); } // ----------------------------------------------------------------------- -std::vector Arch::getDecalGraphics(DecalId decalId) const +std::vector ArchReadMethods::getDecalGraphics(DecalId decalId) const { std::vector ret; // FIXME @@ -315,9 +315,9 @@ DecalXY Arch::getGroupDecal(GroupId pip) const { return {}; }; // ----------------------------------------------------------------------- -bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const { return true; } +bool ArchReadMethods::isValidBelForCell(CellInfo *cell, BelId bel) const { return true; } -bool Arch::isBelLocationValid(BelId bel) const { return true; } +bool ArchReadMethods::isBelLocationValid(BelId bel) const { return true; } // ----------------------------------------------------------------------- @@ -330,4 +330,77 @@ IdString Arch::getPortClock(const CellInfo *cell, IdString port) const { return bool Arch::isClockPort(const CellInfo *cell, IdString port) const { return false; } +bool ArchReadMethods::checkWireAvail(WireId wire) const +{ + NPNR_ASSERT(wire != WireId()); + return wire_to_net.find(wire) == wire_to_net.end() || wire_to_net.at(wire) == IdString(); +} + +bool ArchReadMethods::checkPipAvail(PipId pip) const +{ + NPNR_ASSERT(pip != PipId()); + return pip_to_net.find(pip) == pip_to_net.end() || pip_to_net.at(pip) == IdString(); +} + +bool ArchReadMethods::checkBelAvail(BelId bel) const +{ + NPNR_ASSERT(bel != BelId()); + return bel_to_cell.find(bel) == bel_to_cell.end() || bel_to_cell.at(bel) == IdString(); +} + +IdString ArchReadMethods::getConflictingBelCell(BelId bel) const +{ + NPNR_ASSERT(bel != BelId()); + if (bel_to_cell.find(bel) == bel_to_cell.end()) + return IdString(); + else + return bel_to_cell.at(bel); +} + +IdString ArchReadMethods::getConflictingWireNet(WireId wire) const +{ + NPNR_ASSERT(wire != WireId()); + if (wire_to_net.find(wire) == wire_to_net.end()) + return IdString(); + else + return wire_to_net.at(wire); +} + +IdString ArchReadMethods::getConflictingPipNet(PipId pip) const +{ + NPNR_ASSERT(pip != PipId()); + if (pip_to_net.find(pip) == pip_to_net.end()) + return IdString(); + else + return pip_to_net.at(pip); +} + +IdString ArchReadMethods::getBoundWireNet(WireId wire) const +{ + NPNR_ASSERT(wire != WireId()); + if (wire_to_net.find(wire) == wire_to_net.end()) + return IdString(); + else + return wire_to_net.at(wire); +} + +IdString ArchReadMethods::getBoundPipNet(PipId pip) const +{ + NPNR_ASSERT(pip != PipId()); + if (pip_to_net.find(pip) == pip_to_net.end()) + return IdString(); + else + return pip_to_net.at(pip); +} + +IdString ArchReadMethods::getBoundBelCell(BelId bel) const +{ + NPNR_ASSERT(bel != BelId()); + if (bel_to_cell.find(bel) == bel_to_cell.end()) + return IdString(); + else + return bel_to_cell.at(bel); +} + + NEXTPNR_NAMESPACE_END diff --git a/ecp5/arch.h b/ecp5/arch.h index 421a7738..50897b86 100644 --- a/ecp5/arch.h +++ b/ecp5/arch.h @@ -371,8 +371,6 @@ public: // ------------------------------------------------- - BelId getBelByName(IdString name) const; - template const LocationTypePOD *locInfo(Id &id) const { return &(chip_info->locations[chip_info->location_type[id.location.y * chip_info->width + id.location.x]]); @@ -406,30 +404,6 @@ public: bel_to_cell[bel] = IdString(); } - bool checkBelAvail(BelId bel) const - { - NPNR_ASSERT(bel != BelId()); - return bel_to_cell.find(bel) == bel_to_cell.end() || bel_to_cell.at(bel) == IdString(); - } - - IdString getBoundBelCell(BelId bel) const - { - NPNR_ASSERT(bel != BelId()); - if (bel_to_cell.find(bel) == bel_to_cell.end()) - return IdString(); - else - return bel_to_cell.at(bel); - } - - IdString getConflictingBelCell(BelId bel) const - { - NPNR_ASSERT(bel != BelId()); - if (bel_to_cell.find(bel) == bel_to_cell.end()) - return IdString(); - else - return bel_to_cell.at(bel); - } - BelRange getBels() const { BelRange range; @@ -465,8 +439,6 @@ public: return locInfo(bel)->bel_data[bel.index].type; } - WireId getWireBelPin(BelId bel, PortPin pin) const; - BelPin getBelPinUphill(WireId wire) const { BelPin ret; @@ -494,8 +466,6 @@ public: // ------------------------------------------------- - WireId getWireByName(IdString name) const; - IdString getWireName(WireId wire) const { NPNR_ASSERT(wire != WireId()); @@ -535,30 +505,6 @@ public: wire_to_net[wire] = IdString(); } - bool checkWireAvail(WireId wire) const - { - NPNR_ASSERT(wire != WireId()); - return wire_to_net.find(wire) == wire_to_net.end() || wire_to_net.at(wire) == IdString(); - } - - IdString getBoundWireNet(WireId wire) const - { - NPNR_ASSERT(wire != WireId()); - if (wire_to_net.find(wire) == wire_to_net.end()) - return IdString(); - else - return wire_to_net.at(wire); - } - - IdString getConflictingWireNet(WireId wire) const - { - NPNR_ASSERT(wire != WireId()); - if (wire_to_net.find(wire) == wire_to_net.end()) - return IdString(); - else - return wire_to_net.at(wire); - } - WireRange getWires() const { WireRange range; @@ -574,7 +520,6 @@ public: // ------------------------------------------------- - PipId getPipByName(IdString name) const; IdString getPipName(PipId pip) const; uint32_t getPipChecksum(PipId pip) const { return pip.index; } @@ -610,30 +555,6 @@ public: pip_to_net[pip] = IdString(); } - bool checkPipAvail(PipId pip) const - { - NPNR_ASSERT(pip != PipId()); - return pip_to_net.find(pip) == pip_to_net.end() || pip_to_net.at(pip) == IdString(); - } - - IdString getBoundPipNet(PipId pip) const - { - NPNR_ASSERT(pip != PipId()); - if (pip_to_net.find(pip) == pip_to_net.end()) - return IdString(); - else - return pip_to_net.at(pip); - } - - IdString getConflictingPipNet(PipId pip) const - { - NPNR_ASSERT(pip != PipId()); - if (pip_to_net.find(pip) == pip_to_net.end()) - return IdString(); - else - return pip_to_net.at(pip); - } - AllPipRange getPips() const { AllPipRange range; @@ -716,6 +637,7 @@ public: // ------------------------------------------------- + // TODO(q3k) move this to archproxies? GroupId getGroupByName(IdString name) const { return GroupId(); } IdString getGroupName(GroupId group) const { return IdString(); } std::vector getGroups() const { return std::vector(); } @@ -726,6 +648,8 @@ public: // ------------------------------------------------- + // These are also specific to the chip and not state, so they're available + // on arch directly. void estimatePosition(BelId bel, int &x, int &y, bool &gb) const; delay_t estimateDelay(WireId src, WireId dst) const; delay_t getDelayEpsilon() const { return 20; } @@ -741,8 +665,7 @@ public: // ------------------------------------------------- - std::vector getDecalGraphics(DecalId decal) const; - + // TODO(q3k) move this to archproxies? DecalXY getFrameDecal() const; DecalXY getBelDecal(BelId bel) const; DecalXY getWireDecal(WireId wire) const; @@ -760,11 +683,6 @@ public: bool isClockPort(const CellInfo *cell, IdString port) const; // Return true if a port is a net bool isGlobalNet(const NetInfo *net) const; - - // ------------------------------------------------- - // Placement validity checks - bool isValidBelForCell(CellInfo *cell, BelId bel) const; - bool isBelLocationValid(BelId bel) const; }; class ArchReadMethods : public BaseReadCtx @@ -800,8 +718,6 @@ class ArchReadMethods : public BaseReadCtx bool isValidBelForCell(CellInfo *cell, BelId bel) const; // Return true whether all Bels at a given location are valid bool isBelLocationValid(BelId bel) const; - // Helper function for above - bool logicCellsCompatible(const std::vector &cells) const; bool checkWireAvail(WireId wire) const; bool checkPipAvail(PipId pip) const; diff --git a/ecp5/arch_pybindings.h b/ecp5/arch_pybindings.h index a5044f29..6256af18 100644 --- a/ecp5/arch_pybindings.h +++ b/ecp5/arch_pybindings.h @@ -30,7 +30,11 @@ namespace PythonConversion { template <> struct string_converter { - BelId from_str(Context *ctx, std::string name) { return ctx->getBelByName(ctx->id(name)); } + BelId from_str(Context *ctx, std::string name) + { + auto &&proxy = ctx->rproxy(); + return proxy.getBelByName(ctx->id(name)); + } std::string to_str(Context *ctx, BelId id) { @@ -49,14 +53,22 @@ template <> struct string_converter template <> struct string_converter { - WireId from_str(Context *ctx, std::string name) { return ctx->getWireByName(ctx->id(name)); } + WireId from_str(Context *ctx, std::string name) + { + auto &&proxy = ctx->rproxy(); + return proxy.getWireByName(ctx->id(name)); + } std::string to_str(Context *ctx, WireId id) { return ctx->getWireName(id).str(ctx); } }; template <> struct string_converter { - PipId from_str(Context *ctx, std::string name) { return ctx->getPipByName(ctx->id(name)); } + PipId from_str(Context *ctx, std::string name) + { + auto &&proxy = ctx->rproxy(); + return proxy.getPipByName(ctx->id(name)); + } std::string to_str(Context *ctx, PipId id) { return ctx->getPipName(id).str(ctx); } }; diff --git a/ecp5/bitstream.cc b/ecp5/bitstream.cc index e70d6bb2..b2376391 100644 --- a/ecp5/bitstream.cc +++ b/ecp5/bitstream.cc @@ -155,6 +155,7 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex { Trellis::Chip empty_chip(ctx->getChipName()); Trellis::ChipConfig cc; + auto &&proxy = ctx->rproxy(); std::set cib_tiles = {"CIB", "CIB_LR", "CIB_LR_S", "CIB_EFB0", "CIB_EFB1"}; @@ -172,7 +173,7 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex // Add all set, configurable pips to the config for (auto pip : ctx->getPips()) { - if (ctx->getBoundPipNet(pip) != IdString()) { + if (proxy.getBoundPipNet(pip) != IdString()) { if (ctx->getPipType(pip) == 0) { // ignore fixed pips std::string tile = empty_chip.get_tile_by_position_and_type(pip.location.y, pip.location.x, ctx->getPipTiletype(pip)); @@ -227,7 +228,7 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex (ci->ports.find(ctx->id("T")) == ci->ports.end() || ci->ports.at(ctx->id("T")).net == nullptr)) { // Tie tristate low if unconnected for outputs or bidir std::string jpt = fmt_str("X" << bel.location.x << "/Y" << bel.location.y << "/JPADDT" << pio.back()); - WireId jpt_wire = ctx->getWireByName(ctx->id(jpt)); + WireId jpt_wire = proxy.getWireByName(ctx->id(jpt)); PipId jpt_pip = *ctx->getPipsUphill(jpt_wire).begin(); WireId cib_wire = ctx->getPipSrcWire(jpt_pip); std::string cib_tile = diff --git a/gui/designwidget.cc b/gui/designwidget.cc index 110cf1b7..e839f006 100644 --- a/gui/designwidget.cc +++ b/gui/designwidget.cc @@ -335,10 +335,12 @@ void DesignWidget::onItemClicked(QTreeWidgetItem *clickItem, int pos) return; } + auto &&proxy = ctx->rproxy(); + clearProperties(); if (type == ElementType::BEL) { IdString c = static_cast(clickItem)->getData(); - BelId bel = ctx->getBelByName(c); + BelId bel = proxy.getBelByName(c); QtProperty *topItem = groupManager->addProperty("Bel"); addProperty(topItem, "Bel"); @@ -352,20 +354,20 @@ void DesignWidget::onItemClicked(QTreeWidgetItem *clickItem, int pos) topItem->addSubProperty(typeItem); QtVariantProperty *availItem = readOnlyManager->addProperty(QVariant::Bool, "Available"); - availItem->setValue(ctx->checkBelAvail(bel)); + availItem->setValue(proxy.checkBelAvail(bel)); topItem->addSubProperty(availItem); QtVariantProperty *cellItem = readOnlyManager->addProperty(QVariant::String, "Bound Cell"); - cellItem->setValue(ctx->getBoundBelCell(bel).c_str(ctx)); + cellItem->setValue(proxy.getBoundBelCell(bel).c_str(ctx)); topItem->addSubProperty(cellItem); QtVariantProperty *conflictItem = readOnlyManager->addProperty(QVariant::String, "Conflicting Cell"); - conflictItem->setValue(ctx->getConflictingBelCell(bel).c_str(ctx)); + conflictItem->setValue(proxy.getConflictingBelCell(bel).c_str(ctx)); topItem->addSubProperty(conflictItem); } else if (type == ElementType::WIRE) { IdString c = static_cast(clickItem)->getData(); - WireId wire = ctx->getWireByName(c); + WireId wire = proxy.getWireByName(c); QtProperty *topItem = groupManager->addProperty("Wire"); addProperty(topItem, "Wire"); @@ -375,15 +377,15 @@ void DesignWidget::onItemClicked(QTreeWidgetItem *clickItem, int pos) topItem->addSubProperty(nameItem); QtVariantProperty *availItem = readOnlyManager->addProperty(QVariant::Bool, "Available"); - availItem->setValue(ctx->checkWireAvail(wire)); + availItem->setValue(proxy.checkWireAvail(wire)); topItem->addSubProperty(availItem); QtVariantProperty *cellItem = readOnlyManager->addProperty(QVariant::String, "Bound Net"); - cellItem->setValue(ctx->getBoundWireNet(wire).c_str(ctx)); + cellItem->setValue(proxy.getBoundWireNet(wire).c_str(ctx)); topItem->addSubProperty(cellItem); QtVariantProperty *conflictItem = readOnlyManager->addProperty(QVariant::String, "Conflicting Net"); - conflictItem->setValue(ctx->getConflictingWireNet(wire).c_str(ctx)); + conflictItem->setValue(proxy.getConflictingWireNet(wire).c_str(ctx)); topItem->addSubProperty(conflictItem); BelPin uphill = ctx->getBelPinUphill(wire); @@ -439,7 +441,7 @@ void DesignWidget::onItemClicked(QTreeWidgetItem *clickItem, int pos) } else if (type == ElementType::PIP) { IdString c = static_cast(clickItem)->getData(); - PipId pip = ctx->getPipByName(c); + PipId pip = proxy.getPipByName(c); QtProperty *topItem = groupManager->addProperty("Pip"); addProperty(topItem, "Pip"); @@ -449,15 +451,15 @@ void DesignWidget::onItemClicked(QTreeWidgetItem *clickItem, int pos) topItem->addSubProperty(nameItem); QtVariantProperty *availItem = readOnlyManager->addProperty(QVariant::Bool, "Available"); - availItem->setValue(ctx->checkPipAvail(pip)); + availItem->setValue(proxy.checkPipAvail(pip)); topItem->addSubProperty(availItem); QtVariantProperty *cellItem = readOnlyManager->addProperty(QVariant::String, "Bound Net"); - cellItem->setValue(ctx->getBoundPipNet(pip).c_str(ctx)); + cellItem->setValue(proxy.getBoundPipNet(pip).c_str(ctx)); topItem->addSubProperty(cellItem); QtVariantProperty *conflictItem = readOnlyManager->addProperty(QVariant::String, "Conflicting Net"); - conflictItem->setValue(ctx->getConflictingPipNet(pip).c_str(ctx)); + conflictItem->setValue(proxy.getConflictingPipNet(pip).c_str(ctx)); topItem->addSubProperty(conflictItem); QtVariantProperty *srcWireItem = readOnlyManager->addProperty(QVariant::String, "Src Wire"); diff --git a/ice40/arch.h b/ice40/arch.h index cdee92e4..ec1e456f 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -578,6 +578,7 @@ class Arch : public BaseCtx // ------------------------------------------------- + // TODO(q3k) move this to archproxies? DecalXY getFrameDecal() const; DecalXY getBelDecal(BelId bel) const; DecalXY getWireDecal(WireId wire) const; diff --git a/ice40/picorv32.sh b/ice40/picorv32.sh index 2c67f641..0518db83 100755 --- a/ice40/picorv32.sh +++ b/ice40/picorv32.sh @@ -1,6 +1,6 @@ #!/bin/bash set -ex -rm -f picorv32.v -wget https://raw.githubusercontent.com/cliffordwolf/picorv32/master/picorv32.v -yosys -p 'synth_ice40 -nocarry -json picorv32.json -top top' picorv32.v picorv32_top.v -../nextpnr-ice40 --hx8k --asc picorv32.asc --json picorv32.json +#rm -f picorv32.v +#wget https://raw.githubusercontent.com/cliffordwolf/picorv32/master/picorv32.v +#yosys -p 'synth_ice40 -nocarry -json picorv32.json -top top' picorv32.v picorv32_top.v +CPUPROFILE=../profile ../nextpnr-ice40 --hx8k --asc picorv32.asc --json picorv32.json