Merge pull request #584 from YosysHQ/gatecat/generic-belpin
Add bel pin mapping control to nextpnr-generic
This commit is contained in:
commit
9fc02041fe
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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
2
tests
@ -1 +1 @@
|
||||
Subproject commit 31648368460b9e216479ce7c38e6fed883c380c4
|
||||
Subproject commit 7673d60124707346de001367afcbab6be466f405
|
Loading…
Reference in New Issue
Block a user