Merge pull request #584 from YosysHQ/gatecat/generic-belpin

Add bel pin mapping control to nextpnr-generic
This commit is contained in:
gatecat 2021-02-15 16:19:25 +00:00 committed by GitHub
commit 9fc02041fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 41 additions and 6 deletions

View File

@ -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

View File

@ -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.

View File

@ -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});
}
}

View File

@ -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;

View File

@ -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");

View File

@ -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

2
tests

@ -1 +1 @@
Subproject commit 31648368460b9e216479ce7c38e6fed883c380c4
Subproject commit 7673d60124707346de001367afcbab6be466f405