Added checking if all FFs added to an existing cluster have matching configuration
Signed-off-by: Maciej Kurc <mkurc@antmicro.com>
This commit is contained in:
parent
238da79e52
commit
41accf84ce
@ -2304,6 +2304,23 @@ struct NexusPacker
|
||||
}
|
||||
}
|
||||
|
||||
FFControlSet gather_ff_settings(CellInfo* cell) {
|
||||
NPNR_ASSERT(cell->type == id_OXIDE_FF);
|
||||
|
||||
FFControlSet ctrlset;
|
||||
ctrlset.async = str_or_default(cell->params, id_SRMODE, "LSR_OVER_CE") == "ASYNC";
|
||||
ctrlset.regddr_en = is_enabled(cell, id_REGDDR);
|
||||
ctrlset.gsr_en = is_enabled(cell, id_GSR);
|
||||
ctrlset.clkmux = ctx->id(str_or_default(cell->params, id_CLKMUX, "CLK")).index;
|
||||
ctrlset.cemux = ctx->id(str_or_default(cell->params, id_CEMUX, "CE")).index;
|
||||
ctrlset.lsrmux = ctx->id(str_or_default(cell->params, id_LSRMUX, "LSR")).index;
|
||||
ctrlset.clk = get_net_or_empty(cell, id_CLK);
|
||||
ctrlset.ce = get_net_or_empty(cell, id_CE);
|
||||
ctrlset.lsr = get_net_or_empty(cell, id_LSR);
|
||||
|
||||
return ctrlset;
|
||||
}
|
||||
|
||||
void pack_lutffs () {
|
||||
log_info("Inferring LUT+FF pairs...\n");
|
||||
|
||||
@ -2312,6 +2329,12 @@ struct NexusPacker
|
||||
carry_ratio = ctx->setting<float>("carry_lutff_ratio");
|
||||
}
|
||||
|
||||
// FF control settings/signals are slice-wide. The dict below is used
|
||||
// to track settings of FFs glued to clusters which may span more than
|
||||
// one slice (eg. carry-chains). For now it is assumed that all FFs
|
||||
// in one cluster share the same settings and control signals.
|
||||
dict<IdString, FFControlSet> cluster_ffinfo;
|
||||
|
||||
size_t num_comb = 0;
|
||||
size_t num_ff = 0;
|
||||
size_t num_pair = 0;
|
||||
@ -2364,6 +2387,9 @@ struct NexusPacker
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get FF settings
|
||||
auto ffinfo = gather_ff_settings(ff);
|
||||
|
||||
// A free LUT, create a new cluster
|
||||
if (lut->cluster == ClusterId()) {
|
||||
|
||||
@ -2381,6 +2407,19 @@ struct NexusPacker
|
||||
// Attach the FF to the existing cluster of the LUT
|
||||
else {
|
||||
|
||||
// Check if the FF settings match those of others in this
|
||||
// cluster. If not then reject this FF.
|
||||
//
|
||||
// This is a greedy approach - the first attached FF will
|
||||
// enforce its settings on all following candidates. A better
|
||||
// approach would be to first form groups of matching FFs for
|
||||
// a cluster and then attach only the largest group to it.
|
||||
if (cluster_ffinfo.count(lut->cluster)) {
|
||||
if (ffinfo != cluster_ffinfo.at(lut->cluster)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// No order not to make too large carry clusters pack only the
|
||||
// given fraction of FFs there.
|
||||
if(str_or_default(lut->params, id_MODE, "LOGIC") == "CCU2") {
|
||||
@ -2407,6 +2446,11 @@ struct NexusPacker
|
||||
// Reconnect M to DI
|
||||
rename_port(ctx, ff, id_M, id_DI);
|
||||
ff->params[id_SEL] = std::string("DL");
|
||||
|
||||
// Store FF settings of the cluster
|
||||
if (!cluster_ffinfo.count(lut->cluster)) {
|
||||
cluster_ffinfo.emplace(lut->cluster, ffinfo);
|
||||
}
|
||||
}
|
||||
|
||||
// Count OXIDE_COMB, OXIDE_FF are already counted
|
||||
|
Loading…
Reference in New Issue
Block a user