aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--common/timing_opt.cc7
-rw-r--r--machxo2/.gitignore1
-rw-r--r--machxo2/arch.cc105
-rw-r--r--machxo2/arch.h426
-rw-r--r--machxo2/archdefs.h1
-rw-r--r--machxo2/bitstream.cc36
-rw-r--r--machxo2/cells.cc5
-rw-r--r--machxo2/pack.cc5
9 files changed, 119 insertions, 468 deletions
diff --git a/.gitignore b/.gitignore
index 9ddd4a4e..eea5bf5c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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);
}