From 510969ab9704865f87c7c0bd09e0185b729feffc Mon Sep 17 00:00:00 2001 From: gatecat Date: Thu, 11 Feb 2021 11:10:32 +0000 Subject: Create machxo2 backend (renamed from generic). Signed-off-by: William D. Jones --- machxo2/arch.cc | 730 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 730 insertions(+) create mode 100644 machxo2/arch.cc (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc new file mode 100644 index 00000000..6979673a --- /dev/null +++ b/machxo2/arch.cc @@ -0,0 +1,730 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 Clifford Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include +#include +#include "nextpnr.h" +#include "placer1.h" +#include "placer_heap.h" +#include "router1.h" +#include "router2.h" +#include "util.h" + +NEXTPNR_NAMESPACE_BEGIN + +WireInfo &Arch::wire_info(IdString wire) +{ + auto w = wires.find(wire); + if (w == wires.end()) + NPNR_ASSERT_FALSE_STR("no wire named " + wire.str(this)); + return w->second; +} + +PipInfo &Arch::pip_info(IdString pip) +{ + auto p = pips.find(pip); + if (p == pips.end()) + NPNR_ASSERT_FALSE_STR("no pip named " + pip.str(this)); + return p->second; +} + +BelInfo &Arch::bel_info(IdString bel) +{ + auto b = bels.find(bel); + if (b == bels.end()) + NPNR_ASSERT_FALSE_STR("no bel named " + bel.str(this)); + return b->second; +} + +void Arch::addWire(IdString name, IdString type, int x, int y) +{ + NPNR_ASSERT(wires.count(name) == 0); + WireInfo &wi = wires[name]; + wi.name = name; + wi.type = type; + wi.x = x; + wi.y = y; + + wire_ids.push_back(name); +} + +void Arch::addPip(IdString name, IdString type, IdString srcWire, IdString dstWire, DelayInfo delay, Loc loc) +{ + NPNR_ASSERT(pips.count(name) == 0); + PipInfo &pi = pips[name]; + pi.name = name; + pi.type = type; + pi.srcWire = srcWire; + pi.dstWire = dstWire; + pi.delay = delay; + pi.loc = loc; + + wire_info(srcWire).downhill.push_back(name); + wire_info(dstWire).uphill.push_back(name); + pip_ids.push_back(name); + + if (int(tilePipDimZ.size()) <= loc.x) + tilePipDimZ.resize(loc.x + 1); + + if (int(tilePipDimZ[loc.x].size()) <= loc.y) + tilePipDimZ[loc.x].resize(loc.y + 1); + + gridDimX = std::max(gridDimX, loc.x + 1); + gridDimY = std::max(gridDimY, loc.x + 1); + tilePipDimZ[loc.x][loc.y] = std::max(tilePipDimZ[loc.x][loc.y], loc.z + 1); +} + +void Arch::addAlias(IdString name, IdString type, IdString srcWire, IdString dstWire, DelayInfo delay) +{ + NPNR_ASSERT(pips.count(name) == 0); + PipInfo &pi = pips[name]; + pi.name = name; + pi.type = type; + pi.srcWire = srcWire; + pi.dstWire = dstWire; + pi.delay = delay; + + wire_info(srcWire).aliases.push_back(name); + pip_ids.push_back(name); +} + +void Arch::addBel(IdString name, IdString type, Loc loc, bool gb) +{ + NPNR_ASSERT(bels.count(name) == 0); + NPNR_ASSERT(bel_by_loc.count(loc) == 0); + BelInfo &bi = bels[name]; + bi.name = name; + bi.type = type; + bi.x = loc.x; + bi.y = loc.y; + bi.z = loc.z; + bi.gb = gb; + + bel_ids.push_back(name); + bel_by_loc[loc] = name; + + if (int(bels_by_tile.size()) <= loc.x) + bels_by_tile.resize(loc.x + 1); + + if (int(bels_by_tile[loc.x].size()) <= loc.y) + bels_by_tile[loc.x].resize(loc.y + 1); + + bels_by_tile[loc.x][loc.y].push_back(name); + + if (int(tileBelDimZ.size()) <= loc.x) + tileBelDimZ.resize(loc.x + 1); + + if (int(tileBelDimZ[loc.x].size()) <= loc.y) + tileBelDimZ[loc.x].resize(loc.y + 1); + + gridDimX = std::max(gridDimX, loc.x + 1); + gridDimY = std::max(gridDimY, loc.x + 1); + tileBelDimZ[loc.x][loc.y] = std::max(tileBelDimZ[loc.x][loc.y], loc.z + 1); +} + +void Arch::addBelInput(IdString bel, IdString name, IdString wire) +{ + NPNR_ASSERT(bel_info(bel).pins.count(name) == 0); + PinInfo &pi = bel_info(bel).pins[name]; + pi.name = name; + pi.wire = wire; + pi.type = PORT_IN; + + wire_info(wire).downhill_bel_pins.push_back(BelPin{bel, name}); + wire_info(wire).bel_pins.push_back(BelPin{bel, name}); +} + +void Arch::addBelOutput(IdString bel, IdString name, IdString wire) +{ + NPNR_ASSERT(bel_info(bel).pins.count(name) == 0); + PinInfo &pi = bel_info(bel).pins[name]; + pi.name = name; + pi.wire = wire; + pi.type = PORT_OUT; + + wire_info(wire).uphill_bel_pin = BelPin{bel, name}; + wire_info(wire).bel_pins.push_back(BelPin{bel, name}); +} + +void Arch::addBelInout(IdString bel, IdString name, IdString wire) +{ + NPNR_ASSERT(bel_info(bel).pins.count(name) == 0); + PinInfo &pi = bel_info(bel).pins[name]; + pi.name = name; + pi.wire = wire; + pi.type = PORT_INOUT; + + wire_info(wire).downhill_bel_pins.push_back(BelPin{bel, name}); + wire_info(wire).bel_pins.push_back(BelPin{bel, name}); +} + +void Arch::addGroupBel(IdString group, IdString bel) { groups[group].bels.push_back(bel); } + +void Arch::addGroupWire(IdString group, IdString wire) { groups[group].wires.push_back(wire); } + +void Arch::addGroupPip(IdString group, IdString pip) { groups[group].pips.push_back(pip); } + +void Arch::addGroupGroup(IdString group, IdString grp) { groups[group].groups.push_back(grp); } + +void Arch::addDecalGraphic(DecalId decal, const GraphicElement &graphic) +{ + decal_graphics[decal].push_back(graphic); + refreshUi(); +} + +void Arch::setWireDecal(WireId wire, DecalXY decalxy) +{ + wire_info(wire).decalxy = decalxy; + refreshUiWire(wire); +} + +void Arch::setPipDecal(PipId pip, DecalXY decalxy) +{ + pip_info(pip).decalxy = decalxy; + refreshUiPip(pip); +} + +void Arch::setBelDecal(BelId bel, DecalXY decalxy) +{ + bel_info(bel).decalxy = decalxy; + refreshUiBel(bel); +} + +void Arch::setGroupDecal(GroupId group, DecalXY decalxy) +{ + groups[group].decalxy = decalxy; + refreshUiGroup(group); +} + +void Arch::setWireAttr(IdString wire, IdString key, const std::string &value) { wire_info(wire).attrs[key] = value; } + +void Arch::setPipAttr(IdString pip, IdString key, const std::string &value) { pip_info(pip).attrs[key] = value; } + +void Arch::setBelAttr(IdString bel, IdString key, const std::string &value) { bel_info(bel).attrs[key] = value; } + +void Arch::setLutK(int K) { args.K = K; } + +void Arch::setDelayScaling(double scale, double offset) +{ + args.delayScale = scale; + args.delayOffset = offset; +} + +void Arch::addCellTimingClock(IdString cell, IdString port) { cellTiming[cell].portClasses[port] = TMG_CLOCK_INPUT; } + +void Arch::addCellTimingDelay(IdString cell, IdString fromPort, IdString toPort, DelayInfo delay) +{ + if (get_or_default(cellTiming[cell].portClasses, fromPort, TMG_IGNORE) == TMG_IGNORE) + cellTiming[cell].portClasses[fromPort] = TMG_COMB_INPUT; + if (get_or_default(cellTiming[cell].portClasses, toPort, TMG_IGNORE) == TMG_IGNORE) + cellTiming[cell].portClasses[toPort] = TMG_COMB_OUTPUT; + cellTiming[cell].combDelays[CellDelayKey{fromPort, toPort}] = delay; +} + +void Arch::addCellTimingSetupHold(IdString cell, IdString port, IdString clock, DelayInfo setup, DelayInfo hold) +{ + TimingClockingInfo ci; + ci.clock_port = clock; + ci.edge = RISING_EDGE; + ci.setup = setup; + ci.hold = hold; + cellTiming[cell].clockingInfo[port].push_back(ci); + cellTiming[cell].portClasses[port] = TMG_REGISTER_INPUT; +} + +void Arch::addCellTimingClockToOut(IdString cell, IdString port, IdString clock, DelayInfo clktoq) +{ + TimingClockingInfo ci; + ci.clock_port = clock; + ci.edge = RISING_EDGE; + ci.clockToQ = clktoq; + cellTiming[cell].clockingInfo[port].push_back(ci); + cellTiming[cell].portClasses[port] = TMG_REGISTER_OUTPUT; +} + +// --------------------------------------------------------------- + +Arch::Arch(ArchArgs args) : chipName("generic"), args(args) +{ + // Dummy for empty decals + decal_graphics[IdString()]; +} + +void IdString::initialize_arch(const BaseCtx *ctx) {} + +// --------------------------------------------------------------- + +BelId Arch::getBelByName(IdString name) const +{ + if (bels.count(name)) + return name; + return BelId(); +} + +IdString Arch::getBelName(BelId bel) const { return bel; } + +Loc Arch::getBelLocation(BelId bel) const +{ + auto &info = bels.at(bel); + return Loc(info.x, info.y, info.z); +} + +BelId Arch::getBelByLocation(Loc loc) const +{ + auto it = bel_by_loc.find(loc); + if (it != bel_by_loc.end()) + return it->second; + return BelId(); +} + +const std::vector &Arch::getBelsByTile(int x, int y) const { return bels_by_tile.at(x).at(y); } + +bool Arch::getBelGlobalBuf(BelId bel) const { return bels.at(bel).gb; } + +uint32_t Arch::getBelChecksum(BelId bel) const +{ + // FIXME + return 0; +} + +void Arch::bindBel(BelId bel, CellInfo *cell, PlaceStrength strength) +{ + bels.at(bel).bound_cell = cell; + cell->bel = bel; + cell->belStrength = strength; + refreshUiBel(bel); +} + +void Arch::unbindBel(BelId bel) +{ + bels.at(bel).bound_cell->bel = BelId(); + bels.at(bel).bound_cell->belStrength = STRENGTH_NONE; + bels.at(bel).bound_cell = nullptr; + refreshUiBel(bel); +} + +bool Arch::checkBelAvail(BelId bel) const { return bels.at(bel).bound_cell == nullptr; } + +CellInfo *Arch::getBoundBelCell(BelId bel) const { return bels.at(bel).bound_cell; } + +CellInfo *Arch::getConflictingBelCell(BelId bel) const { return bels.at(bel).bound_cell; } + +const std::vector &Arch::getBels() const { return bel_ids; } + +IdString Arch::getBelType(BelId bel) const { return bels.at(bel).type; } + +const std::map &Arch::getBelAttrs(BelId bel) const { return bels.at(bel).attrs; } + +WireId Arch::getBelPinWire(BelId bel, IdString pin) const +{ + const auto &bdata = bels.at(bel); + if (!bdata.pins.count(pin)) + log_error("bel '%s' has no pin '%s'\n", bel.c_str(this), pin.c_str(this)); + return bdata.pins.at(pin).wire; +} + +PortType Arch::getBelPinType(BelId bel, IdString pin) const { return bels.at(bel).pins.at(pin).type; } + +std::vector Arch::getBelPins(BelId bel) const +{ + std::vector ret; + for (auto &it : bels.at(bel).pins) + ret.push_back(it.first); + return ret; +} + +// --------------------------------------------------------------- + +WireId Arch::getWireByName(IdString name) const +{ + if (wires.count(name)) + return name; + return WireId(); +} + +IdString Arch::getWireName(WireId wire) const { return wire; } + +IdString Arch::getWireType(WireId wire) const { return wires.at(wire).type; } + +const std::map &Arch::getWireAttrs(WireId wire) const { return wires.at(wire).attrs; } + +uint32_t Arch::getWireChecksum(WireId wire) const +{ + // FIXME + return 0; +} + +void Arch::bindWire(WireId wire, NetInfo *net, PlaceStrength strength) +{ + wires.at(wire).bound_net = net; + net->wires[wire].pip = PipId(); + net->wires[wire].strength = strength; + refreshUiWire(wire); +} + +void Arch::unbindWire(WireId wire) +{ + auto &net_wires = wires.at(wire).bound_net->wires; + + auto pip = net_wires.at(wire).pip; + if (pip != PipId()) { + pips.at(pip).bound_net = nullptr; + refreshUiPip(pip); + } + + net_wires.erase(wire); + wires.at(wire).bound_net = nullptr; + refreshUiWire(wire); +} + +bool Arch::checkWireAvail(WireId wire) const { return wires.at(wire).bound_net == nullptr; } + +NetInfo *Arch::getBoundWireNet(WireId wire) const { return wires.at(wire).bound_net; } + +NetInfo *Arch::getConflictingWireNet(WireId wire) const { return wires.at(wire).bound_net; } + +const std::vector &Arch::getWireBelPins(WireId wire) const { return wires.at(wire).bel_pins; } + +const std::vector &Arch::getWires() const { return wire_ids; } + +// --------------------------------------------------------------- + +PipId Arch::getPipByName(IdString name) const +{ + if (pips.count(name)) + return name; + return PipId(); +} + +IdString Arch::getPipName(PipId pip) const { return pip; } + +IdString Arch::getPipType(PipId pip) const { return pips.at(pip).type; } + +const std::map &Arch::getPipAttrs(PipId pip) const { return pips.at(pip).attrs; } + +uint32_t Arch::getPipChecksum(PipId wire) const +{ + // FIXME + return 0; +} + +void Arch::bindPip(PipId pip, NetInfo *net, PlaceStrength strength) +{ + WireId wire = pips.at(pip).dstWire; + pips.at(pip).bound_net = net; + wires.at(wire).bound_net = net; + net->wires[wire].pip = pip; + net->wires[wire].strength = strength; + refreshUiPip(pip); + refreshUiWire(wire); +} + +void Arch::unbindPip(PipId pip) +{ + WireId wire = pips.at(pip).dstWire; + wires.at(wire).bound_net->wires.erase(wire); + pips.at(pip).bound_net = nullptr; + wires.at(wire).bound_net = nullptr; + refreshUiPip(pip); + refreshUiWire(wire); +} + +bool Arch::checkPipAvail(PipId pip) const { return pips.at(pip).bound_net == nullptr; } + +NetInfo *Arch::getBoundPipNet(PipId pip) const { return pips.at(pip).bound_net; } + +NetInfo *Arch::getConflictingPipNet(PipId pip) const { return pips.at(pip).bound_net; } + +WireId Arch::getConflictingPipWire(PipId pip) const { return pips.at(pip).bound_net ? pips.at(pip).dstWire : WireId(); } + +const std::vector &Arch::getPips() const { return pip_ids; } + +Loc Arch::getPipLocation(PipId pip) const { return pips.at(pip).loc; } + +WireId Arch::getPipSrcWire(PipId pip) const { return pips.at(pip).srcWire; } + +WireId Arch::getPipDstWire(PipId pip) const { return pips.at(pip).dstWire; } + +DelayInfo Arch::getPipDelay(PipId pip) const { return pips.at(pip).delay; } + +const std::vector &Arch::getPipsDownhill(WireId wire) const { return wires.at(wire).downhill; } + +const std::vector &Arch::getPipsUphill(WireId wire) const { return wires.at(wire).uphill; } + +const std::vector &Arch::getWireAliases(WireId wire) const { return wires.at(wire).aliases; } + +// --------------------------------------------------------------- + +GroupId Arch::getGroupByName(IdString name) const { return name; } + +IdString Arch::getGroupName(GroupId group) const { return group; } + +std::vector Arch::getGroups() const +{ + std::vector ret; + for (auto &it : groups) + ret.push_back(it.first); + return ret; +} + +const std::vector &Arch::getGroupBels(GroupId group) const { return groups.at(group).bels; } + +const std::vector &Arch::getGroupWires(GroupId group) const { return groups.at(group).wires; } + +const std::vector &Arch::getGroupPips(GroupId group) const { return groups.at(group).pips; } + +const std::vector &Arch::getGroupGroups(GroupId group) const { return groups.at(group).groups; } + +// --------------------------------------------------------------- + +delay_t Arch::estimateDelay(WireId src, WireId dst) const +{ + const WireInfo &s = wires.at(src); + const WireInfo &d = wires.at(dst); + int dx = abs(s.x - d.x); + int dy = abs(s.y - d.y); + return (dx + dy) * args.delayScale + args.delayOffset; +} + +delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const +{ + const auto &driver = net_info->driver; + auto driver_loc = getBelLocation(driver.cell->bel); + auto sink_loc = getBelLocation(sink.cell->bel); + + int dx = abs(sink_loc.x - driver_loc.x); + int dy = abs(sink_loc.y - driver_loc.y); + return (dx + dy) * args.delayScale + args.delayOffset; +} + +bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const { return false; } + +ArcBounds Arch::getRouteBoundingBox(WireId src, WireId dst) const +{ + ArcBounds bb; + + int src_x = wires.at(src).x; + int src_y = wires.at(src).y; + int dst_x = wires.at(dst).x; + int dst_y = wires.at(dst).y; + + bb.x0 = src_x; + bb.y0 = src_y; + bb.x1 = src_x; + bb.y1 = src_y; + + auto extend = [&](int x, int y) { + bb.x0 = std::min(bb.x0, x); + bb.x1 = std::max(bb.x1, x); + bb.y0 = std::min(bb.y0, y); + bb.y1 = std::max(bb.y1, y); + }; + extend(dst_x, dst_y); + return bb; +} + +// --------------------------------------------------------------- + +bool Arch::place() +{ + std::string placer = str_or_default(settings, id("placer"), defaultPlacer); + if (placer == "heap") { + bool have_iobuf_or_constr = false; + for (auto cell : sorted(cells)) { + CellInfo *ci = cell.second; + if (ci->type == id("GENERIC_IOB") || ci->bel != BelId() || ci->attrs.count(id("BEL"))) { + have_iobuf_or_constr = true; + break; + } + } + bool retVal; + if (!have_iobuf_or_constr) { + log_warning("Unable to use HeAP due to a lack of IO buffers or constrained cells as anchors; reverting to " + "SA.\n"); + retVal = placer1(getCtx(), Placer1Cfg(getCtx())); + } else { + PlacerHeapCfg cfg(getCtx()); + cfg.ioBufTypes.insert(id("GENERIC_IOB")); + retVal = placer_heap(getCtx(), cfg); + } + getCtx()->settings[getCtx()->id("place")] = 1; + archInfoToAttributes(); + return retVal; + } else if (placer == "sa") { + bool retVal = placer1(getCtx(), Placer1Cfg(getCtx())); + getCtx()->settings[getCtx()->id("place")] = 1; + archInfoToAttributes(); + return retVal; + } else { + log_error("Generic architecture does not support placer '%s'\n", placer.c_str()); + } +} + +bool Arch::route() +{ + std::string router = str_or_default(settings, id("router"), defaultRouter); + bool result; + if (router == "router1") { + result = router1(getCtx(), Router1Cfg(getCtx())); + } else if (router == "router2") { + router2(getCtx(), Router2Cfg(getCtx())); + result = true; + } else { + log_error("iCE40 architecture does not support router '%s'\n", router.c_str()); + } + getCtx()->settings[getCtx()->id("route")] = 1; + archInfoToAttributes(); + return result; +} + +// --------------------------------------------------------------- + +const std::vector &Arch::getDecalGraphics(DecalId decal) const +{ + if (!decal_graphics.count(decal)) { + std::cerr << "No decal named " << decal.str(this) << std::endl; + log_error("No decal named %s!\n", decal.c_str(this)); + } + return decal_graphics.at(decal); +} + +DecalXY Arch::getBelDecal(BelId bel) const { return bels.at(bel).decalxy; } + +DecalXY Arch::getWireDecal(WireId wire) const { return wires.at(wire).decalxy; } + +DecalXY Arch::getPipDecal(PipId pip) const { return pips.at(pip).decalxy; } + +DecalXY Arch::getGroupDecal(GroupId group) const { return groups.at(group).decalxy; } + +// --------------------------------------------------------------- + +bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const +{ + if (!cellTiming.count(cell->name)) + return false; + const auto &tmg = cellTiming.at(cell->name); + auto fnd = tmg.combDelays.find(CellDelayKey{fromPort, toPort}); + if (fnd != tmg.combDelays.end()) { + delay = fnd->second; + return true; + } else { + return false; + } +} + +// Get the port class, also setting clockPort if applicable +TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const +{ + if (!cellTiming.count(cell->name)) + return TMG_IGNORE; + const auto &tmg = cellTiming.at(cell->name); + if (tmg.clockingInfo.count(port)) + clockInfoCount = int(tmg.clockingInfo.at(port).size()); + else + clockInfoCount = 0; + return get_or_default(tmg.portClasses, port, TMG_IGNORE); +} + +TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port, int index) const +{ + NPNR_ASSERT(cellTiming.count(cell->name)); + const auto &tmg = cellTiming.at(cell->name); + NPNR_ASSERT(tmg.clockingInfo.count(port)); + return tmg.clockingInfo.at(port).at(index); +} + +bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const +{ + std::vector cells; + cells.push_back(cell); + Loc loc = getBelLocation(bel); + for (auto tbel : getBelsByTile(loc.x, loc.y)) { + if (tbel == bel) + continue; + CellInfo *bound = getBoundBelCell(tbel); + if (bound != nullptr) + cells.push_back(bound); + } + return cellsCompatible(cells.data(), int(cells.size())); +} + +bool Arch::isBelLocationValid(BelId bel) const +{ + std::vector cells; + Loc loc = getBelLocation(bel); + for (auto tbel : getBelsByTile(loc.x, loc.y)) { + CellInfo *bound = getBoundBelCell(tbel); + if (bound != nullptr) + cells.push_back(bound); + } + return cellsCompatible(cells.data(), int(cells.size())); +} + +#ifdef WITH_HEAP +const std::string Arch::defaultPlacer = "heap"; +#else +const std::string Arch::defaultPlacer = "sa"; +#endif + +const std::vector Arch::availablePlacers = {"sa", +#ifdef WITH_HEAP + "heap" +#endif +}; + +const std::string Arch::defaultRouter = "router1"; +const std::vector Arch::availableRouters = {"router1", "router2"}; + +void Arch::assignArchInfo() +{ + for (auto &cell : getCtx()->cells) { + CellInfo *ci = cell.second.get(); + if (ci->type == id("GENERIC_SLICE")) { + ci->is_slice = true; + ci->slice_clk = get_net_or_empty(ci, id("CLK")); + } else { + ci->is_slice = false; + } + ci->user_group = int_or_default(ci->attrs, id("PACK_GROUP"), -1); + } +} + +bool Arch::cellsCompatible(const CellInfo **cells, int count) const +{ + const NetInfo *clk = nullptr; + int group = -1; + for (int i = 0; i < count; i++) { + const CellInfo *ci = cells[i]; + if (ci->is_slice && ci->slice_clk != nullptr) { + if (clk == nullptr) + clk = ci->slice_clk; + else if (clk != ci->slice_clk) + return false; + } + if (ci->user_group != -1) { + if (group == -1) + group = ci->user_group; + else if (group != ci->user_group) + return false; + } + } + return true; +} + +NEXTPNR_NAMESPACE_END -- cgit v1.2.3 From 98214865bef10f675b864dec4e1ae35bbd22c76f Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sat, 27 Jun 2020 18:00:53 -0400 Subject: machxo2: Remove generic API functions from Arch. --- machxo2/arch.cc | 230 -------------------------------------------------------- 1 file changed, 230 deletions(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 6979673a..56899ced 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -28,236 +28,6 @@ NEXTPNR_NAMESPACE_BEGIN -WireInfo &Arch::wire_info(IdString wire) -{ - auto w = wires.find(wire); - if (w == wires.end()) - NPNR_ASSERT_FALSE_STR("no wire named " + wire.str(this)); - return w->second; -} - -PipInfo &Arch::pip_info(IdString pip) -{ - auto p = pips.find(pip); - if (p == pips.end()) - NPNR_ASSERT_FALSE_STR("no pip named " + pip.str(this)); - return p->second; -} - -BelInfo &Arch::bel_info(IdString bel) -{ - auto b = bels.find(bel); - if (b == bels.end()) - NPNR_ASSERT_FALSE_STR("no bel named " + bel.str(this)); - return b->second; -} - -void Arch::addWire(IdString name, IdString type, int x, int y) -{ - NPNR_ASSERT(wires.count(name) == 0); - WireInfo &wi = wires[name]; - wi.name = name; - wi.type = type; - wi.x = x; - wi.y = y; - - wire_ids.push_back(name); -} - -void Arch::addPip(IdString name, IdString type, IdString srcWire, IdString dstWire, DelayInfo delay, Loc loc) -{ - NPNR_ASSERT(pips.count(name) == 0); - PipInfo &pi = pips[name]; - pi.name = name; - pi.type = type; - pi.srcWire = srcWire; - pi.dstWire = dstWire; - pi.delay = delay; - pi.loc = loc; - - wire_info(srcWire).downhill.push_back(name); - wire_info(dstWire).uphill.push_back(name); - pip_ids.push_back(name); - - if (int(tilePipDimZ.size()) <= loc.x) - tilePipDimZ.resize(loc.x + 1); - - if (int(tilePipDimZ[loc.x].size()) <= loc.y) - tilePipDimZ[loc.x].resize(loc.y + 1); - - gridDimX = std::max(gridDimX, loc.x + 1); - gridDimY = std::max(gridDimY, loc.x + 1); - tilePipDimZ[loc.x][loc.y] = std::max(tilePipDimZ[loc.x][loc.y], loc.z + 1); -} - -void Arch::addAlias(IdString name, IdString type, IdString srcWire, IdString dstWire, DelayInfo delay) -{ - NPNR_ASSERT(pips.count(name) == 0); - PipInfo &pi = pips[name]; - pi.name = name; - pi.type = type; - pi.srcWire = srcWire; - pi.dstWire = dstWire; - pi.delay = delay; - - wire_info(srcWire).aliases.push_back(name); - pip_ids.push_back(name); -} - -void Arch::addBel(IdString name, IdString type, Loc loc, bool gb) -{ - NPNR_ASSERT(bels.count(name) == 0); - NPNR_ASSERT(bel_by_loc.count(loc) == 0); - BelInfo &bi = bels[name]; - bi.name = name; - bi.type = type; - bi.x = loc.x; - bi.y = loc.y; - bi.z = loc.z; - bi.gb = gb; - - bel_ids.push_back(name); - bel_by_loc[loc] = name; - - if (int(bels_by_tile.size()) <= loc.x) - bels_by_tile.resize(loc.x + 1); - - if (int(bels_by_tile[loc.x].size()) <= loc.y) - bels_by_tile[loc.x].resize(loc.y + 1); - - bels_by_tile[loc.x][loc.y].push_back(name); - - if (int(tileBelDimZ.size()) <= loc.x) - tileBelDimZ.resize(loc.x + 1); - - if (int(tileBelDimZ[loc.x].size()) <= loc.y) - tileBelDimZ[loc.x].resize(loc.y + 1); - - gridDimX = std::max(gridDimX, loc.x + 1); - gridDimY = std::max(gridDimY, loc.x + 1); - tileBelDimZ[loc.x][loc.y] = std::max(tileBelDimZ[loc.x][loc.y], loc.z + 1); -} - -void Arch::addBelInput(IdString bel, IdString name, IdString wire) -{ - NPNR_ASSERT(bel_info(bel).pins.count(name) == 0); - PinInfo &pi = bel_info(bel).pins[name]; - pi.name = name; - pi.wire = wire; - pi.type = PORT_IN; - - wire_info(wire).downhill_bel_pins.push_back(BelPin{bel, name}); - wire_info(wire).bel_pins.push_back(BelPin{bel, name}); -} - -void Arch::addBelOutput(IdString bel, IdString name, IdString wire) -{ - NPNR_ASSERT(bel_info(bel).pins.count(name) == 0); - PinInfo &pi = bel_info(bel).pins[name]; - pi.name = name; - pi.wire = wire; - pi.type = PORT_OUT; - - wire_info(wire).uphill_bel_pin = BelPin{bel, name}; - wire_info(wire).bel_pins.push_back(BelPin{bel, name}); -} - -void Arch::addBelInout(IdString bel, IdString name, IdString wire) -{ - NPNR_ASSERT(bel_info(bel).pins.count(name) == 0); - PinInfo &pi = bel_info(bel).pins[name]; - pi.name = name; - pi.wire = wire; - pi.type = PORT_INOUT; - - wire_info(wire).downhill_bel_pins.push_back(BelPin{bel, name}); - wire_info(wire).bel_pins.push_back(BelPin{bel, name}); -} - -void Arch::addGroupBel(IdString group, IdString bel) { groups[group].bels.push_back(bel); } - -void Arch::addGroupWire(IdString group, IdString wire) { groups[group].wires.push_back(wire); } - -void Arch::addGroupPip(IdString group, IdString pip) { groups[group].pips.push_back(pip); } - -void Arch::addGroupGroup(IdString group, IdString grp) { groups[group].groups.push_back(grp); } - -void Arch::addDecalGraphic(DecalId decal, const GraphicElement &graphic) -{ - decal_graphics[decal].push_back(graphic); - refreshUi(); -} - -void Arch::setWireDecal(WireId wire, DecalXY decalxy) -{ - wire_info(wire).decalxy = decalxy; - refreshUiWire(wire); -} - -void Arch::setPipDecal(PipId pip, DecalXY decalxy) -{ - pip_info(pip).decalxy = decalxy; - refreshUiPip(pip); -} - -void Arch::setBelDecal(BelId bel, DecalXY decalxy) -{ - bel_info(bel).decalxy = decalxy; - refreshUiBel(bel); -} - -void Arch::setGroupDecal(GroupId group, DecalXY decalxy) -{ - groups[group].decalxy = decalxy; - refreshUiGroup(group); -} - -void Arch::setWireAttr(IdString wire, IdString key, const std::string &value) { wire_info(wire).attrs[key] = value; } - -void Arch::setPipAttr(IdString pip, IdString key, const std::string &value) { pip_info(pip).attrs[key] = value; } - -void Arch::setBelAttr(IdString bel, IdString key, const std::string &value) { bel_info(bel).attrs[key] = value; } - -void Arch::setLutK(int K) { args.K = K; } - -void Arch::setDelayScaling(double scale, double offset) -{ - args.delayScale = scale; - args.delayOffset = offset; -} - -void Arch::addCellTimingClock(IdString cell, IdString port) { cellTiming[cell].portClasses[port] = TMG_CLOCK_INPUT; } - -void Arch::addCellTimingDelay(IdString cell, IdString fromPort, IdString toPort, DelayInfo delay) -{ - if (get_or_default(cellTiming[cell].portClasses, fromPort, TMG_IGNORE) == TMG_IGNORE) - cellTiming[cell].portClasses[fromPort] = TMG_COMB_INPUT; - if (get_or_default(cellTiming[cell].portClasses, toPort, TMG_IGNORE) == TMG_IGNORE) - cellTiming[cell].portClasses[toPort] = TMG_COMB_OUTPUT; - cellTiming[cell].combDelays[CellDelayKey{fromPort, toPort}] = delay; -} - -void Arch::addCellTimingSetupHold(IdString cell, IdString port, IdString clock, DelayInfo setup, DelayInfo hold) -{ - TimingClockingInfo ci; - ci.clock_port = clock; - ci.edge = RISING_EDGE; - ci.setup = setup; - ci.hold = hold; - cellTiming[cell].clockingInfo[port].push_back(ci); - cellTiming[cell].portClasses[port] = TMG_REGISTER_INPUT; -} - -void Arch::addCellTimingClockToOut(IdString cell, IdString port, IdString clock, DelayInfo clktoq) -{ - TimingClockingInfo ci; - ci.clock_port = clock; - ci.edge = RISING_EDGE; - ci.clockToQ = clktoq; - cellTiming[cell].clockingInfo[port].push_back(ci); - cellTiming[cell].portClasses[port] = TMG_REGISTER_OUTPUT; -} - // --------------------------------------------------------------- Arch::Arch(ArchArgs args) : chipName("generic"), args(args) -- cgit v1.2.3 From 9704f422dcae5788d39edf35addd6ee5e9dfd428 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sat, 27 Jun 2020 19:22:58 -0400 Subject: machxo2: Start creating MachXO2CommandHandler. --- machxo2/arch.cc | 54 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 13 deletions(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 56899ced..70de80cf 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -20,6 +20,7 @@ #include #include #include "nextpnr.h" +#include "embed.h" #include "placer1.h" #include "placer_heap.h" #include "router1.h" @@ -36,7 +37,44 @@ Arch::Arch(ArchArgs args) : chipName("generic"), args(args) decal_graphics[IdString()]; } -void IdString::initialize_arch(const BaseCtx *ctx) {} +// ----------------------------------------------------------------------- + +void IdString::initialize_arch(const BaseCtx *ctx) { + #define X(t) initialize_add(ctx, #t, ID_##t); + + #include "constids.inc" + + #undef X +} + +// --------------------------------------------------------------- + +static const ChipInfoPOD *get_chip_info(ArchArgs::ArchArgsTypes chip) +{ + std::string chipdb; + if (chip == ArchArgs::LCMXO2_256HC) { + chipdb = "machxo2/chipdb-256.bin"; + } else if (chip == ArchArgs::LCMXO2_640HC) { + chipdb = "machxo2/chipdb-640.bin"; + } else if (chip == ArchArgs::LCMXO2_1200HC) { + chipdb = "machxo2/chipdb-1200.bin"; + } else if (chip == ArchArgs::LCMXO2_2000HC) { + chipdb = "machxo2/chipdb-2000.bin"; + } else if (chip == ArchArgs::LCMXO2_4000HC) { + chipdb = "machxo2/chipdb-4000.bin"; + } else if (chip == ArchArgs::LCMXO2_7000HC) { + chipdb = "machxo2/chipdb-7000.bin"; + } else { + log_error("Unknown chip\n"); + } + + auto ptr = reinterpret_cast *>(get_chipdb(chipdb)); + if (ptr == nullptr) + return nullptr; + return ptr->get(); +} + +bool Arch::isAvailable(ArchArgs::ArchArgsTypes chip) { return get_chip_info(chip) != nullptr; } // --------------------------------------------------------------- @@ -265,22 +303,12 @@ const std::vector &Arch::getGroupGroups(GroupId group) const { return g delay_t Arch::estimateDelay(WireId src, WireId dst) const { - const WireInfo &s = wires.at(src); - const WireInfo &d = wires.at(dst); - int dx = abs(s.x - d.x); - int dy = abs(s.y - d.y); - return (dx + dy) * args.delayScale + args.delayOffset; + return 0; } delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const { - const auto &driver = net_info->driver; - auto driver_loc = getBelLocation(driver.cell->bel); - auto sink_loc = getBelLocation(sink.cell->bel); - - int dx = abs(sink_loc.x - driver_loc.x); - int dy = abs(sink_loc.y - driver_loc.y); - return (dx + dy) * args.delayScale + args.delayOffset; + return 0; } bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const { return false; } -- cgit v1.2.3 From 512daf2c897e84738684566188c86024ae5abe8c Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sat, 27 Jun 2020 19:43:16 -0400 Subject: machxo2: Remove generic packing. --- machxo2/arch.cc | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 70de80cf..ed62ed37 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -491,16 +491,7 @@ const std::vector Arch::availableRouters = {"router1", "router2"}; void Arch::assignArchInfo() { - for (auto &cell : getCtx()->cells) { - CellInfo *ci = cell.second.get(); - if (ci->type == id("GENERIC_SLICE")) { - ci->is_slice = true; - ci->slice_clk = get_net_or_empty(ci, id("CLK")); - } else { - ci->is_slice = false; - } - ci->user_group = int_or_default(ci->attrs, id("PACK_GROUP"), -1); - } + } bool Arch::cellsCompatible(const CellInfo **cells, int count) const -- cgit v1.2.3 From e5576448eaf9817163c45d0e8778e64b9b205c26 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sat, 27 Jun 2020 20:22:00 -0400 Subject: machxo2: Remove HeAP placer for now, fix typos. --- machxo2/arch.cc | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index ed62ed37..0b6b448e 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -342,35 +342,13 @@ ArcBounds Arch::getRouteBoundingBox(WireId src, WireId dst) const bool Arch::place() { std::string placer = str_or_default(settings, id("placer"), defaultPlacer); - if (placer == "heap") { - bool have_iobuf_or_constr = false; - for (auto cell : sorted(cells)) { - CellInfo *ci = cell.second; - if (ci->type == id("GENERIC_IOB") || ci->bel != BelId() || ci->attrs.count(id("BEL"))) { - have_iobuf_or_constr = true; - break; - } - } - bool retVal; - if (!have_iobuf_or_constr) { - log_warning("Unable to use HeAP due to a lack of IO buffers or constrained cells as anchors; reverting to " - "SA.\n"); - retVal = placer1(getCtx(), Placer1Cfg(getCtx())); - } else { - PlacerHeapCfg cfg(getCtx()); - cfg.ioBufTypes.insert(id("GENERIC_IOB")); - retVal = placer_heap(getCtx(), cfg); - } - getCtx()->settings[getCtx()->id("place")] = 1; - archInfoToAttributes(); - return retVal; - } else if (placer == "sa") { + if (placer == "sa") { bool retVal = placer1(getCtx(), Placer1Cfg(getCtx())); getCtx()->settings[getCtx()->id("place")] = 1; archInfoToAttributes(); return retVal; } else { - log_error("Generic architecture does not support placer '%s'\n", placer.c_str()); + log_error("MachXO2 architecture does not support placer '%s'\n", placer.c_str()); } } @@ -384,7 +362,7 @@ bool Arch::route() router2(getCtx(), Router2Cfg(getCtx())); result = true; } else { - log_error("iCE40 architecture does not support router '%s'\n", router.c_str()); + log_error("MachXO2 architecture does not support router '%s'\n", router.c_str()); } getCtx()->settings[getCtx()->id("route")] = 1; archInfoToAttributes(); -- cgit v1.2.3 From 88b7dfce58479f3002e5ba6d71856eeecfa41893 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sat, 27 Jun 2020 21:52:03 -0400 Subject: machxo2: Stub out arch API functions and members. --- machxo2/arch.cc | 235 ++++++++++++++------------------------------------------ 1 file changed, 57 insertions(+), 178 deletions(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 0b6b448e..5d1cb0cb 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -34,7 +34,7 @@ NEXTPNR_NAMESPACE_BEGIN Arch::Arch(ArchArgs args) : chipName("generic"), args(args) { // Dummy for empty decals - decal_graphics[IdString()]; + // decal_graphics[IdString()]; } // ----------------------------------------------------------------------- @@ -80,8 +80,6 @@ bool Arch::isAvailable(ArchArgs::ArchArgsTypes chip) { return get_chip_info(chip BelId Arch::getBelByName(IdString name) const { - if (bels.count(name)) - return name; return BelId(); } @@ -89,21 +87,17 @@ IdString Arch::getBelName(BelId bel) const { return bel; } Loc Arch::getBelLocation(BelId bel) const { - auto &info = bels.at(bel); - return Loc(info.x, info.y, info.z); + return Loc(); } BelId Arch::getBelByLocation(Loc loc) const { - auto it = bel_by_loc.find(loc); - if (it != bel_by_loc.end()) - return it->second; return BelId(); } -const std::vector &Arch::getBelsByTile(int x, int y) const { return bels_by_tile.at(x).at(y); } +const std::vector &Arch::getBelsByTile(int x, int y) const { return bel_id_dummy; } -bool Arch::getBelGlobalBuf(BelId bel) const { return bels.at(bel).gb; } +bool Arch::getBelGlobalBuf(BelId bel) const { return false; } uint32_t Arch::getBelChecksum(BelId bel) const { @@ -113,47 +107,36 @@ uint32_t Arch::getBelChecksum(BelId bel) const void Arch::bindBel(BelId bel, CellInfo *cell, PlaceStrength strength) { - bels.at(bel).bound_cell = cell; - cell->bel = bel; - cell->belStrength = strength; - refreshUiBel(bel); + } void Arch::unbindBel(BelId bel) { - bels.at(bel).bound_cell->bel = BelId(); - bels.at(bel).bound_cell->belStrength = STRENGTH_NONE; - bels.at(bel).bound_cell = nullptr; - refreshUiBel(bel); + } -bool Arch::checkBelAvail(BelId bel) const { return bels.at(bel).bound_cell == nullptr; } +bool Arch::checkBelAvail(BelId bel) const { return false; } -CellInfo *Arch::getBoundBelCell(BelId bel) const { return bels.at(bel).bound_cell; } +CellInfo *Arch::getBoundBelCell(BelId bel) const { return nullptr; } -CellInfo *Arch::getConflictingBelCell(BelId bel) const { return bels.at(bel).bound_cell; } +CellInfo *Arch::getConflictingBelCell(BelId bel) const { return nullptr; } -const std::vector &Arch::getBels() const { return bel_ids; } +const std::vector &Arch::getBels() const { return bel_id_dummy; } -IdString Arch::getBelType(BelId bel) const { return bels.at(bel).type; } +IdString Arch::getBelType(BelId bel) const { return IdString(); } -const std::map &Arch::getBelAttrs(BelId bel) const { return bels.at(bel).attrs; } +const std::map &Arch::getBelAttrs(BelId bel) const { return attrs_dummy; } WireId Arch::getBelPinWire(BelId bel, IdString pin) const { - const auto &bdata = bels.at(bel); - if (!bdata.pins.count(pin)) - log_error("bel '%s' has no pin '%s'\n", bel.c_str(this), pin.c_str(this)); - return bdata.pins.at(pin).wire; + return WireId(); } -PortType Arch::getBelPinType(BelId bel, IdString pin) const { return bels.at(bel).pins.at(pin).type; } +PortType Arch::getBelPinType(BelId bel, IdString pin) const { return PortType(); } std::vector Arch::getBelPins(BelId bel) const { std::vector ret; - for (auto &it : bels.at(bel).pins) - ret.push_back(it.first); return ret; } @@ -161,16 +144,14 @@ std::vector Arch::getBelPins(BelId bel) const WireId Arch::getWireByName(IdString name) const { - if (wires.count(name)) - return name; return WireId(); } -IdString Arch::getWireName(WireId wire) const { return wire; } +IdString Arch::getWireName(WireId wire) const { return IdString(); } -IdString Arch::getWireType(WireId wire) const { return wires.at(wire).type; } +IdString Arch::getWireType(WireId wire) const { return IdString(); } -const std::map &Arch::getWireAttrs(WireId wire) const { return wires.at(wire).attrs; } +const std::map &Arch::getWireAttrs(WireId wire) const { return attrs_dummy; } uint32_t Arch::getWireChecksum(WireId wire) const { @@ -180,51 +161,36 @@ uint32_t Arch::getWireChecksum(WireId wire) const void Arch::bindWire(WireId wire, NetInfo *net, PlaceStrength strength) { - wires.at(wire).bound_net = net; - net->wires[wire].pip = PipId(); - net->wires[wire].strength = strength; - refreshUiWire(wire); + } void Arch::unbindWire(WireId wire) { - auto &net_wires = wires.at(wire).bound_net->wires; - auto pip = net_wires.at(wire).pip; - if (pip != PipId()) { - pips.at(pip).bound_net = nullptr; - refreshUiPip(pip); - } - - net_wires.erase(wire); - wires.at(wire).bound_net = nullptr; - refreshUiWire(wire); } -bool Arch::checkWireAvail(WireId wire) const { return wires.at(wire).bound_net == nullptr; } +bool Arch::checkWireAvail(WireId wire) const { return false; } -NetInfo *Arch::getBoundWireNet(WireId wire) const { return wires.at(wire).bound_net; } +NetInfo *Arch::getBoundWireNet(WireId wire) const { return nullptr; } -NetInfo *Arch::getConflictingWireNet(WireId wire) const { return wires.at(wire).bound_net; } +NetInfo *Arch::getConflictingWireNet(WireId wire) const { return nullptr; } -const std::vector &Arch::getWireBelPins(WireId wire) const { return wires.at(wire).bel_pins; } +const std::vector &Arch::getWireBelPins(WireId wire) const { return bel_pin_dummy; } -const std::vector &Arch::getWires() const { return wire_ids; } +const std::vector &Arch::getWires() const { return wire_id_dummy; } // --------------------------------------------------------------- PipId Arch::getPipByName(IdString name) const { - if (pips.count(name)) - return name; return PipId(); } -IdString Arch::getPipName(PipId pip) const { return pip; } +IdString Arch::getPipName(PipId pip) const { return IdString(); } -IdString Arch::getPipType(PipId pip) const { return pips.at(pip).type; } +IdString Arch::getPipType(PipId pip) const { return IdString(); } -const std::map &Arch::getPipAttrs(PipId pip) const { return pips.at(pip).attrs; } +const std::map &Arch::getPipAttrs(PipId pip) const { return attrs_dummy; } uint32_t Arch::getPipChecksum(PipId wire) const { @@ -234,70 +200,57 @@ uint32_t Arch::getPipChecksum(PipId wire) const void Arch::bindPip(PipId pip, NetInfo *net, PlaceStrength strength) { - WireId wire = pips.at(pip).dstWire; - pips.at(pip).bound_net = net; - wires.at(wire).bound_net = net; - net->wires[wire].pip = pip; - net->wires[wire].strength = strength; - refreshUiPip(pip); - refreshUiWire(wire); + } void Arch::unbindPip(PipId pip) { - WireId wire = pips.at(pip).dstWire; - wires.at(wire).bound_net->wires.erase(wire); - pips.at(pip).bound_net = nullptr; - wires.at(wire).bound_net = nullptr; - refreshUiPip(pip); - refreshUiWire(wire); + } -bool Arch::checkPipAvail(PipId pip) const { return pips.at(pip).bound_net == nullptr; } +bool Arch::checkPipAvail(PipId pip) const { return false; } -NetInfo *Arch::getBoundPipNet(PipId pip) const { return pips.at(pip).bound_net; } +NetInfo *Arch::getBoundPipNet(PipId pip) const { return nullptr; } -NetInfo *Arch::getConflictingPipNet(PipId pip) const { return pips.at(pip).bound_net; } +NetInfo *Arch::getConflictingPipNet(PipId pip) const { return nullptr; } -WireId Arch::getConflictingPipWire(PipId pip) const { return pips.at(pip).bound_net ? pips.at(pip).dstWire : WireId(); } +WireId Arch::getConflictingPipWire(PipId pip) const { return WireId(); } -const std::vector &Arch::getPips() const { return pip_ids; } +const std::vector &Arch::getPips() const { return pip_id_dummy; } -Loc Arch::getPipLocation(PipId pip) const { return pips.at(pip).loc; } +Loc Arch::getPipLocation(PipId pip) const { return Loc(); } -WireId Arch::getPipSrcWire(PipId pip) const { return pips.at(pip).srcWire; } +WireId Arch::getPipSrcWire(PipId pip) const { return WireId(); } -WireId Arch::getPipDstWire(PipId pip) const { return pips.at(pip).dstWire; } +WireId Arch::getPipDstWire(PipId pip) const { return WireId(); } -DelayInfo Arch::getPipDelay(PipId pip) const { return pips.at(pip).delay; } +DelayInfo Arch::getPipDelay(PipId pip) const { return DelayInfo(); } -const std::vector &Arch::getPipsDownhill(WireId wire) const { return wires.at(wire).downhill; } +const std::vector &Arch::getPipsDownhill(WireId wire) const { return pip_id_dummy; } -const std::vector &Arch::getPipsUphill(WireId wire) const { return wires.at(wire).uphill; } +const std::vector &Arch::getPipsUphill(WireId wire) const { return pip_id_dummy; } -const std::vector &Arch::getWireAliases(WireId wire) const { return wires.at(wire).aliases; } +const std::vector &Arch::getWireAliases(WireId wire) const { return pip_id_dummy; } // --------------------------------------------------------------- -GroupId Arch::getGroupByName(IdString name) const { return name; } +GroupId Arch::getGroupByName(IdString name) const { return GroupId(); } -IdString Arch::getGroupName(GroupId group) const { return group; } +IdString Arch::getGroupName(GroupId group) const { return IdString(); } std::vector Arch::getGroups() const { std::vector ret; - for (auto &it : groups) - ret.push_back(it.first); return ret; } -const std::vector &Arch::getGroupBels(GroupId group) const { return groups.at(group).bels; } +const std::vector &Arch::getGroupBels(GroupId group) const { return bel_id_dummy; } -const std::vector &Arch::getGroupWires(GroupId group) const { return groups.at(group).wires; } +const std::vector &Arch::getGroupWires(GroupId group) const { return wire_id_dummy; } -const std::vector &Arch::getGroupPips(GroupId group) const { return groups.at(group).pips; } +const std::vector &Arch::getGroupPips(GroupId group) const { return pip_id_dummy; } -const std::vector &Arch::getGroupGroups(GroupId group) const { return groups.at(group).groups; } +const std::vector &Arch::getGroupGroups(GroupId group) const { return group_id_dummy; } // --------------------------------------------------------------- @@ -317,23 +270,6 @@ ArcBounds Arch::getRouteBoundingBox(WireId src, WireId dst) const { ArcBounds bb; - int src_x = wires.at(src).x; - int src_y = wires.at(src).y; - int dst_x = wires.at(dst).x; - int dst_y = wires.at(dst).y; - - bb.x0 = src_x; - bb.y0 = src_y; - bb.x1 = src_x; - bb.y1 = src_y; - - auto extend = [&](int x, int y) { - bb.x0 = std::min(bb.x0, x); - bb.x1 = std::max(bb.x1, x); - bb.y0 = std::min(bb.y0, y); - bb.y1 = std::max(bb.y1, y); - }; - extend(dst_x, dst_y); return bb; } @@ -373,83 +309,43 @@ bool Arch::route() const std::vector &Arch::getDecalGraphics(DecalId decal) const { - if (!decal_graphics.count(decal)) { - std::cerr << "No decal named " << decal.str(this) << std::endl; - log_error("No decal named %s!\n", decal.c_str(this)); - } - return decal_graphics.at(decal); + return graphic_element_dummy; } -DecalXY Arch::getBelDecal(BelId bel) const { return bels.at(bel).decalxy; } +DecalXY Arch::getBelDecal(BelId bel) const { return DecalXY(); } -DecalXY Arch::getWireDecal(WireId wire) const { return wires.at(wire).decalxy; } +DecalXY Arch::getWireDecal(WireId wire) const { return DecalXY(); } -DecalXY Arch::getPipDecal(PipId pip) const { return pips.at(pip).decalxy; } +DecalXY Arch::getPipDecal(PipId pip) const { return DecalXY(); } -DecalXY Arch::getGroupDecal(GroupId group) const { return groups.at(group).decalxy; } +DecalXY Arch::getGroupDecal(GroupId group) const { return DecalXY(); } // --------------------------------------------------------------- bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const { - if (!cellTiming.count(cell->name)) - return false; - const auto &tmg = cellTiming.at(cell->name); - auto fnd = tmg.combDelays.find(CellDelayKey{fromPort, toPort}); - if (fnd != tmg.combDelays.end()) { - delay = fnd->second; - return true; - } else { - return false; - } + return false; } // Get the port class, also setting clockPort if applicable TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const { - if (!cellTiming.count(cell->name)) - return TMG_IGNORE; - const auto &tmg = cellTiming.at(cell->name); - if (tmg.clockingInfo.count(port)) - clockInfoCount = int(tmg.clockingInfo.at(port).size()); - else - clockInfoCount = 0; - return get_or_default(tmg.portClasses, port, TMG_IGNORE); + return TMG_IGNORE; } TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port, int index) const { - NPNR_ASSERT(cellTiming.count(cell->name)); - const auto &tmg = cellTiming.at(cell->name); - NPNR_ASSERT(tmg.clockingInfo.count(port)); - return tmg.clockingInfo.at(port).at(index); + return TimingClockingInfo(); } bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const { - std::vector cells; - cells.push_back(cell); - Loc loc = getBelLocation(bel); - for (auto tbel : getBelsByTile(loc.x, loc.y)) { - if (tbel == bel) - continue; - CellInfo *bound = getBoundBelCell(tbel); - if (bound != nullptr) - cells.push_back(bound); - } - return cellsCompatible(cells.data(), int(cells.size())); + return false; } bool Arch::isBelLocationValid(BelId bel) const { - std::vector cells; - Loc loc = getBelLocation(bel); - for (auto tbel : getBelsByTile(loc.x, loc.y)) { - CellInfo *bound = getBoundBelCell(tbel); - if (bound != nullptr) - cells.push_back(bound); - } - return cellsCompatible(cells.data(), int(cells.size())); + return false; } #ifdef WITH_HEAP @@ -474,24 +370,7 @@ void Arch::assignArchInfo() bool Arch::cellsCompatible(const CellInfo **cells, int count) const { - const NetInfo *clk = nullptr; - int group = -1; - for (int i = 0; i < count; i++) { - const CellInfo *ci = cells[i]; - if (ci->is_slice && ci->slice_clk != nullptr) { - if (clk == nullptr) - clk = ci->slice_clk; - else if (clk != ci->slice_clk) - return false; - } - if (ci->user_group != -1) { - if (group == -1) - group = ci->user_group; - else if (group != ci->user_group) - return false; - } - } - return true; + return false; } NEXTPNR_NAMESPACE_END -- cgit v1.2.3 From ec4a9685abf0fd7d7b2cfecc5dbfc09b963b6ea8 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sat, 5 Dec 2020 00:38:00 -0500 Subject: machxo2: Initialize Arch context with device type and package. --- machxo2/arch.cc | 49 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 8 deletions(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 5d1cb0cb..0a3f345f 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -29,14 +29,6 @@ NEXTPNR_NAMESPACE_BEGIN -// --------------------------------------------------------------- - -Arch::Arch(ArchArgs args) : chipName("generic"), args(args) -{ - // Dummy for empty decals - // decal_graphics[IdString()]; -} - // ----------------------------------------------------------------------- void IdString::initialize_arch(const BaseCtx *ctx) { @@ -74,8 +66,49 @@ static const ChipInfoPOD *get_chip_info(ArchArgs::ArchArgsTypes chip) return ptr->get(); } +// --------------------------------------------------------------- + +Arch::Arch(ArchArgs args) : args(args) +{ + chip_info = get_chip_info(args.type); + if (chip_info == nullptr) + log_error("Unsupported MachXO2 chip type.\n"); + if (chip_info->const_id_count != DB_CONST_ID_COUNT) + log_error("Chip database 'bba' and nextpnr code are out of sync; please rebuild (or contact distribution " + "maintainer)!\n"); + + package_info = nullptr; + for (int i = 0; i < chip_info->num_packages; i++) { + if (args.package == chip_info->package_info[i].name.get()) { + package_info = &(chip_info->package_info[i]); + break; + } + } + if (!package_info) + log_error("Unsupported package '%s' for '%s'.\n", args.package.c_str(), getChipName().c_str()); +} + bool Arch::isAvailable(ArchArgs::ArchArgsTypes chip) { return get_chip_info(chip) != nullptr; } +std::string Arch::getChipName() const +{ + if (args.type == ArchArgs::LCMXO2_256HC) { + return "LCMXO2-256HC"; + } else if (args.type == ArchArgs::LCMXO2_640HC) { + return "LCMXO2-640HC"; + } else if (args.type == ArchArgs::LCMXO2_1200HC) { + return "LCMXO2-1200HC"; + } else if (args.type == ArchArgs::LCMXO2_2000HC) { + return "LCMXO2-2000HC"; + } else if (args.type == ArchArgs::LCMXO2_4000HC) { + return "LCMXO2-4000HC"; + } else if (args.type == ArchArgs::LCMXO2_7000HC) { + return "LCMXO2-7000HC"; + } else { + log_error("Unknown chip\n"); + } +} + // --------------------------------------------------------------- BelId Arch::getBelByName(IdString name) const -- cgit v1.2.3 From dc07054ee8c28b9c553be4a61562c5b294de0c06 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sat, 5 Dec 2020 22:01:28 -0500 Subject: machxo2: Implement functions to get device utilization (throws std::out_of_range during place phase). --- machxo2/arch.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 0a3f345f..431fcc88 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -116,7 +116,7 @@ BelId Arch::getBelByName(IdString name) const return BelId(); } -IdString Arch::getBelName(BelId bel) const { return bel; } +IdString Arch::getBelName(BelId bel) const { return IdString(); } Loc Arch::getBelLocation(BelId bel) const { @@ -154,10 +154,6 @@ CellInfo *Arch::getBoundBelCell(BelId bel) const { return nullptr; } CellInfo *Arch::getConflictingBelCell(BelId bel) const { return nullptr; } -const std::vector &Arch::getBels() const { return bel_id_dummy; } - -IdString Arch::getBelType(BelId bel) const { return IdString(); } - const std::map &Arch::getBelAttrs(BelId bel) const { return attrs_dummy; } WireId Arch::getBelPinWire(BelId bel, IdString pin) const -- cgit v1.2.3 From 094233a4ab49245d8fbdbae83f3241ff3c6585b0 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sun, 6 Dec 2020 21:50:04 -0500 Subject: machxo2: Implement getBelLocation to stop std::out_of_range in place phase. --- machxo2/arch.cc | 5 ----- 1 file changed, 5 deletions(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 431fcc88..dccbcb87 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -118,11 +118,6 @@ BelId Arch::getBelByName(IdString name) const IdString Arch::getBelName(BelId bel) const { return IdString(); } -Loc Arch::getBelLocation(BelId bel) const -{ - return Loc(); -} - BelId Arch::getBelByLocation(Loc loc) const { return BelId(); -- cgit v1.2.3 From 3e6be4bbfd3be2bb57075d8b76ba239ff6a0ee54 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sun, 6 Dec 2020 22:06:24 -0500 Subject: machxo2: Implement General Methods. --- machxo2/arch.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index dccbcb87..821fb7e7 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -109,6 +109,25 @@ std::string Arch::getChipName() const } } +IdString Arch::archArgsToId(ArchArgs args) const +{ + if (args.type == ArchArgs::LCMXO2_256HC) { + return id("lcmxo2_256hc"); + } else if (args.type == ArchArgs::LCMXO2_640HC) { + return id("lcmxo2_640hc"); + } else if (args.type == ArchArgs::LCMXO2_1200HC) { + return id("lcmxo2_1200hc"); + } else if (args.type == ArchArgs::LCMXO2_2000HC) { + return id("lcmxo2_2000hc"); + } else if (args.type == ArchArgs::LCMXO2_4000HC) { + return id("lcmxo2_4000hc"); + } else if (args.type == ArchArgs::LCMXO2_7000HC) { + return id("lcmxo2_7000hc"); + } + + return IdString(); +} + // --------------------------------------------------------------- BelId Arch::getBelByName(IdString name) const -- cgit v1.2.3 From 682de724a8f84ee5106a1fd8ad68888605eafa89 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sun, 6 Dec 2020 22:35:25 -0500 Subject: machxo2: Implement 2 Bel API functions. --- machxo2/arch.cc | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 821fb7e7..8c8dda5e 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -135,10 +135,25 @@ BelId Arch::getBelByName(IdString name) const return BelId(); } -IdString Arch::getBelName(BelId bel) const { return IdString(); } - BelId Arch::getBelByLocation(Loc loc) const { + BelId ret; + + if(loc.x >= chip_info->width || loc.y >= chip_info->height) + return BelId(); + + ret.location.x = loc.x; + ret.location.y = loc.y; + + const TileTypePOD *tilei = tileInfo(ret); + for(int i = 0; i < tilei->num_bels; i++) { + if(tilei->bel_data[i].z == loc.z) + { + ret.index = i; + return ret; + } + } + return BelId(); } -- cgit v1.2.3 From 5f748272fc118f5fdf8b5389188434c6070ca917 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sun, 6 Dec 2020 22:50:15 -0500 Subject: machxo2: Implement bel_to_cell and API functions using it. --- machxo2/arch.cc | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 8c8dda5e..42d93f16 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -167,22 +167,6 @@ uint32_t Arch::getBelChecksum(BelId bel) const return 0; } -void Arch::bindBel(BelId bel, CellInfo *cell, PlaceStrength strength) -{ - -} - -void Arch::unbindBel(BelId bel) -{ - -} - -bool Arch::checkBelAvail(BelId bel) const { return false; } - -CellInfo *Arch::getBoundBelCell(BelId bel) const { return nullptr; } - -CellInfo *Arch::getConflictingBelCell(BelId bel) const { return nullptr; } - const std::map &Arch::getBelAttrs(BelId bel) const { return attrs_dummy; } WireId Arch::getBelPinWire(BelId bel, IdString pin) const -- cgit v1.2.3 From 8a94a3451f88ca6632991ef3f2a61e4ed9a4ac5b Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Mon, 7 Dec 2020 02:15:29 -0500 Subject: machxo2: Stub valid BEL functions with comment. Place phase segfaults. --- machxo2/arch.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 42d93f16..d9753528 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -382,12 +382,17 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const { - return false; + // FIXME: Unlike ECP5, SLICEs in a given tile do not share a clock, so + // any SLICE Cell is valid for any BEL, even if some cells are already + // bound to BELs in the tile. However, this may need to be filled in once + // more than one LUT4 and DFF type is supported. + return true; } bool Arch::isBelLocationValid(BelId bel) const { - return false; + // FIXME: Same deal as isValidBelForCell. + return true; } #ifdef WITH_HEAP -- cgit v1.2.3 From 138519d820cd25cdd6700fabf13e855d67030e1a Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Mon, 7 Dec 2020 02:15:51 -0500 Subject: machxo2: Fix place phase segfault. Placement suceeds with warning of no clock. --- machxo2/arch.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index d9753528..6c7efbe5 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -86,6 +86,8 @@ Arch::Arch(ArchArgs args) : args(args) } if (!package_info) log_error("Unsupported package '%s' for '%s'.\n", args.package.c_str(), getChipName().c_str()); + + bel_to_cell.resize(chip_info->height * chip_info->width * max_loc_bels, nullptr); } bool Arch::isAvailable(ArchArgs::ArchArgsTypes chip) { return get_chip_info(chip) != nullptr; } -- cgit v1.2.3 From bbc683dd75fcf54b8f215704a932c5c2f1a39c93 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Mon, 7 Dec 2020 11:48:15 -0500 Subject: machxo2: Implement all of Bel API except getBelPinWire. --- machxo2/arch.cc | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 9 deletions(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 6c7efbe5..a01f96e6 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -29,6 +29,18 @@ NEXTPNR_NAMESPACE_BEGIN +static std::tuple split_identifier_name(const std::string &name) +{ + size_t first_slash = name.find('/'); + NPNR_ASSERT(first_slash != std::string::npos); + size_t second_slash = name.find('/', first_slash + 1); + NPNR_ASSERT(second_slash != std::string::npos); + return std::make_tuple(std::stoi(name.substr(1, first_slash)), + std::stoi(name.substr(first_slash + 2, second_slash - first_slash)), + name.substr(second_slash + 1)); +}; + + // ----------------------------------------------------------------------- void IdString::initialize_arch(const BaseCtx *ctx) { @@ -134,7 +146,25 @@ IdString Arch::archArgsToId(ArchArgs args) const BelId Arch::getBelByName(IdString name) const { - return BelId(); + BelId ret; + auto it = bel_by_name.find(name); + if (it != bel_by_name.end()) + return it->second; + + Location loc; + std::string basename; + std::tie(loc.x, loc.y, basename) = split_identifier_name(name.str(this)); + ret.location = loc; + const TileTypePOD *tilei = tileInfo(ret); + for (int i = 0; i < tilei->num_bels; i++) { + if (std::strcmp(tilei->bel_data[i].name.get(), basename.c_str()) == 0) { + ret.index = i; + break; + } + } + if (ret.index >= 0) + bel_by_name[name] = ret; + return ret; } BelId Arch::getBelByLocation(Loc loc) const @@ -159,16 +189,25 @@ BelId Arch::getBelByLocation(Loc loc) const return BelId(); } -const std::vector &Arch::getBelsByTile(int x, int y) const { return bel_id_dummy; } - -bool Arch::getBelGlobalBuf(BelId bel) const { return false; } - -uint32_t Arch::getBelChecksum(BelId bel) const +BelRange Arch::getBelsByTile(int x, int y) const { - // FIXME - return 0; + BelRange br; + + br.b.cursor_tile = y * chip_info->width + x; + br.e.cursor_tile = y * chip_info->width + x; + br.b.cursor_index = 0; + br.e.cursor_index = chip_info->tiles[y * chip_info->width + x].num_bels - 1; + br.b.chip = chip_info; + br.e.chip = chip_info; + if (br.e.cursor_index == -1) + ++br.e.cursor_index; + else + ++br.e; + return br; } +bool Arch::getBelGlobalBuf(BelId bel) const { return false; } + const std::map &Arch::getBelAttrs(BelId bel) const { return attrs_dummy; } WireId Arch::getBelPinWire(BelId bel, IdString pin) const @@ -176,11 +215,33 @@ WireId Arch::getBelPinWire(BelId bel, IdString pin) const return WireId(); } -PortType Arch::getBelPinType(BelId bel, IdString pin) const { return PortType(); } +PortType Arch::getBelPinType(BelId bel, IdString pin) const +{ + NPNR_ASSERT(bel != BelId()); + + int num_bel_wires = tileInfo(bel)->bel_data[bel.index].num_bel_wires; + const BelWirePOD *bel_wires = &*tileInfo(bel)->bel_data[bel.index].bel_wires; + + for(int i = 0; i < num_bel_wires; i++) + if(bel_wires[i].port == pin.index) + return PortType(bel_wires[i].dir); + + return PORT_INOUT; +} std::vector Arch::getBelPins(BelId bel) const { std::vector ret; + NPNR_ASSERT(bel != BelId()); + + int num_bel_wires = tileInfo(bel)->bel_data[bel.index].num_bel_wires; + const BelWirePOD *bel_wires = &*tileInfo(bel)->bel_data[bel.index].bel_wires; + + for(int i = 0; i < num_bel_wires; i++) { + IdString id(bel_wires[i].port); + ret.push_back(id); + } + return ret; } -- cgit v1.2.3 From a7917c9c63efe654a24a4136a91fa4558ee2c625 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Mon, 7 Dec 2020 17:41:34 -0500 Subject: machxo2: Implement WireId/PipId, complete Bel part of API. --- machxo2/arch.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index a01f96e6..ee334ed4 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -212,6 +212,22 @@ const std::map &Arch::getBelAttrs(BelId bel) const { retu WireId Arch::getBelPinWire(BelId bel, IdString pin) const { + NPNR_ASSERT(bel != BelId()); + + int num_bel_wires = tileInfo(bel)->bel_data[bel.index].num_bel_wires; + const BelWirePOD *bel_wires = &*tileInfo(bel)->bel_data[bel.index].bel_wires; + + for(int i = 0; i < num_bel_wires; i++) + if(bel_wires[i].port == pin.index) { + WireId ret; + + ret.location.x = bel_wires[i].rel_wire_loc.x; + ret.location.y = bel_wires[i].rel_wire_loc.y; + ret.index = bel_wires[i].wire_index; + + return ret; + } + return WireId(); } -- cgit v1.2.3 From 0e63178fe196dc042f2dc873ab40a929678dc53a Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Mon, 7 Dec 2020 18:56:27 -0500 Subject: machxo2: clang format. --- machxo2/arch.cc | 84 +++++++++++++++++---------------------------------------- 1 file changed, 25 insertions(+), 59 deletions(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index ee334ed4..20c68065 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -19,8 +19,8 @@ #include #include -#include "nextpnr.h" #include "embed.h" +#include "nextpnr.h" #include "placer1.h" #include "placer_heap.h" #include "router1.h" @@ -40,15 +40,15 @@ static std::tuple split_identifier_name(const std::string name.substr(second_slash + 1)); }; - // ----------------------------------------------------------------------- -void IdString::initialize_arch(const BaseCtx *ctx) { - #define X(t) initialize_add(ctx, #t, ID_##t); +void IdString::initialize_arch(const BaseCtx *ctx) +{ +#define X(t) initialize_add(ctx, #t, ID_##t); - #include "constids.inc" +#include "constids.inc" - #undef X +#undef X } // --------------------------------------------------------------- @@ -171,16 +171,15 @@ BelId Arch::getBelByLocation(Loc loc) const { BelId ret; - if(loc.x >= chip_info->width || loc.y >= chip_info->height) + if (loc.x >= chip_info->width || loc.y >= chip_info->height) return BelId(); ret.location.x = loc.x; ret.location.y = loc.y; const TileTypePOD *tilei = tileInfo(ret); - for(int i = 0; i < tilei->num_bels; i++) { - if(tilei->bel_data[i].z == loc.z) - { + for (int i = 0; i < tilei->num_bels; i++) { + if (tilei->bel_data[i].z == loc.z) { ret.index = i; return ret; } @@ -217,8 +216,8 @@ WireId Arch::getBelPinWire(BelId bel, IdString pin) const int num_bel_wires = tileInfo(bel)->bel_data[bel.index].num_bel_wires; const BelWirePOD *bel_wires = &*tileInfo(bel)->bel_data[bel.index].bel_wires; - for(int i = 0; i < num_bel_wires; i++) - if(bel_wires[i].port == pin.index) { + for (int i = 0; i < num_bel_wires; i++) + if (bel_wires[i].port == pin.index) { WireId ret; ret.location.x = bel_wires[i].rel_wire_loc.x; @@ -238,8 +237,8 @@ PortType Arch::getBelPinType(BelId bel, IdString pin) const int num_bel_wires = tileInfo(bel)->bel_data[bel.index].num_bel_wires; const BelWirePOD *bel_wires = &*tileInfo(bel)->bel_data[bel.index].bel_wires; - for(int i = 0; i < num_bel_wires; i++) - if(bel_wires[i].port == pin.index) + for (int i = 0; i < num_bel_wires; i++) + if (bel_wires[i].port == pin.index) return PortType(bel_wires[i].dir); return PORT_INOUT; @@ -253,7 +252,7 @@ std::vector Arch::getBelPins(BelId bel) const int num_bel_wires = tileInfo(bel)->bel_data[bel.index].num_bel_wires; const BelWirePOD *bel_wires = &*tileInfo(bel)->bel_data[bel.index].bel_wires; - for(int i = 0; i < num_bel_wires; i++) { + for (int i = 0; i < num_bel_wires; i++) { IdString id(bel_wires[i].port); ret.push_back(id); } @@ -263,10 +262,7 @@ std::vector Arch::getBelPins(BelId bel) const // --------------------------------------------------------------- -WireId Arch::getWireByName(IdString name) const -{ - return WireId(); -} +WireId Arch::getWireByName(IdString name) const { return WireId(); } IdString Arch::getWireName(WireId wire) const { return IdString(); } @@ -280,15 +276,9 @@ uint32_t Arch::getWireChecksum(WireId wire) const return 0; } -void Arch::bindWire(WireId wire, NetInfo *net, PlaceStrength strength) -{ - -} - -void Arch::unbindWire(WireId wire) -{ +void Arch::bindWire(WireId wire, NetInfo *net, PlaceStrength strength) {} -} +void Arch::unbindWire(WireId wire) {} bool Arch::checkWireAvail(WireId wire) const { return false; } @@ -302,10 +292,7 @@ const std::vector &Arch::getWires() const { return wire_id_dummy; } // --------------------------------------------------------------- -PipId Arch::getPipByName(IdString name) const -{ - return PipId(); -} +PipId Arch::getPipByName(IdString name) const { return PipId(); } IdString Arch::getPipName(PipId pip) const { return IdString(); } @@ -319,15 +306,9 @@ uint32_t Arch::getPipChecksum(PipId wire) const return 0; } -void Arch::bindPip(PipId pip, NetInfo *net, PlaceStrength strength) -{ - -} - -void Arch::unbindPip(PipId pip) -{ +void Arch::bindPip(PipId pip, NetInfo *net, PlaceStrength strength) {} -} +void Arch::unbindPip(PipId pip) {} bool Arch::checkPipAvail(PipId pip) const { return false; } @@ -375,15 +356,9 @@ const std::vector &Arch::getGroupGroups(GroupId group) const { return g // --------------------------------------------------------------- -delay_t Arch::estimateDelay(WireId src, WireId dst) const -{ - return 0; -} +delay_t Arch::estimateDelay(WireId src, WireId dst) const { return 0; } -delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const -{ - return 0; -} +delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const { return 0; } bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const { return false; } @@ -428,10 +403,7 @@ bool Arch::route() // --------------------------------------------------------------- -const std::vector &Arch::getDecalGraphics(DecalId decal) const -{ - return graphic_element_dummy; -} +const std::vector &Arch::getDecalGraphics(DecalId decal) const { return graphic_element_dummy; } DecalXY Arch::getBelDecal(BelId bel) const { return DecalXY(); } @@ -489,14 +461,8 @@ const std::vector Arch::availablePlacers = {"sa", const std::string Arch::defaultRouter = "router1"; const std::vector Arch::availableRouters = {"router1", "router2"}; -void Arch::assignArchInfo() -{ +void Arch::assignArchInfo() {} -} - -bool Arch::cellsCompatible(const CellInfo **cells, int count) const -{ - return false; -} +bool Arch::cellsCompatible(const CellInfo **cells, int count) const { return false; } NEXTPNR_NAMESPACE_END -- cgit v1.2.3 From 9c37aef499b584ca464d8ceb238aec9321c0a274 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Tue, 8 Dec 2020 01:42:58 -0500 Subject: machxo2: Detect LOC attributes during packing to implement rudimentary user constraints. --- machxo2/arch.cc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 20c68065..abc281cb 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -262,6 +262,21 @@ std::vector Arch::getBelPins(BelId bel) const // --------------------------------------------------------------- +BelId Arch::getPackagePinBel(const std::string &pin) const +{ + for (int i = 0; i < package_info->num_pins; i++) { + if (package_info->pin_data[i].name.get() == pin) { + BelId bel; + bel.location = package_info->pin_data[i].abs_loc; + bel.index = package_info->pin_data[i].bel_index; + return bel; + } + } + return BelId(); +} + +// --------------------------------------------------------------- + WireId Arch::getWireByName(IdString name) const { return WireId(); } IdString Arch::getWireName(WireId wire) const { return IdString(); } -- cgit v1.2.3 From 9a9054188c52d76670dace9777981ffd28de5599 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Wed, 27 Jan 2021 01:46:32 -0500 Subject: machxo2: Implement getByName/getName for Wires and Pips. --- machxo2/arch.cc | 70 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 9 deletions(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index abc281cb..3fc4dcd8 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -277,9 +277,30 @@ BelId Arch::getPackagePinBel(const std::string &pin) const // --------------------------------------------------------------- -WireId Arch::getWireByName(IdString name) const { return WireId(); } +WireId Arch::getWireByName(IdString name) const +{ + WireId ret; + + auto it = wire_by_name.find(name); + if (it != wire_by_name.end()) + return it->second; -IdString Arch::getWireName(WireId wire) const { return IdString(); } + Location loc; + std::string basename; + std::tie(loc.x, loc.y, basename) = split_identifier_name(name.str(this)); + ret.location = loc; + + const TileTypePOD *tilei = tileInfo(ret); + for (int i = 0; i < tilei->num_wires; i++) { + if (std::strcmp(tilei->wire_data[i].name.get(), basename.c_str()) == 0) { + ret.index = i; + break; + } + } + if (ret.index >= 0) + wire_by_name[name] = ret; + return ret; +} IdString Arch::getWireType(WireId wire) const { return IdString(); } @@ -307,11 +328,46 @@ const std::vector &Arch::getWires() const { return wire_id_dummy; } // --------------------------------------------------------------- -PipId Arch::getPipByName(IdString name) const { return PipId(); } +PipId Arch::getPipByName(IdString name) const +{ + PipId ret; -IdString Arch::getPipName(PipId pip) const { return IdString(); } + auto it = pip_by_name.find(name); + if (it != pip_by_name.end()) + return it->second; -IdString Arch::getPipType(PipId pip) const { return IdString(); } + Location loc; + std::string basename; + std::tie(loc.x, loc.y, basename) = split_identifier_name(name.str(this)); + ret.location = loc; + + const TileTypePOD *tilei = tileInfo(ret); + for (int i = 0; i < tilei->num_pips; i++) { + PipId curr; + curr.location = loc; + curr.index = i; + pip_by_name[getPipName(curr)] = curr; + } + if (pip_by_name.find(name) == pip_by_name.end()) + NPNR_ASSERT_FALSE_STR("no pip named " + name.str(this)); + return pip_by_name[name]; +} + +IdString Arch::getPipName(PipId pip) const +{ + NPNR_ASSERT(pip != PipId()); + + int x = pip.location.x; + int y = pip.location.y; + + std::string src_name = getWireName(getPipSrcWire(pip)).str(this); + std::replace(src_name.begin(), src_name.end(), '/', '.'); + + std::string dst_name = getWireName(getPipDstWire(pip)).str(this); + std::replace(dst_name.begin(), dst_name.end(), '/', '.'); + + return id("X" + std::to_string(x) + "/Y" + std::to_string(y) + "/" + src_name + ".->." + dst_name); +} const std::map &Arch::getPipAttrs(PipId pip) const { return attrs_dummy; } @@ -337,10 +393,6 @@ const std::vector &Arch::getPips() const { return pip_id_dummy; } Loc Arch::getPipLocation(PipId pip) const { return Loc(); } -WireId Arch::getPipSrcWire(PipId pip) const { return WireId(); } - -WireId Arch::getPipDstWire(PipId pip) const { return WireId(); } - DelayInfo Arch::getPipDelay(PipId pip) const { return DelayInfo(); } const std::vector &Arch::getPipsDownhill(WireId wire) const { return pip_id_dummy; } -- cgit v1.2.3 From 19a9554bdadf19eec2fb83e6a04ecabfeafc1ed7 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Wed, 27 Jan 2021 02:03:50 -0500 Subject: machxo2: Add stub getAttrs API functions. --- machxo2/arch.cc | 8 -------- 1 file changed, 8 deletions(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 3fc4dcd8..9ac4f3ae 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -207,8 +207,6 @@ BelRange Arch::getBelsByTile(int x, int y) const bool Arch::getBelGlobalBuf(BelId bel) const { return false; } -const std::map &Arch::getBelAttrs(BelId bel) const { return attrs_dummy; } - WireId Arch::getBelPinWire(BelId bel, IdString pin) const { NPNR_ASSERT(bel != BelId()); @@ -302,10 +300,6 @@ WireId Arch::getWireByName(IdString name) const return ret; } -IdString Arch::getWireType(WireId wire) const { return IdString(); } - -const std::map &Arch::getWireAttrs(WireId wire) const { return attrs_dummy; } - uint32_t Arch::getWireChecksum(WireId wire) const { // FIXME @@ -369,8 +363,6 @@ IdString Arch::getPipName(PipId pip) const return id("X" + std::to_string(x) + "/Y" + std::to_string(y) + "/" + src_name + ".->." + dst_name); } -const std::map &Arch::getPipAttrs(PipId pip) const { return attrs_dummy; } - uint32_t Arch::getPipChecksum(PipId wire) const { // FIXME -- cgit v1.2.3 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 ------------------------ 1 file changed, 24 deletions(-) (limited to 'machxo2/arch.cc') 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; } -- cgit v1.2.3 From 861c12e6eba1ae1c0d6b1ea0ed27c060b2ceb671 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Thu, 28 Jan 2021 03:16:57 -0500 Subject: machxo2: Finish implementing Pip API functions. --- machxo2/arch.cc | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 0f1a0670..eb050598 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -351,24 +351,6 @@ IdString Arch::getPipName(PipId pip) const return id("X" + std::to_string(x) + "/Y" + std::to_string(y) + "/" + src_name + ".->." + dst_name); } -NetInfo *Arch::getBoundPipNet(PipId pip) const { return nullptr; } - -NetInfo *Arch::getConflictingPipNet(PipId pip) const { return nullptr; } - -WireId Arch::getConflictingPipWire(PipId pip) const { return WireId(); } - -const std::vector &Arch::getPips() const { return pip_id_dummy; } - -Loc Arch::getPipLocation(PipId pip) const { return Loc(); } - -DelayInfo Arch::getPipDelay(PipId pip) const { return DelayInfo(); } - -const std::vector &Arch::getPipsDownhill(WireId wire) const { return pip_id_dummy; } - -const std::vector &Arch::getPipsUphill(WireId wire) const { return pip_id_dummy; } - -const std::vector &Arch::getWireAliases(WireId wire) const { return pip_id_dummy; } - // --------------------------------------------------------------- GroupId Arch::getGroupByName(IdString name) const { return GroupId(); } -- cgit v1.2.3 From 722d1f254284638515accc8c1d4562807f6452cc Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Thu, 28 Jan 2021 03:24:52 -0500 Subject: machxo2: Finish implementing Wire API functions. nextpnr segfaults on example with constraints. --- machxo2/arch.cc | 8 -------- 1 file changed, 8 deletions(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index eb050598..3410ec16 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -300,14 +300,6 @@ WireId Arch::getWireByName(IdString name) const return ret; } -NetInfo *Arch::getBoundWireNet(WireId wire) const { return nullptr; } - -NetInfo *Arch::getConflictingWireNet(WireId wire) const { return nullptr; } - -const std::vector &Arch::getWireBelPins(WireId wire) const { return bel_pin_dummy; } - -const std::vector &Arch::getWires() const { return wire_id_dummy; } - // --------------------------------------------------------------- PipId Arch::getPipByName(IdString name) const -- cgit v1.2.3 From e1f72318e0b126de119cbc5e7f7b143e7beadd09 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sat, 30 Jan 2021 12:39:57 -0500 Subject: machxo2: Tweak A-star parameters for acceptable performance. --- machxo2/arch.cc | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 3410ec16..58c48044 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -365,9 +365,25 @@ const std::vector &Arch::getGroupGroups(GroupId group) const { return g // --------------------------------------------------------------- -delay_t Arch::estimateDelay(WireId src, WireId dst) const { return 0; } +delay_t Arch::estimateDelay(WireId src, WireId dst) const +{ + // Taxicab distance multiplied by pipDelay (0.01) and fake wireDelay (0.01). + // TODO: This function will not work well for entrance to global routing, + // as the entrances are located physically far from the DCCAs. + return (abs(dst.location.x - src.location.x) + abs(dst.location.y - src.location.y)) * (0.01 + 0.01); +} + +delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const +{ + BelId src = net_info->driver.cell->bel; + BelId dst = sink.cell->bel; + + NPNR_ASSERT(src != BelId()); + NPNR_ASSERT(dst != BelId()); -delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const { return 0; } + // TODO: Same deal applies here as with estimateDelay. + return (abs(dst.location.x - src.location.x) + abs(dst.location.y - src.location.y)) * (0.01 + 0.01); +} bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const { return false; } -- cgit v1.2.3 From 695fb7e569a9b8368ecf623029997248910d753e Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sat, 30 Jan 2021 18:06:55 -0500 Subject: machxo2: Add/fix copyright banners. --- machxo2/arch.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 58c48044..4ab3dc5b 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -1,7 +1,8 @@ /* * nextpnr -- Next Generation Place and Route * - * Copyright (C) 2018 Clifford Wolf + * Copyright (C) 2018 Claire Xen + * Copyright (C) 2021 William D. Jones * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above -- cgit v1.2.3 From cf2db7a4c474569d372c176e9790dd4f6ae24a03 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sat, 30 Jan 2021 22:42:16 -0500 Subject: machxo2: Write out pips to bitstream. --- machxo2/arch.cc | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 4ab3dc5b..dbe17fd9 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -124,6 +124,33 @@ std::string Arch::getChipName() const } } +std::string Arch::getFullChipName() const +{ + std::string name = getChipName(); + name += "-"; + switch (args.speed) { + case ArchArgs::SPEED_1: + name += "1"; + break; + case ArchArgs::SPEED_2: + name += "2"; + break; + case ArchArgs::SPEED_3: + name += "3"; + case ArchArgs::SPEED_4: + name += "4"; + break; + case ArchArgs::SPEED_5: + name += "5"; + break; + case ArchArgs::SPEED_6: + name += "6"; + break; + } + name += args.package; + return name; +} + IdString Arch::archArgsToId(ArchArgs args) const { if (args.type == ArchArgs::LCMXO2_256HC) { -- cgit v1.2.3 From 5415194b39c0e7ade963f5c52f2977f00ed5feeb Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sat, 30 Jan 2021 23:14:48 -0500 Subject: machxo2: Checkpoint commit for slice bitstream generation. --- machxo2/arch.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index dbe17fd9..101ceae7 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -518,4 +518,15 @@ void Arch::assignArchInfo() {} bool Arch::cellsCompatible(const CellInfo **cells, int count) const { return false; } +std::vector> Arch::getTilesAtLocation(int row, int col) +{ + std::vector> ret; + auto &tileloc = chip_info->tile_info[row * chip_info->width + col]; + for (int i = 0; i < tileloc.num_tiles; i++) { + ret.push_back(std::make_pair(tileloc.tile_names[i].name.get(), + chip_info->tiletype_names[tileloc.tile_names[i].type_idx].get())); + } + return ret; +} + NEXTPNR_NAMESPACE_END -- cgit v1.2.3 From 3f7618283d1eed2a35bbce161f905a4088020d8e Mon Sep 17 00:00:00 2001 From: gatecat Date: Thu, 11 Feb 2021 11:34:08 +0000 Subject: machxo2: Update with Arch API changes Signed-off-by: gatecat --- machxo2/arch.cc | 105 +++++++++++++++++--------------------------------------- 1 file changed, 32 insertions(+), 73 deletions(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 101ceae7..4c0f9b9c 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -100,7 +100,8 @@ Arch::Arch(ArchArgs args) : args(args) if (!package_info) log_error("Unsupported package '%s' for '%s'.\n", args.package.c_str(), getChipName().c_str()); - bel_to_cell.resize(chip_info->height * chip_info->width * max_loc_bels, nullptr); + BaseArch::init_cell_types(); + BaseArch::init_bel_buckets(); } bool Arch::isAvailable(ArchArgs::ArchArgsTypes chip) { return get_chip_info(chip) != nullptr; } @@ -172,16 +173,18 @@ IdString Arch::archArgsToId(ArchArgs args) const // --------------------------------------------------------------- -BelId Arch::getBelByName(IdString name) const +BelId Arch::getBelByName(IdStringList name) const { BelId ret; - auto it = bel_by_name.find(name); + IdString name_id = name[0]; + + auto it = bel_by_name.find(name_id); if (it != bel_by_name.end()) return it->second; 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_id.str(this)); ret.location = loc; const TileTypePOD *tilei = tileInfo(ret); for (int i = 0; i < tilei->num_bels; i++) { @@ -191,7 +194,7 @@ BelId Arch::getBelByName(IdString name) const } } if (ret.index >= 0) - bel_by_name[name] = ret; + bel_by_name[name_id] = ret; return ret; } @@ -303,17 +306,18 @@ BelId Arch::getPackagePinBel(const std::string &pin) const // --------------------------------------------------------------- -WireId Arch::getWireByName(IdString name) const +WireId Arch::getWireByName(IdStringList name) const { WireId ret; + IdString name_id = name[0]; - auto it = wire_by_name.find(name); + auto it = wire_by_name.find(name_id); if (it != wire_by_name.end()) return it->second; 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_id.str(this)); ret.location = loc; const TileTypePOD *tilei = tileInfo(ret); @@ -324,23 +328,24 @@ WireId Arch::getWireByName(IdString name) const } } if (ret.index >= 0) - wire_by_name[name] = ret; + wire_by_name[name_id] = ret; return ret; } // --------------------------------------------------------------- -PipId Arch::getPipByName(IdString name) const +PipId Arch::getPipByName(IdStringList name) const { PipId ret; + IdString name_id = name[0]; - auto it = pip_by_name.find(name); + auto it = pip_by_name.find(name_id); if (it != pip_by_name.end()) return it->second; 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_id.str(this)); ret.location = loc; const TileTypePOD *tilei = tileInfo(ret); @@ -348,49 +353,29 @@ PipId Arch::getPipByName(IdString name) const PipId curr; curr.location = loc; curr.index = i; - pip_by_name[getPipName(curr)] = curr; + pip_by_name[getPipName(curr)[0]] = curr; } - if (pip_by_name.find(name) == pip_by_name.end()) - NPNR_ASSERT_FALSE_STR("no pip named " + name.str(this)); - return pip_by_name[name]; + if (pip_by_name.find(name_id) == pip_by_name.end()) + NPNR_ASSERT_FALSE_STR("no pip named " + name_id.str(this)); + return pip_by_name[name_id]; } -IdString Arch::getPipName(PipId pip) const +IdStringList Arch::getPipName(PipId pip) const { NPNR_ASSERT(pip != PipId()); int x = pip.location.x; int y = pip.location.y; - std::string src_name = getWireName(getPipSrcWire(pip)).str(this); + std::string src_name = getWireName(getPipSrcWire(pip)).str(getCtx()); std::replace(src_name.begin(), src_name.end(), '/', '.'); - std::string dst_name = getWireName(getPipDstWire(pip)).str(this); + std::string dst_name = getWireName(getPipDstWire(pip)).str(getCtx()); std::replace(dst_name.begin(), dst_name.end(), '/', '.'); - return id("X" + std::to_string(x) + "/Y" + std::to_string(y) + "/" + src_name + ".->." + dst_name); -} - -// --------------------------------------------------------------- - -GroupId Arch::getGroupByName(IdString name) const { return GroupId(); } - -IdString Arch::getGroupName(GroupId group) const { return IdString(); } - -std::vector Arch::getGroups() const -{ - std::vector ret; - return ret; + return IdStringList(id("X" + std::to_string(x) + "/Y" + std::to_string(y) + "/" + src_name + ".->." + dst_name)); } -const std::vector &Arch::getGroupBels(GroupId group) const { return bel_id_dummy; } - -const std::vector &Arch::getGroupWires(GroupId group) const { return wire_id_dummy; } - -const std::vector &Arch::getGroupPips(GroupId group) const { return pip_id_dummy; } - -const std::vector &Arch::getGroupGroups(GroupId group) const { return group_id_dummy; } - // --------------------------------------------------------------- delay_t Arch::estimateDelay(WireId src, WireId dst) const @@ -413,8 +398,6 @@ delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const return (abs(dst.location.x - src.location.x) + abs(dst.location.y - src.location.y)) * (0.01 + 0.01); } -bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const { return false; } - ArcBounds Arch::getRouteBoundingBox(WireId src, WireId dst) const { ArcBounds bb; @@ -432,6 +415,13 @@ bool Arch::place() getCtx()->settings[getCtx()->id("place")] = 1; archInfoToAttributes(); return retVal; + } else if (placer == "heap") { + PlacerHeapCfg cfg(getCtx()); + cfg.ioBufTypes.insert(id_FACADE_IO); + bool retVal = placer_heap(getCtx(), cfg); + getCtx()->settings[getCtx()->id("place")] = 1; + archInfoToAttributes(); + return retVal; } else { log_error("MachXO2 architecture does not support placer '%s'\n", placer.c_str()); } @@ -455,35 +445,6 @@ bool Arch::route() } // --------------------------------------------------------------- - -const std::vector &Arch::getDecalGraphics(DecalId decal) const { return graphic_element_dummy; } - -DecalXY Arch::getBelDecal(BelId bel) const { return DecalXY(); } - -DecalXY Arch::getWireDecal(WireId wire) const { return DecalXY(); } - -DecalXY Arch::getPipDecal(PipId pip) const { return DecalXY(); } - -DecalXY Arch::getGroupDecal(GroupId group) const { return DecalXY(); } - -// --------------------------------------------------------------- - -bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const -{ - return false; -} - -// Get the port class, also setting clockPort if applicable -TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const -{ - return TMG_IGNORE; -} - -TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port, int index) const -{ - return TimingClockingInfo(); -} - bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const { // FIXME: Unlike ECP5, SLICEs in a given tile do not share a clock, so @@ -514,8 +475,6 @@ const std::vector Arch::availablePlacers = {"sa", const std::string Arch::defaultRouter = "router1"; const std::vector Arch::availableRouters = {"router1", "router2"}; -void Arch::assignArchInfo() {} - bool Arch::cellsCompatible(const CellInfo **cells, int count) const { return false; } std::vector> Arch::getTilesAtLocation(int row, int col) -- cgit v1.2.3 From b539363cd05a2841661be3cc4fb0c2804dc35376 Mon Sep 17 00:00:00 2001 From: gatecat Date: Thu, 11 Feb 2021 12:46:31 +0000 Subject: machxo2: Use IdStringLists in earnest Signed-off-by: gatecat --- machxo2/arch.cc | 122 ++++++++++++++++++++++++++------------------------------ 1 file changed, 56 insertions(+), 66 deletions(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 4c0f9b9c..c2b2e0ad 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -30,17 +30,6 @@ NEXTPNR_NAMESPACE_BEGIN -static std::tuple split_identifier_name(const std::string &name) -{ - size_t first_slash = name.find('/'); - NPNR_ASSERT(first_slash != std::string::npos); - size_t second_slash = name.find('/', first_slash + 1); - NPNR_ASSERT(second_slash != std::string::npos); - return std::make_tuple(std::stoi(name.substr(1, first_slash)), - std::stoi(name.substr(first_slash + 2, second_slash - first_slash)), - name.substr(second_slash + 1)); -}; - // ----------------------------------------------------------------------- void IdString::initialize_arch(const BaseCtx *ctx) @@ -102,6 +91,22 @@ Arch::Arch(ArchArgs args) : args(args) BaseArch::init_cell_types(); BaseArch::init_bel_buckets(); + + for (int i = 0; i < chip_info->width; i++) + x_ids.push_back(id(stringf("X%d", i))); + for (int i = 0; i < chip_info->height; i++) + y_ids.push_back(id(stringf("Y%d", i))); + + for (int i = 0; i < chip_info->width; i++) { + IdString x_id = id(stringf("X%d", i)); + x_ids.push_back(x_id); + id_to_x[x_id] = i; + } + for (int i = 0; i < chip_info->height; i++) { + IdString y_id = id(stringf("Y%d", i)); + y_ids.push_back(y_id); + id_to_y[y_id] = i; + } } bool Arch::isAvailable(ArchArgs::ArchArgsTypes chip) { return get_chip_info(chip) != nullptr; } @@ -175,27 +180,21 @@ IdString Arch::archArgsToId(ArchArgs args) const BelId Arch::getBelByName(IdStringList name) const { + if (name.size() != 3) + return BelId(); BelId ret; - IdString name_id = name[0]; - - auto it = bel_by_name.find(name_id); - if (it != bel_by_name.end()) - return it->second; - Location loc; - std::string basename; - std::tie(loc.x, loc.y, basename) = split_identifier_name(name_id.str(this)); + loc.x = id_to_x.at(name[0]); + loc.y = id_to_y.at(name[1]); ret.location = loc; - const TileTypePOD *tilei = tileInfo(ret); - for (int i = 0; i < tilei->num_bels; i++) { - if (std::strcmp(tilei->bel_data[i].name.get(), basename.c_str()) == 0) { + const TileTypePOD *loci = tileInfo(ret); + for (int i = 0; i < loci->num_bels; i++) { + if (std::strcmp(loci->bel_data[i].name.get(), name[2].c_str(this)) == 0) { ret.index = i; - break; + return ret; } } - if (ret.index >= 0) - bel_by_name[name_id] = ret; - return ret; + return BelId(); } BelId Arch::getBelByLocation(Loc loc) const @@ -308,72 +307,63 @@ BelId Arch::getPackagePinBel(const std::string &pin) const WireId Arch::getWireByName(IdStringList name) const { + if (name.size() != 3) + return WireId(); WireId ret; - IdString name_id = name[0]; - - auto it = wire_by_name.find(name_id); - if (it != wire_by_name.end()) - return it->second; - Location loc; - std::string basename; - std::tie(loc.x, loc.y, basename) = split_identifier_name(name_id.str(this)); + loc.x = id_to_x.at(name[0]); + loc.y = id_to_y.at(name[1]); ret.location = loc; - - const TileTypePOD *tilei = tileInfo(ret); - for (int i = 0; i < tilei->num_wires; i++) { - if (std::strcmp(tilei->wire_data[i].name.get(), basename.c_str()) == 0) { + const TileTypePOD *loci = tileInfo(ret); + for (int i = 0; i < loci->num_wires; i++) { + if (std::strcmp(loci->wire_data[i].name.get(), name[2].c_str(this)) == 0) { ret.index = i; - break; + return ret; } } - if (ret.index >= 0) - wire_by_name[name_id] = ret; - return ret; + return WireId(); } // --------------------------------------------------------------- PipId Arch::getPipByName(IdStringList name) const { - PipId ret; - IdString name_id = name[0]; - - auto it = pip_by_name.find(name_id); + if (name.size() != 3) + return PipId(); + auto it = pip_by_name.find(name); if (it != pip_by_name.end()) return it->second; + PipId ret; Location loc; std::string basename; - std::tie(loc.x, loc.y, basename) = split_identifier_name(name_id.str(this)); + loc.x = id_to_x.at(name[0]); + loc.y = id_to_y.at(name[1]); ret.location = loc; - - const TileTypePOD *tilei = tileInfo(ret); - for (int i = 0; i < tilei->num_pips; i++) { + const TileTypePOD *loci = tileInfo(ret); + for (int i = 0; i < loci->num_pips; i++) { PipId curr; curr.location = loc; curr.index = i; - pip_by_name[getPipName(curr)[0]] = curr; + pip_by_name[getPipName(curr)] = curr; } - if (pip_by_name.find(name_id) == pip_by_name.end()) - NPNR_ASSERT_FALSE_STR("no pip named " + name_id.str(this)); - return pip_by_name[name_id]; + if (pip_by_name.find(name) == pip_by_name.end()) + NPNR_ASSERT_FALSE_STR("no pip named " + name.str(getCtx())); + return pip_by_name[name]; } IdStringList Arch::getPipName(PipId pip) const { - NPNR_ASSERT(pip != PipId()); - - int x = pip.location.x; - int y = pip.location.y; - - std::string src_name = getWireName(getPipSrcWire(pip)).str(getCtx()); - std::replace(src_name.begin(), src_name.end(), '/', '.'); - - std::string dst_name = getWireName(getPipDstWire(pip)).str(getCtx()); - std::replace(dst_name.begin(), dst_name.end(), '/', '.'); - - return IdStringList(id("X" + std::to_string(x) + "/Y" + std::to_string(y) + "/" + src_name + ".->." + dst_name)); + auto &pip_data = tileInfo(pip)->pips_data[pip.index]; + WireId src = getPipSrcWire(pip), dst = getPipDstWire(pip); + const char *src_name = tileInfo(src)->wire_data[src.index].name.get(); + const char *dst_name = tileInfo(dst)->wire_data[dst.index].name.get(); + std::string pip_name = + stringf("%d_%d_%s->%d_%d_%s", pip_data.src.x - pip.location.x, pip_data.src.y - pip.location.y, src_name, + pip_data.dst.x - pip.location.x, pip_data.dst.y - pip.location.y, dst_name); + + std::array ids{x_ids.at(pip.location.x), y_ids.at(pip.location.y), id(pip_name)}; + return IdStringList(ids); } // --------------------------------------------------------------- -- cgit v1.2.3 From 8f5133d8111d83137195b8cdae5d80747f8ee315 Mon Sep 17 00:00:00 2001 From: gatecat Date: Thu, 11 Feb 2021 13:46:29 +0000 Subject: machxo2: Use snake_case for non-ArchAPI functions Signed-off-by: gatecat --- machxo2/arch.cc | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index c2b2e0ad..21129f07 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -109,7 +109,7 @@ Arch::Arch(ArchArgs args) : args(args) } } -bool Arch::isAvailable(ArchArgs::ArchArgsTypes chip) { return get_chip_info(chip) != nullptr; } +bool Arch::is_available(ArchArgs::ArchArgsTypes chip) { return get_chip_info(chip) != nullptr; } std::string Arch::getChipName() const { @@ -130,7 +130,7 @@ std::string Arch::getChipName() const } } -std::string Arch::getFullChipName() const +std::string Arch::get_full_chip_name() const { std::string name = getChipName(); name += "-"; @@ -187,7 +187,7 @@ BelId Arch::getBelByName(IdStringList name) const loc.x = id_to_x.at(name[0]); loc.y = id_to_y.at(name[1]); ret.location = loc; - const TileTypePOD *loci = tileInfo(ret); + const TileTypePOD *loci = tile_info(ret); for (int i = 0; i < loci->num_bels; i++) { if (std::strcmp(loci->bel_data[i].name.get(), name[2].c_str(this)) == 0) { ret.index = i; @@ -207,7 +207,7 @@ BelId Arch::getBelByLocation(Loc loc) const ret.location.x = loc.x; ret.location.y = loc.y; - const TileTypePOD *tilei = tileInfo(ret); + const TileTypePOD *tilei = tile_info(ret); for (int i = 0; i < tilei->num_bels; i++) { if (tilei->bel_data[i].z == loc.z) { ret.index = i; @@ -241,8 +241,8 @@ WireId Arch::getBelPinWire(BelId bel, IdString pin) const { NPNR_ASSERT(bel != BelId()); - int num_bel_wires = tileInfo(bel)->bel_data[bel.index].num_bel_wires; - const BelWirePOD *bel_wires = &*tileInfo(bel)->bel_data[bel.index].bel_wires; + int num_bel_wires = tile_info(bel)->bel_data[bel.index].num_bel_wires; + const BelWirePOD *bel_wires = &*tile_info(bel)->bel_data[bel.index].bel_wires; for (int i = 0; i < num_bel_wires; i++) if (bel_wires[i].port == pin.index) { @@ -262,8 +262,8 @@ PortType Arch::getBelPinType(BelId bel, IdString pin) const { NPNR_ASSERT(bel != BelId()); - int num_bel_wires = tileInfo(bel)->bel_data[bel.index].num_bel_wires; - const BelWirePOD *bel_wires = &*tileInfo(bel)->bel_data[bel.index].bel_wires; + int num_bel_wires = tile_info(bel)->bel_data[bel.index].num_bel_wires; + const BelWirePOD *bel_wires = &*tile_info(bel)->bel_data[bel.index].bel_wires; for (int i = 0; i < num_bel_wires; i++) if (bel_wires[i].port == pin.index) @@ -277,8 +277,8 @@ std::vector Arch::getBelPins(BelId bel) const std::vector ret; NPNR_ASSERT(bel != BelId()); - int num_bel_wires = tileInfo(bel)->bel_data[bel.index].num_bel_wires; - const BelWirePOD *bel_wires = &*tileInfo(bel)->bel_data[bel.index].bel_wires; + int num_bel_wires = tile_info(bel)->bel_data[bel.index].num_bel_wires; + const BelWirePOD *bel_wires = &*tile_info(bel)->bel_data[bel.index].bel_wires; for (int i = 0; i < num_bel_wires; i++) { IdString id(bel_wires[i].port); @@ -314,7 +314,7 @@ WireId Arch::getWireByName(IdStringList name) const loc.x = id_to_x.at(name[0]); loc.y = id_to_y.at(name[1]); ret.location = loc; - const TileTypePOD *loci = tileInfo(ret); + const TileTypePOD *loci = tile_info(ret); for (int i = 0; i < loci->num_wires; i++) { if (std::strcmp(loci->wire_data[i].name.get(), name[2].c_str(this)) == 0) { ret.index = i; @@ -340,7 +340,7 @@ PipId Arch::getPipByName(IdStringList name) const loc.x = id_to_x.at(name[0]); loc.y = id_to_y.at(name[1]); ret.location = loc; - const TileTypePOD *loci = tileInfo(ret); + const TileTypePOD *loci = tile_info(ret); for (int i = 0; i < loci->num_pips; i++) { PipId curr; curr.location = loc; @@ -354,10 +354,10 @@ PipId Arch::getPipByName(IdStringList name) const IdStringList Arch::getPipName(PipId pip) const { - auto &pip_data = tileInfo(pip)->pips_data[pip.index]; + auto &pip_data = tile_info(pip)->pips_data[pip.index]; WireId src = getPipSrcWire(pip), dst = getPipDstWire(pip); - const char *src_name = tileInfo(src)->wire_data[src.index].name.get(); - const char *dst_name = tileInfo(dst)->wire_data[dst.index].name.get(); + const char *src_name = tile_info(src)->wire_data[src.index].name.get(); + const char *dst_name = tile_info(dst)->wire_data[dst.index].name.get(); std::string pip_name = stringf("%d_%d_%s->%d_%d_%s", pip_data.src.x - pip.location.x, pip_data.src.y - pip.location.y, src_name, pip_data.dst.x - pip.location.x, pip_data.dst.y - pip.location.y, dst_name); @@ -465,9 +465,9 @@ const std::vector Arch::availablePlacers = {"sa", const std::string Arch::defaultRouter = "router1"; const std::vector Arch::availableRouters = {"router1", "router2"}; -bool Arch::cellsCompatible(const CellInfo **cells, int count) const { return false; } +bool Arch::cells_compatible(const CellInfo **cells, int count) const { return false; } -std::vector> Arch::getTilesAtLocation(int row, int col) +std::vector> Arch::get_tiles_at_location(int row, int col) { std::vector> ret; auto &tileloc = chip_info->tile_info[row * chip_info->width + col]; -- cgit v1.2.3 From 33eca9a3d2569f51c24204ea103672a72f63795d Mon Sep 17 00:00:00 2001 From: gatecat Date: Fri, 12 Feb 2021 10:40:03 +0000 Subject: machxo2: Python bindings and stub GUI Signed-off-by: gatecat --- machxo2/arch.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 21129f07..df9b7efc 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -111,6 +111,16 @@ Arch::Arch(ArchArgs args) : args(args) bool Arch::is_available(ArchArgs::ArchArgsTypes chip) { return get_chip_info(chip) != nullptr; } +std::vector Arch::get_supported_packages(ArchArgs::ArchArgsTypes chip) +{ + const ChipInfoPOD *chip_info = get_chip_info(chip); + std::vector pkgs; + for (int i = 0; i < chip_info->num_packages; i++) { + pkgs.push_back(chip_info->package_info[i].name.get()); + } + return pkgs; +} + std::string Arch::getChipName() const { if (args.type == ArchArgs::LCMXO2_256HC) { -- cgit v1.2.3 From 6de733b38c049bf794975551418c5b4fb592cc8c Mon Sep 17 00:00:00 2001 From: gatecat Date: Fri, 12 Feb 2021 10:43:15 +0000 Subject: machxo2: Misc tidying up Signed-off-by: gatecat --- machxo2/arch.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'machxo2/arch.cc') diff --git a/machxo2/arch.cc b/machxo2/arch.cc index df9b7efc..2938f1ba 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -401,7 +401,10 @@ delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const ArcBounds Arch::getRouteBoundingBox(WireId src, WireId dst) const { ArcBounds bb; - + bb.x0 = std::min(src.location.x, dst.location.x); + bb.y0 = std::min(src.location.y, dst.location.y); + bb.x1 = std::max(src.location.x, dst.location.x); + bb.y1 = std::max(src.location.y, dst.location.y); return bb; } -- cgit v1.2.3