aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml1
-rw-r--r--docs/generic.md12
-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
m---------tests0
7 files changed, 40 insertions, 5 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index f7181fd3..b7ff1891 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -8,6 +8,7 @@ task:
submodule_script: git submodule sync --recursive && git submodule update --init --recursive
build_script: mkdir build && cd build && cmake .. -DARCH=all+alpha -DOXIDE_INSTALL_PREFIX=$HOME/.cargo -DBUILD_TESTS=on -DBUILD_GUI=on && make -j3
test_generic_script: cd build && ./nextpnr-generic-test
+ flow_test_generic_script: export NPNR=$(pwd)/build/nextpnr-generic && cd tests/generic/flow && ./run.sh
test_ice40_script: cd build && ./nextpnr-ice40-test
smoketest_ice40_script: export NEXTPNR=$(pwd)/build/nextpnr-ice40 && cd ice40/smoketest/attosoc && ./smoketest.sh
test_ecp5_script: cd build && ./nextpnr-ecp5-test
diff --git a/docs/generic.md b/docs/generic.md
index 5ea4804d..5c079a7b 100644
--- a/docs/generic.md
+++ b/docs/generic.md
@@ -28,9 +28,9 @@ Adds a pip (programmable connection between two named wires). Pip delays that co
Loc is constructed using `Loc(x, y, z)`. 'z' for pips is only important if region constraints (e.g. for partial reconfiguration regions) are used.
-### void addBel(IdString name, IdString type, Loc loc, bool gb);
+### void addBel(IdString name, IdString type, Loc loc, bool gb, bool hidden);
-Adds a bel to the FPGA description. Bel type should match the type of cells in the netlist that are placed at this bel (see below for information on special bel types supported by the packer). Loc is constructed using `Loc(x, y, z)` and must be unique.
+Adds a bel to the FPGA description. Bel type should match the type of cells in the netlist that are placed at this bel (see below for information on special bel types supported by the packer). Loc is constructed using `Loc(x, y, z)` and must be unique. If `hidden` is true, then the bel will not be included in utilisation reports (e.g. for routing/internal use bels).
### void addBelInput(IdString bel, IdString name, IdString wire);
### void addBelOutput(IdString bel, IdString name, IdString wire);
@@ -90,6 +90,14 @@ Specify setup and hold timings for a port of a cell, and set the timing class of
Specify clock-to-out time for a port of a cell, and set the timing class of that port as register output.
+### void clearCellBelPinMap(IdString cell, IdString cell_pin);
+
+Remove all bel pin mappings from a given cell pin.
+
+### addCellBelPinMapping(IdString cell, IdString cell_pin, IdString bel_pin);
+
+Add a bel pin to the list of bel pins a cell pin maps to. Note that if no mappings are set up (the usual case), cell pins are assumed to map to an identically named bel pin.
+
## Generic Packer
The generic packer combines K-input LUTs (`LUT` cells) and simple D-type flip flops (`DFF` cells) (posedge clock only, no set/reset or enable) into a `GENERIC_SLICE` cell. It also inserts `GENERIC_IOB`s onto any top level IO pins without an IO buffer. Constrained IOBs can be implemented by instantiating `GENERIC_IOB` and setting the `BEL` attribute to an IO location.
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
diff --git a/tests b/tests
-Subproject 31648368460b9e216479ce7c38e6fed883c380c
+Subproject 7673d60124707346de001367afcbab6be466f40