diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | common/timing_opt.cc | 7 | ||||
-rw-r--r-- | machxo2/.gitignore | 1 | ||||
-rw-r--r-- | machxo2/arch.cc | 105 | ||||
-rw-r--r-- | machxo2/arch.h | 426 | ||||
-rw-r--r-- | machxo2/archdefs.h | 1 | ||||
-rw-r--r-- | machxo2/bitstream.cc | 36 | ||||
-rw-r--r-- | machxo2/cells.cc | 5 | ||||
-rw-r--r-- | machxo2/pack.cc | 5 |
9 files changed, 119 insertions, 468 deletions
@@ -6,6 +6,7 @@ /nextpnr-nexus* /nextpnr-fpga_interchange* /nextpnr-gowin* +/nextpnr-machxo2* cmake-build-*/ Makefile cmake_install.cmake diff --git a/common/timing_opt.cc b/common/timing_opt.cc index fc744cac..5b022dd8 100644 --- a/common/timing_opt.cc +++ b/common/timing_opt.cc @@ -39,9 +39,8 @@ namespace std { template <> struct hash<std::pair<NEXTPNR_NAMESPACE_PREFIX IdString, NEXTPNR_NAMESPACE_PREFIX IdString>> { - std::size_t - operator()(const std::pair<NEXTPNR_NAMESPACE_PREFIX IdString, NEXTPNR_NAMESPACE_PREFIX IdString> &idp) const - noexcept + std::size_t operator()( + const std::pair<NEXTPNR_NAMESPACE_PREFIX IdString, NEXTPNR_NAMESPACE_PREFIX IdString> &idp) const noexcept { std::size_t seed = 0; boost::hash_combine(seed, hash<NEXTPNR_NAMESPACE_PREFIX IdString>()(idp.first)); @@ -61,7 +60,7 @@ template <> struct hash<std::pair<int, NEXTPNR_NAMESPACE_PREFIX BelId>> } }; -#if !(defined(ARCH_GENERIC) || defined(ARCH_MACHXO2) || defined(ARCH_GOWIN)) +#if !(defined(ARCH_GENERIC) || defined(ARCH_GOWIN)) template <> struct hash<std::pair<NEXTPNR_NAMESPACE_PREFIX IdString, NEXTPNR_NAMESPACE_PREFIX BelId>> { std::size_t diff --git a/machxo2/.gitignore b/machxo2/.gitignore new file mode 100644 index 00000000..48c9c5ce --- /dev/null +++ b/machxo2/.gitignore @@ -0,0 +1 @@ +chipdb/ 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<GroupId> Arch::getGroups() const -{ - std::vector<GroupId> ret; - return ret; + return IdStringList(id("X" + std::to_string(x) + "/Y" + std::to_string(y) + "/" + src_name + ".->." + dst_name)); } -const std::vector<BelId> &Arch::getGroupBels(GroupId group) const { return bel_id_dummy; } - -const std::vector<WireId> &Arch::getGroupWires(GroupId group) const { return wire_id_dummy; } - -const std::vector<PipId> &Arch::getGroupPips(GroupId group) const { return pip_id_dummy; } - -const std::vector<GroupId> &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<GraphicElement> &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<std::string> Arch::availablePlacers = {"sa", const std::string Arch::defaultRouter = "router1"; const std::vector<std::string> Arch::availableRouters = {"router1", "router2"}; -void Arch::assignArchInfo() {} - bool Arch::cellsCompatible(const CellInfo **cells, int count) const { return false; } std::vector<std::pair<std::string, std::string>> Arch::getTilesAtLocation(int row, int col) diff --git a/machxo2/arch.h b/machxo2/arch.h index 439d54a5..466eca79 100644 --- a/machxo2/arch.h +++ b/machxo2/arch.h @@ -377,109 +377,31 @@ struct ArchArgs } speed = SPEED_4; }; -struct WireInfo; - -struct PipInfo -{ - IdString name, type; - std::map<IdString, std::string> attrs; - NetInfo *bound_net; - WireId srcWire, dstWire; - DelayInfo delay; - DecalXY decalxy; - Loc loc; -}; - -struct WireInfo -{ - IdString name, type; - std::map<IdString, std::string> attrs; - NetInfo *bound_net; - std::vector<PipId> downhill, uphill, aliases; - BelPin uphill_bel_pin; - std::vector<BelPin> downhill_bel_pins; - std::vector<BelPin> bel_pins; - DecalXY decalxy; - int x, y; -}; - -struct PinInfo -{ - IdString name; - WireId wire; - PortType type; -}; - -struct BelInfo -{ - IdString name, type; - std::map<IdString, std::string> attrs; - CellInfo *bound_cell; - std::unordered_map<IdString, PinInfo> pins; - DecalXY decalxy; - int x, y, z; - bool gb; -}; - -struct GroupInfo -{ - IdString name; - std::vector<BelId> bels; - std::vector<WireId> wires; - std::vector<PipId> pips; - std::vector<GroupId> groups; - DecalXY decalxy; -}; - -struct CellDelayKey +struct ArchRanges : BaseArchRanges { - IdString from, to; - inline bool operator==(const CellDelayKey &other) const { return from == other.from && to == other.to; } -}; - -NEXTPNR_NAMESPACE_END -namespace std { -template <> struct hash<NEXTPNR_NAMESPACE_PREFIX CellDelayKey> -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX CellDelayKey &dk) const noexcept - { - std::size_t seed = std::hash<NEXTPNR_NAMESPACE_PREFIX IdString>()(dk.from); - seed ^= std::hash<NEXTPNR_NAMESPACE_PREFIX IdString>()(dk.to) + 0x9e3779b9 + (seed << 6) + (seed >> 2); - return seed; - } -}; -} // namespace std -NEXTPNR_NAMESPACE_BEGIN - -struct CellTiming -{ - std::unordered_map<IdString, TimingPortClass> portClasses; - std::unordered_map<CellDelayKey, DelayInfo> combDelays; - std::unordered_map<IdString, std::vector<TimingClockingInfo>> clockingInfo; + using ArchArgsT = ArchArgs; + // Bels + using AllBelsRangeT = BelRange; + using TileBelsRangeT = BelRange; + using BelPinsRangeT = std::vector<IdString>; + // Wires + using AllWiresRangeT = WireRange; + using DownhillPipRangeT = PipRange; + using UphillPipRangeT = PipRange; + using WireBelPinRangeT = BelPinRange; + // Pips + using AllPipsRangeT = AllPipRange; }; -struct Arch : BaseCtx +struct Arch : BaseArch<ArchRanges> { const ChipInfoPOD *chip_info; const PackageInfoPOD *package_info; - std::vector<CellInfo *> bel_to_cell; - std::unordered_map<WireId, NetInfo *> wire_to_net; - std::unordered_map<PipId, NetInfo *> pip_to_net; - mutable std::unordered_map<IdString, BelId> bel_by_name; mutable std::unordered_map<IdString, WireId> wire_by_name; mutable std::unordered_map<IdString, PipId> pip_by_name; - // Placeholders to be removed. - std::unordered_map<Loc, BelId> bel_by_loc; - std::vector<BelId> bel_id_dummy; - std::vector<BelPin> bel_pin_dummy; - std::vector<WireId> wire_id_dummy; - std::vector<PipId> pip_id_dummy; - std::vector<GroupId> group_id_dummy; - std::vector<GraphicElement> graphic_element_dummy; - // Helpers template <typename Id> const TileTypePOD *tileInfo(Id &id) const { @@ -500,35 +422,35 @@ struct Arch : BaseCtx static bool isAvailable(ArchArgs::ArchArgsTypes chip); - std::string getChipName() const; + std::string getChipName() const override; // Extra helper std::string getFullChipName() const; - IdString archId() const { return id("machxo2"); } - ArchArgs archArgs() const { return args; } - IdString archArgsToId(ArchArgs args) const; + IdString archId() const override { return id("machxo2"); } + ArchArgs archArgs() const override { return args; } + IdString archArgsToId(ArchArgs args) const override; static const int max_loc_bels = 20; - int getGridDimX() const { return chip_info->width; } - int getGridDimY() const { return chip_info->height; } - int getTileBelDimZ(int x, int y) const { return max_loc_bels; } + int getGridDimX() const override { return chip_info->width; } + int getGridDimY() const override { return chip_info->height; } + int getTileBelDimZ(int x, int y) const override { return max_loc_bels; } // TODO: Make more precise? The CENTER MUX having config bits across // tiles can complicate this? - int getTilePipDimZ(int x, int y) const { return 2; } + int getTilePipDimZ(int x, int y) const override { return 2; } // Bels - BelId getBelByName(IdString name) const; + BelId getBelByName(IdStringList name) const override; - IdString getBelName(BelId bel) const + IdStringList getBelName(BelId bel) const override { NPNR_ASSERT(bel != BelId()); std::stringstream name; name << "X" << bel.location.x << "/Y" << bel.location.y << "/" << tileInfo(bel)->bel_data[bel.index].name.get(); - return id(name.str()); + return IdStringList(id(name.str())); } - Loc getBelLocation(BelId bel) const + Loc getBelLocation(BelId bel) const override { NPNR_ASSERT(bel != BelId()); Loc loc; @@ -538,57 +460,11 @@ struct Arch : BaseCtx return loc; } - BelId getBelByLocation(Loc loc) const; - BelRange getBelsByTile(int x, int y) const; - bool getBelGlobalBuf(BelId bel) const; + BelId getBelByLocation(Loc loc) const override; + BelRange getBelsByTile(int x, int y) const override; + bool getBelGlobalBuf(BelId bel) const override; - uint32_t getBelChecksum(BelId bel) const - { - // FIXME- Copied from ECP5. Should be return val from getBelFlatIndex? - return bel.index; - } - - void bindBel(BelId bel, CellInfo *cell, PlaceStrength strength) - { - NPNR_ASSERT(bel != BelId()); - int idx = getBelFlatIndex(bel); - NPNR_ASSERT(bel_to_cell.at(idx) == nullptr); - bel_to_cell[idx] = cell; - cell->bel = bel; - cell->belStrength = strength; - refreshUiBel(bel); - } - - void unbindBel(BelId bel) - { - NPNR_ASSERT(bel != BelId()); - int idx = getBelFlatIndex(bel); - NPNR_ASSERT(bel_to_cell.at(idx) != nullptr); - bel_to_cell[idx]->bel = BelId(); - bel_to_cell[idx]->belStrength = STRENGTH_NONE; - bel_to_cell[idx] = nullptr; - refreshUiBel(bel); - } - - bool checkBelAvail(BelId bel) const - { - NPNR_ASSERT(bel != BelId()); - return bel_to_cell[getBelFlatIndex(bel)] == nullptr; - } - - CellInfo *getBoundBelCell(BelId bel) const - { - NPNR_ASSERT(bel != BelId()); - return bel_to_cell[getBelFlatIndex(bel)]; - } - - CellInfo *getConflictingBelCell(BelId bel) const - { - NPNR_ASSERT(bel != BelId()); - return bel_to_cell[getBelFlatIndex(bel)]; - } - - BelRange getBels() const + BelRange getBels() const override { BelRange range; range.b.cursor_tile = 0; @@ -601,7 +477,7 @@ struct Arch : BaseCtx return range; } - IdString getBelType(BelId bel) const + IdString getBelType(BelId bel) const override { NPNR_ASSERT(bel != BelId()); IdString id; @@ -609,106 +485,28 @@ struct Arch : BaseCtx return id; } - std::vector<std::pair<IdString, std::string>> getBelAttrs(BelId) const - { - std::vector<std::pair<IdString, std::string>> ret; - return ret; - } - - WireId getBelPinWire(BelId bel, IdString pin) const; - PortType getBelPinType(BelId bel, IdString pin) const; - std::vector<IdString> getBelPins(BelId bel) const; + WireId getBelPinWire(BelId bel, IdString pin) const override; + PortType getBelPinType(BelId bel, IdString pin) const override; + std::vector<IdString> getBelPins(BelId bel) const override; // Package BelId getPackagePinBel(const std::string &pin) const; // Wires - WireId getWireByName(IdString name) const; + WireId getWireByName(IdStringList name) const override; - IdString getWireName(WireId wire) const + IdStringList getWireName(WireId wire) const override { NPNR_ASSERT(wire != WireId()); std::stringstream name; name << "X" << wire.location.x << "/Y" << wire.location.y << "/" << tileInfo(wire)->wire_data[wire.index].name.get(); - return id(name.str()); - } - - IdString getWireType(WireId wire) const { return IdString(); } - - std::vector<std::pair<IdString, std::string>> getWireAttrs(WireId) const - { - std::vector<std::pair<IdString, std::string>> ret; - return ret; - } - - uint32_t getWireChecksum(WireId wire) const { return wire.index; } - - void bindWire(WireId wire, NetInfo *net, PlaceStrength strength) - { - NPNR_ASSERT(wire != WireId()); - NPNR_ASSERT(wire_to_net[wire] == nullptr); - wire_to_net[wire] = net; - - // Needs to be set; bindWires is meant for source wires attached - // to a Bel. - net->wires[wire].pip = PipId(); - net->wires[wire].strength = strength; - refreshUiWire(wire); + return IdStringList(id(name.str())); } - void unbindWire(WireId wire) - { - NPNR_ASSERT(wire != WireId()); - NPNR_ASSERT(wire_to_net[wire] != nullptr); - - auto &net_wires = wire_to_net[wire]->wires; - auto it = net_wires.find(wire); - NPNR_ASSERT(it != net_wires.end()); - - // If we have unbound a wire, then the upstream pip is no longer - // used either. - auto pip = it->second.pip; - if (pip != PipId()) { - // TODO: fanout - // wire_fanout[getPipSrcWire(pip)]--; - pip_to_net[pip] = nullptr; - } - - net_wires.erase(it); - wire_to_net[wire] = nullptr; - refreshUiWire(wire); - } + DelayInfo getWireDelay(WireId wire) const override { return DelayInfo(); } - bool checkWireAvail(WireId wire) const - { - NPNR_ASSERT(wire != WireId()); - return wire_to_net.find(wire) == wire_to_net.end() || wire_to_net.at(wire) == nullptr; - } - - NetInfo *getBoundWireNet(WireId wire) const - { - NPNR_ASSERT(wire != WireId()); - if (wire_to_net.find(wire) == wire_to_net.end()) - return nullptr; - else - return wire_to_net.at(wire); - } - - WireId getConflictingWireWire(WireId wire) const { return wire; } - - NetInfo *getConflictingWireNet(WireId wire) const - { - NPNR_ASSERT(wire != WireId()); - if (wire_to_net.find(wire) == wire_to_net.end()) - return nullptr; - else - return wire_to_net.at(wire); - } - - DelayInfo getWireDelay(WireId wire) const { return DelayInfo(); } - - WireRange getWires() const + WireRange getWires() const override { WireRange range; range.b.cursor_tile = 0; @@ -721,7 +519,7 @@ struct Arch : BaseCtx return range; } - BelPinRange getWireBelPins(WireId wire) const + BelPinRange getWireBelPins(WireId wire) const override { BelPinRange range; NPNR_ASSERT(wire != WireId()); @@ -733,85 +531,10 @@ struct Arch : BaseCtx } // Pips - PipId getPipByName(IdString name) const; - IdString getPipName(PipId pip) const; - - IdString getPipType(PipId pip) const { return IdString(); } + PipId getPipByName(IdStringList name) const override; + IdStringList getPipName(PipId pip) const override; - std::vector<std::pair<IdString, std::string>> getPipAttrs(PipId) const - { - std::vector<std::pair<IdString, std::string>> ret; - return ret; - } - - uint32_t getPipChecksum(PipId pip) const { return pip.index; } - - void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) - { - NPNR_ASSERT(pip != PipId()); - NPNR_ASSERT(pip_to_net[pip] == nullptr); - - pip_to_net[pip] = net; - // wire_fanout[getPipSrcWire(pip)]++; - - WireId dst; - dst.index = tileInfo(pip)->pips_data[pip.index].dst_idx; - dst.location = tileInfo(pip)->pips_data[pip.index].dst; - NPNR_ASSERT(wire_to_net[dst] == nullptr); - - // Since NetInfo::wires holds info about uphill pips, bind info about - // this pip to the downhill wire. - wire_to_net[dst] = net; - net->wires[dst].pip = pip; - net->wires[dst].strength = strength; - } - - void unbindPip(PipId pip) - { - NPNR_ASSERT(pip != PipId()); - NPNR_ASSERT(pip_to_net[pip] == nullptr); - - // wire_fanout[getPipSrcWire(pip)]--; - - WireId dst; - dst.index = tileInfo(pip)->pips_data[pip.index].dst_idx; - dst.location = tileInfo(pip)->pips_data[pip.index].dst; - NPNR_ASSERT(wire_to_net[dst] != nullptr); - - // If we unbind a pip, then the downstream wire is no longer in use - // either. - wire_to_net[dst] = nullptr; - pip_to_net[pip]->wires.erase(dst); - pip_to_net[pip] = nullptr; - } - - bool checkPipAvail(PipId pip) const - { - NPNR_ASSERT(pip != PipId()); - return pip_to_net.find(pip) == pip_to_net.end() || pip_to_net.at(pip) == nullptr; - } - - NetInfo *getBoundPipNet(PipId pip) const - { - NPNR_ASSERT(pip != PipId()); - if (pip_to_net.find(pip) == pip_to_net.end()) - return nullptr; - else - return pip_to_net.at(pip); - } - - WireId getConflictingPipWire(PipId pip) const { return WireId(); } - - NetInfo *getConflictingPipNet(PipId pip) const - { - NPNR_ASSERT(pip != PipId()); - if (pip_to_net.find(pip) == pip_to_net.end()) - return nullptr; - else - return pip_to_net.at(pip); - } - - AllPipRange getPips() const + AllPipRange getPips() const override { AllPipRange range; range.b.cursor_tile = 0; @@ -824,7 +547,7 @@ struct Arch : BaseCtx return range; } - Loc getPipLocation(PipId pip) const + Loc getPipLocation(PipId pip) const override { Loc loc; loc.x = pip.location.x; @@ -836,7 +559,7 @@ struct Arch : BaseCtx return loc; } - WireId getPipSrcWire(PipId pip) const + WireId getPipSrcWire(PipId pip) const override { WireId wire; NPNR_ASSERT(pip != PipId()); @@ -845,7 +568,7 @@ struct Arch : BaseCtx return wire; } - WireId getPipDstWire(PipId pip) const + WireId getPipDstWire(PipId pip) const override { WireId wire; NPNR_ASSERT(pip != PipId()); @@ -854,7 +577,7 @@ struct Arch : BaseCtx return wire; } - DelayInfo getPipDelay(PipId pip) const + DelayInfo getPipDelay(PipId pip) const override { DelayInfo delay; @@ -863,7 +586,7 @@ struct Arch : BaseCtx return delay; } - PipRange getPipsDownhill(WireId wire) const + PipRange getPipsDownhill(WireId wire) const override { PipRange range; NPNR_ASSERT(wire != WireId()); @@ -874,7 +597,7 @@ struct Arch : BaseCtx return range; } - PipRange getPipsUphill(WireId wire) const + PipRange getPipsUphill(WireId wire) const override { PipRange range; NPNR_ASSERT(wire != WireId()); @@ -898,56 +621,32 @@ struct Arch : BaseCtx NPNR_ASSERT_FALSE("failed to find Pip tile"); } - // Group - GroupId getGroupByName(IdString name) const; - IdString getGroupName(GroupId group) const; - std::vector<GroupId> getGroups() const; - const std::vector<BelId> &getGroupBels(GroupId group) const; - const std::vector<WireId> &getGroupWires(GroupId group) const; - const std::vector<PipId> &getGroupPips(GroupId group) const; - const std::vector<GroupId> &getGroupGroups(GroupId group) const; - // Delay - delay_t estimateDelay(WireId src, WireId dst) const; - delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const; - delay_t getDelayEpsilon() const { return 0.001; } - delay_t getRipupDelayPenalty() const { return 0.015; } - float getDelayNS(delay_t v) const { return v; } + delay_t estimateDelay(WireId src, WireId dst) const override; + delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const override; + delay_t getDelayEpsilon() const override { return 0.001; } + delay_t getRipupDelayPenalty() const override { return 0.015; } + float getDelayNS(delay_t v) const override { return v; } - DelayInfo getDelayFromNS(float ns) const + DelayInfo getDelayFromNS(float ns) const override { DelayInfo del; del.delay = ns; return del; } - uint32_t getDelayChecksum(delay_t v) const { return 0; } - bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const; + uint32_t getDelayChecksum(delay_t v) const override { return v; } - ArcBounds getRouteBoundingBox(WireId src, WireId dst) const; + ArcBounds getRouteBoundingBox(WireId src, WireId dst) const override; // Flow - bool pack(); - bool place(); - bool route(); - - // Graphics - const std::vector<GraphicElement> &getDecalGraphics(DecalId decal) const; - DecalXY getBelDecal(BelId bel) const; - DecalXY getWireDecal(WireId wire) const; - DecalXY getPipDecal(PipId pip) const; - DecalXY getGroupDecal(GroupId group) const; - - // Cell Delay - bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const; - // Get the port class, also setting clockInfoCount to the number of TimingClockingInfos associated with a port - TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const; - // Get the TimingClockingInfo of a port - TimingClockingInfo getPortClockingInfo(const CellInfo *cell, IdString port, int index) const; + bool pack() override; + bool place() override; + bool route() override; // Placer - bool isValidBelForCell(CellInfo *cell, BelId bel) const; - bool isBelLocationValid(BelId bel) const; + bool isValidBelForCell(CellInfo *cell, BelId bel) const override; + bool isBelLocationValid(BelId bel) const override; static const std::string defaultPlacer; static const std::vector<std::string> availablePlacers; @@ -956,7 +655,6 @@ struct Arch : BaseCtx // --------------------------------------------------------------- // Internal usage - void assignArchInfo(); bool cellsCompatible(const CellInfo **cells, int count) const; std::vector<std::pair<std::string, std::string>> getTilesAtLocation(int row, int col); diff --git a/machxo2/archdefs.h b/machxo2/archdefs.h index 9b62a6c3..caa15ece 100644 --- a/machxo2/archdefs.h +++ b/machxo2/archdefs.h @@ -119,6 +119,7 @@ struct PipId typedef IdString GroupId; typedef IdString DecalId; +typedef IdString BelBucketId; struct ArchNetInfo { diff --git a/machxo2/bitstream.cc b/machxo2/bitstream.cc index a095333a..1711326f 100644 --- a/machxo2/bitstream.cc +++ b/machxo2/bitstream.cc @@ -60,24 +60,15 @@ static std::string get_trellis_wirename(Context *ctx, Location loc, WireId wire) // Handle MachXO2's wonderful naming quirks for wires in left/right tiles, whose // relative coords push them outside the bounds of the chip. auto is_pio_wire = [](std::string name) { - return ( - name.find("DI") != std::string::npos || - name.find("JDI") != std::string::npos || - name.find("PADD") != std::string::npos || - name.find("INDD") != std::string::npos || - name.find("IOLDO") != std::string::npos || - name.find("IOLTO") != std::string::npos || - name.find("JCE") != std::string::npos || - name.find("JCLK") != std::string::npos || - name.find("JLSR") != std::string::npos || - name.find("JONEG") != std::string::npos || - name.find("JOPOS") != std::string::npos || - name.find("JTS") != std::string::npos || - name.find("JIN") != std::string::npos || - name.find("JIP") != std::string::npos || - // Connections to global mux - name.find("JINCK") != std::string::npos - ); + return (name.find("DI") != std::string::npos || name.find("JDI") != std::string::npos || + name.find("PADD") != std::string::npos || name.find("INDD") != std::string::npos || + name.find("IOLDO") != std::string::npos || name.find("IOLTO") != std::string::npos || + name.find("JCE") != std::string::npos || name.find("JCLK") != std::string::npos || + name.find("JLSR") != std::string::npos || name.find("JONEG") != std::string::npos || + name.find("JOPOS") != std::string::npos || name.find("JTS") != std::string::npos || + name.find("JIN") != std::string::npos || name.find("JIP") != std::string::npos || + // Connections to global mux + name.find("JINCK") != std::string::npos); }; if (prefix2 == "G_" || prefix2 == "L_" || prefix2 == "R_" || prefix2 == "U_" || prefix2 == "D_" || @@ -85,10 +76,10 @@ static std::string get_trellis_wirename(Context *ctx, Location loc, WireId wire) return basename; if (loc == wire.location) { // TODO: JINCK is not currently handled by this. - if(is_pio_wire(basename)) { - if(wire.location.x == 0) + if (is_pio_wire(basename)) { + if (wire.location.x == 0) return "W1_" + basename; - else if(wire.location.x == max_col) + else if (wire.location.x == max_col) return "E1_" + basename; } return basename; @@ -200,7 +191,8 @@ void write_bitstream(Context *ctx, std::string text_config_file) for (auto &cell : ctx->cells) { CellInfo *ci = cell.second.get(); if (ci->bel == BelId()) { - log_warning("found unplaced cell '%s' during bitstream gen. Not writing to bitstream.\n", ci->name.c_str(ctx)); + log_warning("found unplaced cell '%s' during bitstream gen. Not writing to bitstream.\n", + ci->name.c_str(ctx)); continue; } BelId bel = ci->bel; diff --git a/machxo2/cells.cc b/machxo2/cells.cc index 5dea36e2..03ba0a41 100644 --- a/machxo2/cells.cc +++ b/machxo2/cells.cc @@ -165,8 +165,9 @@ void dff_to_lc(Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_lut) // If a register's DI port is fed by a constant, options for placing are // limited. Use the LUT to get around this. - if(pass_thru_lut) { - lc->params[ctx->id("LUT0_INITVAL")] = Property(0xAAAA, 16);; + if (pass_thru_lut) { + lc->params[ctx->id("LUT0_INITVAL")] = Property(0xAAAA, 16); + ; replace_port(dff, ctx->id("DI"), lc, ctx->id("A0")); connect_ports(ctx, lc, ctx->id("F0"), lc, ctx->id("DI0")); } else { diff --git a/machxo2/pack.cc b/machxo2/pack.cc index c745a1c0..5a6cd97b 100644 --- a/machxo2/pack.cc +++ b/machxo2/pack.cc @@ -138,7 +138,7 @@ static void set_net_constant(Context *ctx, NetInfo *orig, NetInfo *constnet, boo if (ctx->verbose) log_info("%s user %s\n", orig->name.c_str(ctx), uc->name.c_str(ctx)); - if(uc->type == id_FACADE_FF && user.port == id_DI) { + if (uc->type == id_FACADE_FF && user.port == id_DI) { log_info("FACADE_FF %s is driven by a constant\n", uc->name.c_str(ctx)); std::unique_ptr<CellInfo> lc = create_machxo2_cell(ctx, id_FACADE_SLICE, uc->name.str(ctx) + "_CONST"); @@ -262,8 +262,7 @@ static void pack_io(Context *ctx) log_error("IO buffer '%s' constrained to pin '%s', which does not exist for package '%s'.\n", ci->name.c_str(ctx), pin.c_str(), ctx->args.package.c_str()); } else { - log_info("pin '%s' constrained to Bel '%s'.\n", ci->name.c_str(ctx), - ctx->getBelName(pinBel).c_str(ctx)); + log_info("pin '%s' constrained to Bel '%s'.\n", ci->name.c_str(ctx), ctx->nameOfBel(pinBel)); } ci->attrs[ctx->id("BEL")] = ctx->getBelName(pinBel).str(ctx); } |