diff --git a/himbaechel/uarch/ng-ultra/bitstream.cc b/himbaechel/uarch/ng-ultra/bitstream.cc index 04df24f8..7a0a05af 100644 --- a/himbaechel/uarch/ng-ultra/bitstream.cc +++ b/himbaechel/uarch/ng-ultra/bitstream.cc @@ -349,6 +349,12 @@ struct BitstreamJsonBackend close_instance(); } + void write_rf(CellInfo *cell) { + open_instance(cell, "RF"); + add_config("wck_edge", bool_or_default(cell->params, ctx->id("wck_edge"), false)); + close_instance(); + } + void write_interconnections() { for (auto &net : ctx->nets) { @@ -400,7 +406,8 @@ struct BitstreamJsonBackend //case id_XLUT.index: //case id_RAM.index: //case id_RF.index: - //case id_XRF.index: + case id_RF.index: write_rf(cell.second.get()); break; + //case id_XRF.index: write_xrf(cell.second.get()); break; //case id_FIFO.index: //case id_XFIFO.index: //case id_CDC.index: diff --git a/himbaechel/uarch/ng-ultra/extra_data.h b/himbaechel/uarch/ng-ultra/extra_data.h index a70e9289..0a8adf56 100644 --- a/himbaechel/uarch/ng-ultra/extra_data.h +++ b/himbaechel/uarch/ng-ultra/extra_data.h @@ -42,6 +42,60 @@ enum ClusterPlacement PLACE_CY_FE2, PLACE_CY_FE3, PLACE_CY_FE4, + PLACE_XRF_I1, + PLACE_XRF_I2, + PLACE_XRF_I3, + PLACE_XRF_I4, + PLACE_XRF_I5, + PLACE_XRF_I6, + PLACE_XRF_I7, + PLACE_XRF_I8, + PLACE_XRF_I9, + PLACE_XRF_I10, + PLACE_XRF_I11, + PLACE_XRF_I12, + PLACE_XRF_I13, + PLACE_XRF_I14, + PLACE_XRF_I15, + PLACE_XRF_I16, + PLACE_XRF_I17, + PLACE_XRF_I18, + PLACE_XRF_I19, + PLACE_XRF_I20, + PLACE_XRF_I21, + PLACE_XRF_I22, + PLACE_XRF_I23, + PLACE_XRF_I24, + PLACE_XRF_I25, + PLACE_XRF_I26, + PLACE_XRF_I27, + PLACE_XRF_I28, + PLACE_XRF_I29, + PLACE_XRF_I30, + PLACE_XRF_I31, + PLACE_XRF_I32, + PLACE_XRF_I33, + PLACE_XRF_I34, + PLACE_XRF_I35, + PLACE_XRF_I36, + PLACE_XRF_RA1, + PLACE_XRF_RA2, + PLACE_XRF_RA3, + PLACE_XRF_RA4, + PLACE_XRF_RA5, + PLACE_XRF_RA6, + PLACE_XRF_RA7, + PLACE_XRF_RA8, + PLACE_XRF_RA9, + PLACE_XRF_RA10, + PLACE_XRF_WA1, + PLACE_XRF_WA2, + PLACE_XRF_WA3, + PLACE_XRF_WA4, + PLACE_XRF_WA5, + PLACE_XRF_WA6, + PLACE_XRF_WE, + PLACE_XRF_WEA, }; enum PipExtra diff --git a/himbaechel/uarch/ng-ultra/ng_ultra.cc b/himbaechel/uarch/ng-ultra/ng_ultra.cc index ceb931af..60263ad9 100644 --- a/himbaechel/uarch/ng-ultra/ng_ultra.cc +++ b/himbaechel/uarch/ng-ultra/ng_ultra.cc @@ -347,6 +347,78 @@ Loc getCYFE(Loc root, int pos) return result; } +Loc getXRFFE(Loc root, int pos) +{ + static const std::vector map = + { + Loc(-1, 0, 1),// I/O1 + Loc(-1, 0, 2),// I/O2 + Loc(-1, 0, 5),// I/O3 + Loc(-1, 0, 6),// I/O4 + Loc(-1, 0, 7),// I/O5 + Loc(-1, 0, 9),// I/O6 + Loc(-1, 0, 10),// I/O7 + Loc(-1, 0, 13),// I/O8 + Loc(-1, 0, 14),// I/O9 + Loc(-1, 0, 15),// I/O10 + Loc(-1, 0, 16),// I/O11 + Loc(-1, 0, 17),// I/O12 + Loc(-1, 0, 18),// I/O13 + Loc(-1, 0, 21),// I/O14 + Loc(-1, 0, 24),// I/O15 + Loc(-1, 0, 25),// I/O16 + Loc(-1, 0, 26),// I/O17 + Loc(-1, 0, 29),// I/O18 + Loc(+1, 0, 1),// I/O19 + Loc(+1, 0, 2),// I/O20 + Loc(+1, 0, 5),// I/O21 + Loc(+1, 0, 6),// I/O22 + Loc(+1, 0, 7),// I/O23 + Loc(+1, 0, 9),// I/O24 + Loc(+1, 0, 10),// I/O25 + Loc(+1, 0, 13),// I/O26 + Loc(+1, 0, 14),// I/O27 + Loc(+1, 0, 15),// I/O28 + Loc(+1, 0, 16),// I/O29 + Loc(+1, 0, 17),// I/O30 + Loc(+1, 0, 18),// I/O31 + Loc(+1, 0, 21),// I/O32 + Loc(+1, 0, 24),// I/O33 + Loc(+1, 0, 25),// I/O34 + Loc(+1, 0, 26),// I/O35 + Loc(+1, 0, 29),// I/O36 + + + Loc(-1, 0, 4),// RA1 + Loc(-1, 0, 12),// RA2 + Loc(-1, 0, 20),// RA3 + Loc(-1, 0, 27),// RA4 + Loc(-1, 0, 31),// RA5 + Loc(+1, 0, 4),// RA6 + Loc(+1, 0, 12),// RA7 + Loc(+1, 0, 20),// RA8 + Loc(+1, 0, 27),// RA9 + Loc(+1, 0, 31),// RA10 + + Loc(-1, 0, 3),// WA1 + Loc(-1, 0, 11),// WA2 + Loc(-1, 0, 19),// WA3 + Loc(-1, 0, 23),// WA4 + Loc(-1, 0, 28),// WA5 + Loc(+1, 0, 3),// WA6 + + Loc(-1, 0, 0),// WE + Loc(-1, 0, 8),// WEA + + }; + + Loc result = map.at(pos); + result.x += root.x; + result.y = root.y; + return result; + +} + bool NgUltraImpl::getChildPlacement(const BaseClusterInfo *cluster, Loc root_loc, std::vector> &placement) const { @@ -359,6 +431,61 @@ bool NgUltraImpl::getChildPlacement(const BaseClusterInfo *cluster, Loc root_loc case PLACE_CY_FE2: return getCYFE(root_loc,1); case PLACE_CY_FE3: return getCYFE(root_loc,2); case PLACE_CY_FE4: return getCYFE(root_loc,3); + case PLACE_XRF_I1: + case PLACE_XRF_I2: + case PLACE_XRF_I3: + case PLACE_XRF_I4: + case PLACE_XRF_I5: + case PLACE_XRF_I6: + case PLACE_XRF_I7: + case PLACE_XRF_I8: + case PLACE_XRF_I9: + case PLACE_XRF_I10: + case PLACE_XRF_I11: + case PLACE_XRF_I12: + case PLACE_XRF_I13: + case PLACE_XRF_I14: + case PLACE_XRF_I15: + case PLACE_XRF_I16: + case PLACE_XRF_I17: + case PLACE_XRF_I18: + case PLACE_XRF_I19: + case PLACE_XRF_I20: + case PLACE_XRF_I21: + case PLACE_XRF_I22: + case PLACE_XRF_I23: + case PLACE_XRF_I24: + case PLACE_XRF_I25: + case PLACE_XRF_I26: + case PLACE_XRF_I27: + case PLACE_XRF_I28: + case PLACE_XRF_I29: + case PLACE_XRF_I30: + case PLACE_XRF_I31: + case PLACE_XRF_I32: + case PLACE_XRF_I33: + case PLACE_XRF_I34: + case PLACE_XRF_I35: + case PLACE_XRF_I36: + case PLACE_XRF_RA1: + case PLACE_XRF_RA2: + case PLACE_XRF_RA3: + case PLACE_XRF_RA4: + case PLACE_XRF_RA5: + case PLACE_XRF_RA6: + case PLACE_XRF_RA7: + case PLACE_XRF_RA8: + case PLACE_XRF_RA9: + case PLACE_XRF_RA10: + case PLACE_XRF_WA1: + case PLACE_XRF_WA2: + case PLACE_XRF_WA3: + case PLACE_XRF_WA4: + case PLACE_XRF_WA5: + case PLACE_XRF_WA6: + case PLACE_XRF_WE: + case PLACE_XRF_WEA: + return getXRFFE(root_loc, child->constr_z - PLACE_XRF_I1 ); default: Loc result; result.x = root_loc.x + child->constr_x; diff --git a/himbaechel/uarch/ng-ultra/pack.cc b/himbaechel/uarch/ng-ultra/pack.cc index 45dcc0e6..52840326 100644 --- a/himbaechel/uarch/ng-ultra/pack.cc +++ b/himbaechel/uarch/ng-ultra/pack.cc @@ -717,6 +717,211 @@ void NgUltraPacker::pack_cys(void) flush_cells(); } +ClusterPlacement getPortPlacement(Context *ctx, IdString port) +{ + switch(port.index) + { + case id_I1.index : return PLACE_XRF_I1; + case id_I2.index : return PLACE_XRF_I2; + case id_I3.index : return PLACE_XRF_I3; + case id_I4.index : return PLACE_XRF_I4; + case id_I5.index : return PLACE_XRF_I5; + case id_I6.index : return PLACE_XRF_I6; + case id_I7.index : return PLACE_XRF_I7; + case id_I8.index : return PLACE_XRF_I8; + case id_I9.index : return PLACE_XRF_I9; + case id_I10.index : return PLACE_XRF_I10; + case id_I11.index : return PLACE_XRF_I11; + case id_I12.index : return PLACE_XRF_I12; + case id_I13.index : return PLACE_XRF_I13; + case id_I14.index : return PLACE_XRF_I14; + case id_I15.index : return PLACE_XRF_I15; + case id_I16.index : return PLACE_XRF_I16; + case id_I17.index : return PLACE_XRF_I17; + case id_I18.index : return PLACE_XRF_I18; + case id_I19.index : return PLACE_XRF_I19; + case id_I20.index : return PLACE_XRF_I20; + case id_I21.index : return PLACE_XRF_I21; + case id_I22.index : return PLACE_XRF_I22; + case id_I23.index : return PLACE_XRF_I23; + case id_I24.index : return PLACE_XRF_I24; + case id_I25.index : return PLACE_XRF_I25; + case id_I26.index : return PLACE_XRF_I26; + case id_I27.index : return PLACE_XRF_I27; + case id_I28.index : return PLACE_XRF_I28; + case id_I29.index : return PLACE_XRF_I29; + case id_I30.index : return PLACE_XRF_I30; + case id_I31.index : return PLACE_XRF_I31; + case id_I32.index : return PLACE_XRF_I32; + case id_I33.index : return PLACE_XRF_I33; + case id_I34.index : return PLACE_XRF_I34; + case id_I35.index : return PLACE_XRF_I35; + case id_I36.index : return PLACE_XRF_I36; + case id_RA1.index : return PLACE_XRF_RA1; + case id_RA2.index : return PLACE_XRF_RA2; + case id_RA3.index : return PLACE_XRF_RA3; + case id_RA4.index : return PLACE_XRF_RA4; + case id_RA5.index : return PLACE_XRF_RA5; + case id_RA6.index : return PLACE_XRF_RA6; + case id_RA7.index : return PLACE_XRF_RA7; + case id_RA8.index : return PLACE_XRF_RA8; + case id_RA9.index : return PLACE_XRF_RA9; + case id_RA10.index : return PLACE_XRF_RA10; + case id_WA1.index : return PLACE_XRF_WA1; + case id_WA2.index : return PLACE_XRF_WA2; + case id_WA3.index : return PLACE_XRF_WA3; + case id_WA4.index : return PLACE_XRF_WA4; + case id_WA5.index : return PLACE_XRF_WA5; + case id_WA6.index : return PLACE_XRF_WA6; + case id_WE.index : return PLACE_XRF_WE; + case id_WEA.index : return PLACE_XRF_WEA; + default: + log_error("Unhandled port %s\n", port.c_str(ctx)); + } +} + +void NgUltraPacker::pack_xrf_input_and_output(CellInfo *xrf, IdString cluster, IdString in_port, IdString out_port, int &lut_only, int &lut_and_ff, int &dff_only) +{ + NetInfo *net = xrf->getPort(in_port); + NetInfo *net_out = nullptr; + if (out_port != IdString()) + net_out = xrf->getPort(out_port); + if (!net && !net_out) return; + CellInfo *fe = create_cell_ptr(id_BEYOND_FE, ctx->id(xrf->name.str(ctx) + "$" + in_port.c_str(ctx))); + + if (net) { + if (net->name.in(ctx->id("$PACKER_GND"), ctx->id("$PACKER_VCC"))) { + fe->params[id_lut_table] = Property((net->name ==ctx->id("$PACKER_GND")) ? 0x0000 : 0xffff, 16); + fe->params[id_lut_used] = Property(1,1); + xrf->disconnectPort(in_port); + NetInfo *new_out = ctx->createNet(ctx->id(fe->name.str(ctx) + "$o")); + fe->connectPort(id_LO, new_out); + xrf->connectPort(in_port, new_out); + } else { + CellInfo *lut = net_driven_by(ctx, net, is_lut, id_O); + if (lut && net->users.entries()==1) { + if (!lut->params.count(id_lut_table)) + log_error("Cell '%s' missing lut_table\n", lut->name.c_str(ctx)); + lut_to_fe(lut, fe, false, lut->params[id_lut_table]); + packed_cells.insert(lut->name); + } else { + fe->params[id_lut_table] = Property(0xaaaa, 16); + fe->params[id_lut_used] = Property(1,1); + xrf->disconnectPort(in_port); + NetInfo *new_out = ctx->createNet(ctx->id(fe->name.str(ctx) + "$o")); + fe->connectPort(id_I1, net); + fe->connectPort(id_LO, new_out); + xrf->connectPort(in_port, new_out); + } + } + lut_only++; + } + if (net_out) { + CellInfo *dff = net_only_drives(ctx, net_out, is_dff, id_I, true); + if (dff) { + if (ctx->verbose) + log_info("found attached dff %s\n", dff->name.c_str(ctx)); + dff_to_fe(dff, fe, false); + packed_cells.insert(dff->name); + if (net) { + lut_only--; + lut_and_ff++; + } else + dff_only++; + } + } + fe->cluster = cluster; + fe->constr_z = getPortPlacement(ctx,in_port); + xrf->constr_children.push_back(fe); +} + +void NgUltraPacker::pack_rfs(void) +{ + log_info("Packing RFs..\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_RFB_U)) + continue; + ci.type = id_RF; + //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; + + //NetInfo *net = ci.getPort(id_WCK); + //if (net) { + // ci.disconnectPort(id_WCK); +// + //ci.connectPort(id_WCK1, net); + //ci.connectPort(id_WCK2, net); + //} + ci.cluster = ci.name; + + pack_xrf_input_and_output(&ci, ci.name, id_I1, id_O1, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I2, id_O2, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I3, id_O3, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I4, id_O4, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I5, id_O5, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I6, id_O6, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I7, id_O7, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I8, id_O8, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I9, id_O9, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I10, id_O10, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I11, id_O11, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I12, id_O12, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I13, id_O13, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I14, id_O14, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I15, id_O15, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I16, id_O16, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I17, id_O17, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I18, id_O18, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I19, id_O19, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I20, id_O20, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I21, id_O21, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I22, id_O22, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I23, id_O23, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I24, id_O24, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I25, id_O25, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I26, id_O26, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I27, id_O27, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I28, id_O28, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I29, id_O29, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I30, id_O30, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I31, id_O31, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I32, id_O32, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I33, id_O33, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I34, id_O34, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I35, id_O35, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_I36, id_O36, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_RA1, IdString(), lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_RA2, IdString(), lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_RA3, IdString(), lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_RA4, IdString(), lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_RA5, IdString(), lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_RA6, IdString(), lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_RA7, IdString(), lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_RA8, IdString(), lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_RA9, IdString(), lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_RA10, IdString(), lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_WA1, IdString(), lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_WA2, IdString(), lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_WA3, IdString(), lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_WA4, IdString(), lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_WA5, IdString(), lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_WA6, IdString(), lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_WE, IdString(), lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_WEA, IdString(), 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(); +} + // There are 20 dedicated clock inputs capable of being routed using global network // to be able to best route them, IOM needs to be used to propagate these clock signals void NgUltraPacker::promote_globals() @@ -815,6 +1020,7 @@ void NgUltraImpl::pack() packer.update_dffs(); packer.pack_iobs(); packer.pack_ioms(); + packer.pack_rfs(); packer.pack_cys(); packer.pack_lut_dffs(); packer.pack_dffs(); diff --git a/himbaechel/uarch/ng-ultra/pack.h b/himbaechel/uarch/ng-ultra/pack.h index ccf46d62..482afbb6 100644 --- a/himbaechel/uarch/ng-ultra/pack.h +++ b/himbaechel/uarch/ng-ultra/pack.h @@ -48,6 +48,7 @@ struct NgUltraPacker void pack_lut_dffs(); void pack_dffs(); void pack_cys(); + void pack_rfs(); // IO void pack_iobs(); @@ -63,6 +64,8 @@ private: void exchange_if_constant(CellInfo *cell, IdString input1, IdString input2); void pack_cy_input_and_output(CellInfo *cy, IdString cluster, IdString in_port, IdString out_port, int placer, int &lut_only, int &lut_and_ff, int &dff_only); + void pack_xrf_input_and_output(CellInfo *cy, IdString cluster, IdString in_port, IdString out_port, int &lut_only, int &lut_and_ff, int &dff_only); + // General helper functions void flush_cells();