aboutsummaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorgatecat <gatecat@ds0.me>2021-02-15 09:58:56 +0000
committergatecat <gatecat@ds0.me>2021-02-15 09:58:56 +0000
commita002ccfbc1b627a8de921e7940e9ffe37dc94ca3 (patch)
treecba53fb43bf9a4eee1eed9f30c31ab4a624d3a25 /generic
parent065f46daeb05a8b12cc663a44410b6da27a8d9e3 (diff)
downloadnextpnr-a002ccfbc1b627a8de921e7940e9ffe37dc94ca3.tar.gz
nextpnr-a002ccfbc1b627a8de921e7940e9ffe37dc94ca3.tar.bz2
nextpnr-a002ccfbc1b627a8de921e7940e9ffe37dc94ca3.zip
generic: Add APIs for controlling cell->bel pin mapping
Signed-off-by: gatecat <gatecat@ds0.me>
Diffstat (limited to 'generic')
-rw-r--r--generic/arch.cc15
-rw-r--r--generic/arch.h7
-rw-r--r--generic/arch_pybindings.cc8
-rw-r--r--generic/archdefs.h2
4 files changed, 29 insertions, 3 deletions
diff --git a/generic/arch.cc b/generic/arch.cc
index 7cd71179..999e5033 100644
--- a/generic/arch.cc
+++ b/generic/arch.cc
@@ -249,6 +249,12 @@ void Arch::addCellTimingClockToOut(IdString cell, IdString port, IdString clock,
cellTiming[cell].portClasses[port] = TMG_REGISTER_OUTPUT;
}
+void Arch::clearCellBelPinMap(IdString cell, IdString cell_pin) { cells.at(cell)->bel_pins[cell_pin].clear(); }
+void Arch::addCellBelPinMapping(IdString cell, IdString cell_pin, IdString bel_pin)
+{
+ cells.at(cell)->bel_pins[cell_pin].push_back(bel_pin);
+}
+
// ---------------------------------------------------------------
Arch::Arch(ArchArgs args) : chipName("generic"), args(args)
@@ -342,7 +348,10 @@ std::vector<IdString> Arch::getBelPins(BelId bel) const
return ret;
}
-std::array<IdString, 1> Arch::getBelPinsForCellPin(CellInfo *cell_info, IdString pin) const { return {pin}; }
+const std::vector<IdString> &Arch::getBelPinsForCellPin(CellInfo *cell_info, IdString pin) const
+{
+ return cell_info->bel_pins.at(pin);
+}
// ---------------------------------------------------------------
@@ -694,6 +703,10 @@ void Arch::assignArchInfo()
ci->is_slice = false;
}
ci->user_group = int_or_default(ci->attrs, id("PACK_GROUP"), -1);
+ // If no manual cell->bel pin rule has been created; assign a default one
+ for (auto &p : ci->ports)
+ if (!ci->bel_pins.count(p.first))
+ ci->bel_pins.emplace(p.first, std::vector<IdString>{p.first});
}
}
diff --git a/generic/arch.h b/generic/arch.h
index 2a0c7158..007478eb 100644
--- a/generic/arch.h
+++ b/generic/arch.h
@@ -125,7 +125,7 @@ struct ArchRanges
using TileBelsRangeT = const std::vector<BelId> &;
using BelAttrsRangeT = const std::map<IdString, std::string> &;
using BelPinsRangeT = std::vector<IdString>;
- using CellBelPinRangeT = std::array<IdString, 1>;
+ using CellBelPinRangeT = const std::vector<IdString> &;
// Wires
using AllWiresRangeT = const std::vector<WireId> &;
using DownhillPipRangeT = const std::vector<PipId> &;
@@ -207,6 +207,9 @@ struct Arch : ArchAPI<ArchRanges>
void addCellTimingSetupHold(IdString cell, IdString port, IdString clock, DelayInfo setup, DelayInfo hold);
void addCellTimingClockToOut(IdString cell, IdString port, IdString clock, DelayInfo clktoq);
+ void clearCellBelPinMap(IdString cell, IdString cell_pin);
+ void addCellBelPinMapping(IdString cell, IdString cell_pin, IdString bel_pin);
+
// ---------------------------------------------------------------
// Common Arch API. Every arch must provide the following methods.
@@ -244,7 +247,7 @@ struct Arch : ArchAPI<ArchRanges>
WireId getBelPinWire(BelId bel, IdString pin) const override;
PortType getBelPinType(BelId bel, IdString pin) const override;
std::vector<IdString> getBelPins(BelId bel) const override;
- std::array<IdString, 1> getBelPinsForCellPin(CellInfo *cell_info, IdString pin) const override;
+ const std::vector<IdString> &getBelPinsForCellPin(CellInfo *cell_info, IdString pin) const override;
WireId getWireByName(IdStringList name) const override;
IdStringList getWireName(WireId wire) const override;
diff --git a/generic/arch_pybindings.cc b/generic/arch_pybindings.cc
index 3dc04206..35ec3b33 100644
--- a/generic/arch_pybindings.cc
+++ b/generic/arch_pybindings.cc
@@ -226,6 +226,14 @@ void arch_wrap_python(py::module &m)
pass_through<DelayInfo>>::def_wrap(ctx_cls, "addCellTimingClockToOut", "cell"_a, "port"_a,
"clock"_a, "clktoq"_a);
+ fn_wrapper_2a_v<Context, decltype(&Context::clearCellBelPinMap), &Context::clearCellBelPinMap,
+ conv_from_str<IdString>, conv_from_str<IdString>>::def_wrap(ctx_cls, "clearCellBelPinMap", "cell"_a,
+ "cell_pin"_a);
+ fn_wrapper_3a_v<Context, decltype(&Context::addCellBelPinMapping), &Context::addCellBelPinMapping,
+ conv_from_str<IdString>, conv_from_str<IdString>,
+ conv_from_str<IdString>>::def_wrap(ctx_cls, "addCellBelPinMapping", "cell"_a, "cell_pin"_a,
+ "bel_pin"_a);
+
// const\_range\<BelBucketId\> getBelBuckets() const
fn_wrapper_0a<Context, decltype(&Context::getBelBuckets), &Context::getBelBuckets,
wrap_context<const std::vector<BelBucketId> &>>::def_wrap(ctx_cls, "getBelBuckets");
diff --git a/generic/archdefs.h b/generic/archdefs.h
index fad36894..30503414 100644
--- a/generic/archdefs.h
+++ b/generic/archdefs.h
@@ -68,6 +68,8 @@ struct ArchCellInfo
bool is_slice;
// Only packing rule for slice type primitives is a single clock per tile
const NetInfo *slice_clk;
+ // Cell to bel pin mapping
+ std::unordered_map<IdString, std::vector<IdString>> bel_pins;
};
NEXTPNR_NAMESPACE_END