aboutsummaryrefslogtreecommitdiffstats
path: root/common/kernel/basectx.cc
diff options
context:
space:
mode:
authorgatecat <gatecat@ds0.me>2022-06-23 18:48:31 +0100
committergatecat <gatecat@ds0.me>2022-07-08 14:30:57 +0200
commit09e388f453d9cf998391495349c88e5478b62e34 (patch)
tree004f2b14ed5a3b0584c4998d9f0a5598cc52ab28 /common/kernel/basectx.cc
parent86396c41d64d2583ec1dffca4298e83d927f0762 (diff)
downloadnextpnr-09e388f453d9cf998391495349c88e5478b62e34.tar.gz
nextpnr-09e388f453d9cf998391495349c88e5478b62e34.tar.bz2
nextpnr-09e388f453d9cf998391495349c88e5478b62e34.zip
netlist: Add PseudoCell API
When implementing concepts such as partition pins or deliberately split nets, there's a need for something that looks like a cell (starts/ends routing with pins on nets, has timing data) but isn't mapped to a fixed bel in the architecture, but instead can have pin mappings defined at runtime. The PseudoCell allows this by providing an alternate, virtual-function based API for such cells. When a cell has `pseudo_cell` used, instead of calling functions such as getBelPinWire, getBelLocation or getCellDelay in the Arch API; such data is provided by the cell itself, fully flexible at runtime regardless of arch, via methods on the PseudoCell implementation.
Diffstat (limited to 'common/kernel/basectx.cc')
-rw-r--r--common/kernel/basectx.cc24
1 files changed, 24 insertions, 0 deletions
diff --git a/common/kernel/basectx.cc b/common/kernel/basectx.cc
index 83a2deea..82cdd835 100644
--- a/common/kernel/basectx.cc
+++ b/common/kernel/basectx.cc
@@ -131,6 +131,30 @@ void BaseCtx::constrainCellToRegion(IdString cell, IdString region_name)
if (!matched)
log_warning("No cell matched '%s' when constraining to region '%s'\n", nameOf(cell), nameOf(region_name));
}
+
+void BaseCtx::createRegionPlug(IdString name, IdString type, Loc approx_loc)
+{
+ CellInfo *cell = nullptr;
+ if (cells.count(name))
+ cell = cells.at(name).get();
+ else
+ cell = createCell(name, type);
+ cell->pseudo_cell = std::make_unique<RegionPlug>(approx_loc);
+}
+
+void BaseCtx::addPlugPin(IdString plug, IdString pin, PortType dir, WireId wire)
+{
+ if (!cells.count(plug))
+ log_error("no cell named '%s' found\n", plug.c_str(this));
+ CellInfo *ci = cells.at(plug).get();
+ RegionPlug *rplug = dynamic_cast<RegionPlug *>(ci->pseudo_cell.get());
+ if (!rplug)
+ log_error("cell '%s' is not a RegionPlug\n", plug.c_str(this));
+ rplug->port_wires[pin] = wire;
+ ci->ports[pin].name = pin;
+ ci->ports[pin].type = dir;
+}
+
DecalXY BaseCtx::constructDecalXY(DecalId decal, float x, float y)
{
DecalXY dxy;