From 61073f5aa7e0c00f7751cccf1e81e7f96fe141d7 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 23 Jun 2024 18:15:42 +0200 Subject: [PATCH] CDC packing --- himbaechel/uarch/ng-ultra/extra_data.h | 32 +++++ himbaechel/uarch/ng-ultra/ng_ultra.cc | 121 ++++++++++++++++ himbaechel/uarch/ng-ultra/pack.cc | 189 ++++++++++++++++++++++++- himbaechel/uarch/ng-ultra/pack.h | 3 + 4 files changed, 343 insertions(+), 2 deletions(-) diff --git a/himbaechel/uarch/ng-ultra/extra_data.h b/himbaechel/uarch/ng-ultra/extra_data.h index da7e37bc..e1592387 100644 --- a/himbaechel/uarch/ng-ultra/extra_data.h +++ b/himbaechel/uarch/ng-ultra/extra_data.h @@ -97,6 +97,38 @@ enum ClusterPlacement PLACE_XRF_WE, PLACE_XRF_WEA, PLACE_DSP_CHAIN, + PLACE_CDC_AI1, + PLACE_CDC_AI2, + PLACE_CDC_AI3, + PLACE_CDC_AI4, + PLACE_CDC_AI5, + PLACE_CDC_AI6, + PLACE_CDC_BI1, + PLACE_CDC_BI2, + PLACE_CDC_BI3, + PLACE_CDC_BI4, + PLACE_CDC_BI5, + PLACE_CDC_BI6, + PLACE_CDC_ASRSTI, + PLACE_CDC_ADRSTI, + PLACE_CDC_BSRSTI, + PLACE_CDC_BDRSTI, + PLACE_CDC_CI1, + PLACE_CDC_CI2, + PLACE_CDC_CI3, + PLACE_CDC_CI4, + PLACE_CDC_CI5, + PLACE_CDC_CI6, + PLACE_CDC_DI1, + PLACE_CDC_DI2, + PLACE_CDC_DI3, + PLACE_CDC_DI4, + PLACE_CDC_DI5, + PLACE_CDC_DI6, + PLACE_CDC_CSRSTI, + PLACE_CDC_CDRSTI, + PLACE_CDC_DSRSTI, + PLACE_CDC_DDRSTI, }; enum PipExtra diff --git a/himbaechel/uarch/ng-ultra/ng_ultra.cc b/himbaechel/uarch/ng-ultra/ng_ultra.cc index d30be469..e70be0c8 100644 --- a/himbaechel/uarch/ng-ultra/ng_ultra.cc +++ b/himbaechel/uarch/ng-ultra/ng_ultra.cc @@ -409,6 +409,14 @@ IdString NgUltraImpl::getBelBucketForCellType(IdString cell_type) const return id_RF; else if (cell_type.in(id_XHRF, id_XWRF, id_XPRF)) return id_XRF; + else if (cell_type.in(id_DDE, id_TDE, id_CDC, id_BGC, id_GBC)) + return id_CDC; + else if (cell_type.in(id_XCDC)) + return id_XCDC; + else if (cell_type.in(id_FIFO)) + return id_FIFO; + else if (cell_type.in(id_XHFIFO, id_XWFIFO)) + return id_XFIFO; else if (cell_type.in(id_WFB, id_WFG)) return id_WFG; else @@ -430,6 +438,14 @@ bool NgUltraImpl::isValidBelForCellType(IdString cell_type, BelId bel) const return cell_type.in(id_RF,id_RFSP); else if (bel_type == id_XRF) return cell_type.in(id_XHRF,id_XWRF,id_XPRF); + else if (bel_type == id_CDC) + return cell_type.in(id_DDE, id_TDE, id_CDC, id_BGC, id_GBC); + else if (bel_type == id_XCDC) + return cell_type.in(id_XCDC); + else if (bel_type == id_FIFO) + return cell_type.in(id_FIFO); + else if (bel_type == id_XFIFO) + return cell_type.in(id_XHFIFO, id_XWFIFO); else if (bel_type == id_WFG) return cell_type.in(id_WFB,id_WFG); else @@ -575,6 +591,109 @@ Loc getXRFFE(Loc root, int pos) return result; } + +Loc getCDCFE(Loc root, int pos) +{ + static const std::vector cdc1 = + { + Loc(+1, 0, 1), // AI1 + Loc(+1, 0, 2), // AI2 + Loc(+1, 0, 9), // AI3 + Loc(+1, 0, 17),// AI4 + Loc(+1, 0, 18),// AI5 + Loc(+1, 0, 25),// AI6 + + Loc(+1, 0, 3), // BI1 + Loc(+1, 0, 10),// BI2 + Loc(+1, 0, 11),// BI3 + Loc(+1, 0, 19),// BI4 + Loc(+1, 0, 26),// BI5 + Loc(+1, 0, 27),// BI6 + + Loc( 0, 0, 22),// ASRSTI + Loc( 0, 0, 30),// ADRSTI + Loc(+1, 0, 24),// BSRSTI + Loc(+1, 0, 8), // BDRSTI + }; + + static const std::vector cdc2 = + { + Loc(-1, 0, 4), // AI1 + Loc(-1, 0, 5), // AI2 + Loc(-1, 0, 12),// AI3 + Loc(-1, 0, 20),// AI4 + Loc(-1, 0, 21),// AI5 + Loc(-1, 0, 28),// AI6 + + Loc(-1, 0, 6), // BI1 + Loc(-1, 0, 13),// BI2 + Loc(-1, 0, 14),// BI3 + Loc(-1, 0, 22),// BI4 + Loc(-1, 0, 29),// BI5 + Loc(-1, 0, 30),// BI6 + + Loc( 0, 0, 22),// ASRSTI + Loc( 0, 0, 30),// ADRSTI + Loc(-1, 0, 23),// BSRSTI + Loc(-1, 0, 7), // BDRSTI + }; + + static const std::vector xcdc = + { + Loc( 0, 0, 1), // AI1 + Loc( 0, 0, 2), // AI2 + Loc( 0, 0, 9), // AI3 + Loc( 0, 0, 17),// AI4 + Loc( 0, 0, 18),// AI5 + Loc( 0, 0, 25),// AI6 + + Loc( 0, 0, 4), // BI1 + Loc( 0, 0, 5), // BI2 + Loc( 0, 0, 12),// BI3 + Loc( 0, 0, 20),// BI4 + Loc( 0, 0, 21),// BI5 + Loc( 0, 0, 28),// BI6 + + Loc(-1, 0, 22),// ASRSTI + Loc(-1, 0, 30),// ADRSTI + Loc(+1, 0, 22),// BSRSTI + Loc(+1, 0, 30),// BDRSTI + + Loc( 0, 0, 3), // CI1 + Loc( 0, 0, 10),// CI2 + Loc( 0, 0, 11),// CI3 + Loc( 0, 0, 19),// CI4 + Loc( 0, 0, 26),// CI5 + Loc( 0, 0, 27),// CI6 + + Loc( 0, 0, 6), // DI1 + Loc( 0, 0, 13),// DI2 + Loc( 0, 0, 14),// DI3 + Loc( 0, 0, 22),// DI4 + Loc( 0, 0, 29),// DI5 + Loc( 0, 0, 30),// DI6 + + Loc( 0, 0, 24),// CSRSTI + Loc( 0, 0, 8), // CDRSTI + Loc( 0, 0, 23),// DSRSTI + Loc( 0, 0, 7), // DDRSTI + }; + + Loc result; + if (root.z == BEL_CDC_Z) { + result = cdc1.at(pos); + } else if (root.z == BEL_CDC_Z+1) { + result = cdc2.at(pos); + } else if (root.z == BEL_XCDC_Z) { + result = xcdc.at(pos); + } else { + log_error("Trying to place CDC on wrong location.\n"); + } + result.x += root.x; + result.y = root.y; + return result; +} + bool NgUltraImpl::getChildPlacement(const BaseClusterInfo *cluster, Loc root_loc, std::vector> &placement) const { @@ -589,6 +708,8 @@ bool NgUltraImpl::getChildPlacement(const BaseClusterInfo *cluster, Loc root_loc case PLACE_CY_FE4: return getCYFE(root_loc,3); case PLACE_XRF_I1 ... PLACE_XRF_WEA: return getXRFFE(root_loc, child->constr_z - PLACE_XRF_I1 ); + case PLACE_CDC_AI1 ... PLACE_CDC_DDRSTI: + return getCDCFE(root_loc, child->constr_z - PLACE_CDC_AI1 ); case PLACE_DSP_CHAIN : { Loc l = getNextLocInDSPChain(this, prev); prev = l; return l; } default: Loc result; diff --git a/himbaechel/uarch/ng-ultra/pack.cc b/himbaechel/uarch/ng-ultra/pack.cc index bc949730..c2bb4401 100644 --- a/himbaechel/uarch/ng-ultra/pack.cc +++ b/himbaechel/uarch/ng-ultra/pack.cc @@ -988,6 +988,172 @@ void NgUltraPacker::pack_rfs(void) flush_cells(); } +void NgUltraPacker::pack_cdcs(void) +{ + log_info("Packing CDCs..\n"); + int lut_only = 0, lut_and_ff = 0, dff_only = 0; + for (auto &cell : ctx->cells) { + CellInfo &ci = *cell.second; + if (!ci.type.in(id_NX_CDC_U)) + continue; + int mode = int_or_default(ci.params, ctx->id("mode"), 0); + switch(mode) { + case 0 : ci.type = id_DDE; break; + case 1 : ci.type = id_TDE; break; + case 2 : ci.type = id_CDC; break; + case 3 : ci.type = id_BGC; break; + case 4 : ci.type = id_GBC; break; + case 5 : ci.type = id_XCDC; break; + default: + log_error("Unknown mode %d for cell '%s'.\n", mode, ci.name.c_str(ctx)); + } + ci.cluster = ci.name; + + // If unconnected, connect GND to inputs that are actually used as outputs + for (int i = 1; i <= 6; i++) { + if (ci.getPort(ctx->idf("AO%d",i))) { + connect_gnd_if_unconnected(&ci, ctx->idf("AI%d",i)); + pack_xrf_input_and_output(&ci, ci.name, ctx->idf("AI%d",i), ctx->idf("AO%d",i), ClusterPlacement(PLACE_CDC_AI1 + i-1), lut_only, lut_and_ff, dff_only); + } else + disconnect_unused(&ci, ctx->idf("AI%d",i)); + if (ci.getPort(ctx->idf("BO%d",i))) { + connect_gnd_if_unconnected(&ci, ctx->idf("BI%d",i)); + pack_xrf_input_and_output(&ci, ci.name, ctx->idf("BI%d",i), ctx->idf("BO%d",i), ClusterPlacement(PLACE_CDC_BI1 + i-1), lut_only, lut_and_ff, dff_only); + } else + disconnect_unused(&ci, ctx->idf("BI%d",i)); + if (ci.type.in(id_XCDC)) { + if (ci.getPort(ctx->idf("CO%d",i))) { + connect_gnd_if_unconnected(&ci, ctx->idf("CI%d",i)); + pack_xrf_input_and_output(&ci, ci.name, ctx->idf("CI%d",i), ctx->idf("CO%d",i), ClusterPlacement(PLACE_CDC_CI1 + i-1), lut_only, lut_and_ff, dff_only); + } else + disconnect_unused(&ci, ctx->idf("CI%d",i)); + if (ci.getPort(ctx->idf("DO%d",i))) { + connect_gnd_if_unconnected(&ci, ctx->idf("DI%d",i)); + pack_xrf_input_and_output(&ci, ci.name, ctx->idf("DI%d",i), ctx->idf("DO%d",i), ClusterPlacement(PLACE_CDC_DI1 + i-1), lut_only, lut_and_ff, dff_only); + } else + disconnect_unused(&ci, ctx->idf("DI%d",i)); + } + } + + // Remove inputs and outputs that are not used for specific types + if (ci.type.in(id_BGC, id_GBC)) { + disconnect_unused(&ci, id_CK1); + disconnect_unused(&ci, id_CK2); + disconnect_unused(&ci, id_ADRSTI); + disconnect_unused(&ci, id_ADRSTO); + disconnect_unused(&ci, id_BDRSTI); + disconnect_unused(&ci, id_BDRSTO); + } else { + connect_gnd_if_unconnected(&ci, id_ADRSTI); + pack_xrf_input_and_output(&ci, ci.name, id_ADRSTI, id_ADRSTO, PLACE_CDC_ADRSTI, lut_only, lut_and_ff, dff_only); + connect_gnd_if_unconnected(&ci, id_BDRSTI); + pack_xrf_input_and_output(&ci, ci.name, id_BDRSTI, id_BDRSTO, PLACE_CDC_BDRSTI, lut_only, lut_and_ff, dff_only); + } + if (ci.type.in(id_BGC, id_GBC, id_DDE)) { + disconnect_unused(&ci, id_ASRSTI); + disconnect_unused(&ci, id_ASRSTO); + disconnect_unused(&ci, id_BSRSTI); + disconnect_unused(&ci, id_BSRSTO); + } else { + connect_gnd_if_unconnected(&ci, id_ASRSTI); + pack_xrf_input_and_output(&ci, ci.name, id_ASRSTI, id_ASRSTO, PLACE_CDC_ASRSTI, lut_only, lut_and_ff, dff_only); + connect_gnd_if_unconnected(&ci, id_BSRSTI); + pack_xrf_input_and_output(&ci, ci.name, id_BSRSTI, id_BSRSTO, PLACE_CDC_BSRSTI, lut_only, lut_and_ff, dff_only); + } + + // Only XCDC is using these ports, remove from others if used + if (!ci.type.in(id_XCDC)) { + disconnect_unused(&ci, id_CDRSTI); + disconnect_unused(&ci, id_CDRSTO); + for (int i = 1; i <= 6; i++) { + disconnect_unused(&ci,ctx->idf("CI%d",i)); + disconnect_unused(&ci,ctx->idf("CO%d",i)); + } + disconnect_unused(&ci, id_CSRSTI); + disconnect_unused(&ci, id_CSRSTO); + + disconnect_unused(&ci, id_DDRSTI); + disconnect_unused(&ci, id_DDRSTO); + for (int i = 1; i <= 6; i++) { + disconnect_unused(&ci,ctx->idf("DI%d",i)); + disconnect_unused(&ci,ctx->idf("DO%d",i)); + } + disconnect_unused(&ci, id_DSRSTI); + disconnect_unused(&ci, id_DSRSTO); + } else { + connect_gnd_if_unconnected(&ci, id_CDRSTI); + pack_xrf_input_and_output(&ci, ci.name, id_CDRSTI, id_CDRSTO, PLACE_CDC_CDRSTI, lut_only, lut_and_ff, dff_only); + connect_gnd_if_unconnected(&ci, id_DDRSTI); + pack_xrf_input_and_output(&ci, ci.name, id_DDRSTI, id_DDRSTO, PLACE_CDC_DDRSTI, lut_only, lut_and_ff, dff_only); + connect_gnd_if_unconnected(&ci, id_CSRSTI); + pack_xrf_input_and_output(&ci, ci.name, id_CSRSTI, id_CSRSTO, PLACE_CDC_CSRSTI, lut_only, lut_and_ff, dff_only); + connect_gnd_if_unconnected(&ci, id_DSRSTI); + pack_xrf_input_and_output(&ci, ci.name, id_DSRSTI, id_DSRSTO, PLACE_CDC_DSRSTI, lut_only, lut_and_ff, dff_only); + } + } + if (lut_only) + log_info(" %6d FEs used as LUT only\n", lut_only); + if (lut_and_ff) + log_info(" %6d FEs used as LUT and DFF\n", lut_and_ff); + if (dff_only) + log_info(" %6d FEs used as DFF only\n", dff_only); + flush_cells(); +} + +void NgUltraPacker::pack_fifos(void) +{ + log_info("Packing FIFOs..\n"); + int lut_only = 0, lut_and_ff = 0, dff_only = 0; + for (auto &cell : ctx->cells) { + CellInfo &ci = *cell.second; + if (!ci.type.in(id_NX_FIFO_U)) + continue; + int mode = int_or_default(ci.params, ctx->id("mode"), 0); + switch(mode) { + case 0 : ci.type = id_FIFO; break; + case 1 : ci.type = id_XHFIFO; break; + case 2 : ci.type = id_XWFIFO; break; + default: + log_error("Unknown mode %d for cell '%s'.\n", mode, ci.name.c_str(ctx)); + } + //ci.cluster = ci.name; + + if (mode > 0) { + // XFIFO + ci.ports[id_WCK1].name = id_WCK1; + ci.ports[id_WCK1].type = PORT_IN; + ci.ports[id_WCK2].name = id_WCK2; + ci.ports[id_WCK2].type = PORT_IN; + ci.ports[id_RCK1].name = id_RCK1; + ci.ports[id_RCK1].type = PORT_IN; + ci.ports[id_RCK2].name = id_RCK2; + ci.ports[id_RCK2].type = PORT_IN; + NetInfo *net = ci.getPort(id_WCK); + if (net) { + ci.disconnectPort(id_WCK); + + ci.connectPort(id_WCK1, net); + ci.connectPort(id_WCK2, net); + } + net = ci.getPort(id_RCK); + if (net) { + ci.disconnectPort(id_RCK); + + ci.connectPort(id_RCK1, net); + ci.connectPort(id_RCK2, net); + } + } + + } + if (lut_only) + log_info(" %6d FEs used as LUT only\n", lut_only); + if (lut_and_ff) + log_info(" %6d FEs used as LUT and DFF\n", lut_and_ff); + if (dff_only) + log_info(" %6d FEs used as DFF only\n", dff_only); + flush_cells(); +} + void NgUltraPacker::insert_ioms() { std::vector pins_needing_iom; @@ -1404,6 +1570,22 @@ void NgUltraPacker::pack_dsps(void) } } } + +void NgUltraPacker::remove_not_used() +{ + for (auto &cell : ctx->cells) { + CellInfo &ci = *cell.second; + for (auto &p : ci.ports) { + if (p.second.type == PortType::PORT_OUT) { + NetInfo *net = ci.getPort(p.first); + if (net && net->users.entries()==0) { + ci.disconnectPort(p.first); + } + } + } + } +} + void NgUltraPacker::setup() { // Note: These are per Cell type not Bel type @@ -1484,6 +1666,7 @@ void NgUltraImpl::pack() // Setup NgUltraPacker packer(ctx, this); packer.setup(); + packer.remove_not_used(); packer.pack_constants(); packer.update_lut_init(); packer.update_dffs(); @@ -1494,6 +1677,8 @@ void NgUltraImpl::pack() // TILE packer.pack_rfs(); + packer.pack_cdcs(); + packer.pack_fifos(); packer.pack_cys(); packer.pack_lut_dffs(); packer.pack_dffs(); @@ -1549,7 +1734,7 @@ void NgUltraPacker::pre_place(void) NetInfo *ref = ci.getPort(id_REF); if (ref && ref->driver.cell && ref->driver.cell->type == id_IOM) { IdString bank= uarch->tile_name_id(ref->driver.cell->bel.tile); - bool found = false; + //bool found = false; for (auto &item : uarch->unused_pll) { BelId bel = item.first; std::pair& ckgs = uarch->bank_to_ckg[bank]; @@ -1557,7 +1742,7 @@ void NgUltraPacker::pre_place(void) uarch->unused_pll.erase(bel); log_info(" Using PLL in '%s' for cell '%s'.\n", uarch->tile_name(bel.tile).c_str(), ci.name.c_str(ctx)); ctx->bindBel(bel, &ci, PlaceStrength::STRENGTH_LOCKED); - found = true; + //found = true; break; } } diff --git a/himbaechel/uarch/ng-ultra/pack.h b/himbaechel/uarch/ng-ultra/pack.h index 0202f445..d97e40d9 100644 --- a/himbaechel/uarch/ng-ultra/pack.h +++ b/himbaechel/uarch/ng-ultra/pack.h @@ -38,6 +38,7 @@ struct NgUltraPacker { NgUltraPacker(Context *ctx, NgUltraImpl *uarch) : ctx(ctx), uarch(uarch) { h.init(ctx); }; + void remove_not_used(); // Constants void pack_constants(); void remove_constants(); @@ -49,6 +50,8 @@ struct NgUltraPacker void pack_dffs(); void pack_cys(); void pack_rfs(); + void pack_cdcs(); + void pack_fifos(); void pack_rams(); void pack_dsps();