From 7229fb73f587562b0a8d5ffd17ddf97a729bd705 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 7 Aug 2024 12:20:34 +0200 Subject: [PATCH] Pack LUT and multiple DFF in stripe --- himbaechel/uarch/ng-ultra/extra_data.h | 1 + himbaechel/uarch/ng-ultra/location_map.cc | 9 +++ himbaechel/uarch/ng-ultra/location_map.h | 1 + himbaechel/uarch/ng-ultra/ng_ultra.cc | 1 + himbaechel/uarch/ng-ultra/pack.cc | 88 +++++++++++++++++++++++ himbaechel/uarch/ng-ultra/pack.h | 1 + 6 files changed, 101 insertions(+) diff --git a/himbaechel/uarch/ng-ultra/extra_data.h b/himbaechel/uarch/ng-ultra/extra_data.h index 1164d7ce..87957296 100644 --- a/himbaechel/uarch/ng-ultra/extra_data.h +++ b/himbaechel/uarch/ng-ultra/extra_data.h @@ -205,6 +205,7 @@ enum ClusterPlacement PLACE_FIFO_REQ1, PLACE_FIFO_WEQ2, PLACE_FIFO_REQ2, + PLACE_LUT_CHAIN, }; enum PipExtra diff --git a/himbaechel/uarch/ng-ultra/location_map.cc b/himbaechel/uarch/ng-ultra/location_map.cc index 0a83379c..83123030 100644 --- a/himbaechel/uarch/ng-ultra/location_map.cc +++ b/himbaechel/uarch/ng-ultra/location_map.cc @@ -471,6 +471,15 @@ Loc getNextLocInCYChain(Loc loc) return result; } +Loc getNextLocInLutChain(Loc loc) +{ + Loc result = loc; + result.x = loc.x; + result.y = loc.y; + result.z = (loc.z + 8) % 32; // BEL_LUT_Z is 0 + return result; +} + Loc getCYFE(Loc root, int pos) { int p[] = { 2-1, 25-1, 10-1, 17-1 }; diff --git a/himbaechel/uarch/ng-ultra/location_map.h b/himbaechel/uarch/ng-ultra/location_map.h index 0547260a..0745d8a1 100644 --- a/himbaechel/uarch/ng-ultra/location_map.h +++ b/himbaechel/uarch/ng-ultra/location_map.h @@ -29,6 +29,7 @@ namespace ng_ultra { Loc getNextLocInDSPChain(const NgUltraImpl *impl, Loc loc); Loc getNextLocInCYChain(Loc loc); +Loc getNextLocInLutChain(Loc loc); Loc getCYFE(Loc root, int pos); Loc getXLUTFE(Loc root, int pos); Loc getXRFFE(Loc root, int pos); diff --git a/himbaechel/uarch/ng-ultra/ng_ultra.cc b/himbaechel/uarch/ng-ultra/ng_ultra.cc index 6835f8f9..643ec6d5 100644 --- a/himbaechel/uarch/ng-ultra/ng_ultra.cc +++ b/himbaechel/uarch/ng-ultra/ng_ultra.cc @@ -644,6 +644,7 @@ bool NgUltraImpl::getChildPlacement(const BaseClusterInfo *cluster, Loc root_loc Loc child_loc = if_using_basecluster(child, [&](const BaseClusterInfo *child) { switch(child->constr_z) { case PLACE_CY_CHAIN : { Loc l = getNextLocInCYChain(prev); prev = l; return l; } + case PLACE_LUT_CHAIN : { Loc l = getNextLocInLutChain(prev); prev = l; return l; } case PLACE_CY_FE1 ... PLACE_CY_FE4: return getCYFE(root_loc, child->constr_z - PLACE_CY_FE1 ); case PLACE_XLUT_FE1 ... PLACE_XLUT_FE4: return getXLUTFE(root_loc, child->constr_z - PLACE_XLUT_FE1 ); case PLACE_XRF_I1 ... PLACE_XRF_WEA: diff --git a/himbaechel/uarch/ng-ultra/pack.cc b/himbaechel/uarch/ng-ultra/pack.cc index 25dbe878..e53e82fa 100644 --- a/himbaechel/uarch/ng-ultra/pack.cc +++ b/himbaechel/uarch/ng-ultra/pack.cc @@ -382,6 +382,93 @@ void NgUltraPacker::pack_xluts(void) flush_cells(); } +void NgUltraPacker::pack_lut_multi_dffs(void) +{ + log_info("Pack LUT-multi DFFs...\n"); + + int dff_only = 0, lut_and_ff = 0, bff_only = 0;; + for (auto &cell : ctx->cells) { + CellInfo &ci = *cell.second; + if (!ci.type.in(id_NX_LUT)) + continue; + if (!ci.params.count(id_lut_table)) + log_error("Cell '%s' missing lut_table\n", ci.name.c_str(ctx)); + + NetInfo *o = ci.getPort(id_O); + if (o) { + if (o->users.entries()<2) continue; + + int cnt = 0; + for (auto u : o->users) + { + if (u.cell->type == id_NX_DFF && u.cell->getPort(id_I) == o) + cnt++; + } + if (cnt<2) continue; + + CellInfo *root = create_cell_ptr(id_BEYOND_FE, ctx->id(ci.name.str(ctx) + "$fe")); + packed_cells.insert(ci.name); + bind_attr_loc(root, &ci.attrs); + lut_to_fe(&ci, root, false, ci.params[id_lut_table]); + root->cluster = root->name; + + int max_use = (cnt==4 && o->users.entries()==4) ? 4 : 3; + bool use_bff = max_use!=4 && cnt>=4; + int i = 0; + std::vector users; + for (auto u : o->users) + { + if (u.cell->type == id_NX_DFF && u.cell->getPort(id_I) == o) { + if (i==0) { + packed_cells.insert(u.cell->name); + dff_to_fe(u.cell, root, false); + ++lut_and_ff; + } else if (i < max_use) { + packed_cells.insert(u.cell->name); + CellInfo *new_cell = create_cell_ptr(id_BEYOND_FE, ctx->id(u.cell->name.str(ctx) + "$fe")); + dff_to_fe(u.cell, new_cell, false); + root->constr_children.push_back(new_cell); + new_cell->cluster = root->cluster; + new_cell->constr_z = PLACE_LUT_CHAIN; + ++dff_only; + } else { + use_bff = true; + users.push_back(u); + u.cell->disconnectPort(u.port); + } + i++; + } else { + use_bff = true; + users.push_back(u); + u.cell->disconnectPort(u.port); + } + } + if (use_bff) { + CellInfo *new_cell = create_cell_ptr(id_BEYOND_FE, ctx->id(ci.name.str(ctx) + "$bff")); + new_cell->params[id_dff_used] = Property(1,1); + new_cell->setParam(ctx->id("type"), Property("BFF")); + new_cell->connectPort(id_DI, o); + root->constr_children.push_back(new_cell); + new_cell->cluster = root->cluster; + new_cell->constr_z = PLACE_LUT_CHAIN; + bff_only++; + NetInfo *new_out = ctx->createNet(ctx->id(o->name.str(ctx) + "$new")); + new_cell->connectPort(id_DO, new_out); + for(auto &user : users) { + user.cell->connectPort(user.port, new_out); + } + } + } + } + if (dff_only) + log_info(" %6d FEs used as DFF only\n", dff_only); + if (bff_only) + log_info(" %6d FEs used as BFF only\n", bff_only); + if (lut_and_ff) + log_info(" %6d FEs used as LUT and DFF\n", lut_and_ff); + flush_cells(); +} + void NgUltraPacker::pack_lut_dffs(void) { log_info("Pack LUT-DFFs...\n"); @@ -1906,6 +1993,7 @@ void NgUltraImpl::pack() packer.pack_fifos(); packer.pack_cys(); packer.pack_xluts(); + packer.pack_lut_multi_dffs(); packer.pack_lut_dffs(); packer.pack_dffs(); diff --git a/himbaechel/uarch/ng-ultra/pack.h b/himbaechel/uarch/ng-ultra/pack.h index 4c3fef9a..7be3e1b9 100644 --- a/himbaechel/uarch/ng-ultra/pack.h +++ b/himbaechel/uarch/ng-ultra/pack.h @@ -47,6 +47,7 @@ struct NgUltraPacker void update_lut_init(); void update_dffs(); void pack_xluts(); + void pack_lut_multi_dffs(); void pack_lut_dffs(); void pack_dffs(); void pack_cys();