diff --git a/himbaechel/uarch/ng-ultra/bitstream.cc b/himbaechel/uarch/ng-ultra/bitstream.cc index 7a0a05af..31f0ca8a 100644 --- a/himbaechel/uarch/ng-ultra/bitstream.cc +++ b/himbaechel/uarch/ng-ultra/bitstream.cc @@ -188,6 +188,13 @@ struct BitstreamJsonBackend } }; + template std::string extract_bits_or_default(const dict &ct, const KeyType &key, int bits, int def = 0) + { + Property extr = get_or_default(ct, key, Property()).extract(0, bits); + std::string str = extr.str; + std::reverse(str.begin(), str.end()); + return str; + }; std::vector config; @@ -308,10 +315,7 @@ struct BitstreamJsonBackend void write_fe(CellInfo *cell) { if (bool_or_default(cell->params, id_lut_used)) { open_instance_fe(cell, "LUT", ".LUT"); - Property init = get_or_default(cell->params, id_lut_table, Property()).extract(0, 16); - std::string lut = init.str; - std::reverse(lut.begin(), lut.end()); - add_config("lut_table", lut); + add_config("lut_table", extract_bits_or_default(cell->params, id_lut_table, 16)); close_instance(); } if (bool_or_default(cell->params, id_dff_used)) { @@ -350,11 +354,28 @@ struct BitstreamJsonBackend } void write_rf(CellInfo *cell) { - open_instance(cell, "RF"); + int mode = int_or_default(cell->params, ctx->id("mode"), 0); + switch(mode) { + case 0 : open_instance(cell, "RF"); break; + case 1 : open_instance(cell, "RFSP"); break; + case 2 : open_instance(cell, "XHRF"); break; + case 3 : open_instance(cell, "XWRF"); break; + case 4 : open_instance(cell, "XPRF"); break; + default: + log_error("Unknown mode %d for cell '%s'.\n", mode, cell->name.c_str(ctx)); + } + add_config("mode", mode); add_config("wck_edge", bool_or_default(cell->params, ctx->id("wck_edge"), false)); close_instance(); } + void write_ram(CellInfo *cell) { + open_instance(cell, "RAM"); + add_config("raw_config0", extract_bits_or_default(cell->params, ctx->id("raw_config0"), 4)); + add_config("raw_config1", extract_bits_or_default(cell->params, ctx->id("raw_config1"), 16)); + close_instance(); + } + void write_interconnections() { for (auto &net : ctx->nets) { @@ -404,10 +425,10 @@ struct BitstreamJsonBackend case id_DDFR.index: write_dfr(cell.second.get()); break; case id_DFR.index: write_dfr(cell.second.get()); break; //case id_XLUT.index: - //case id_RAM.index: + case id_RAM.index: write_ram(cell.second.get()); break; //case id_RF.index: case id_RF.index: write_rf(cell.second.get()); break; - //case id_XRF.index: write_xrf(cell.second.get()); break; + case id_XRF.index: write_rf(cell.second.get()); break; //case id_FIFO.index: //case id_XFIFO.index: //case id_CDC.index: diff --git a/himbaechel/uarch/ng-ultra/pack.cc b/himbaechel/uarch/ng-ultra/pack.cc index 52840326..becc93b5 100644 --- a/himbaechel/uarch/ng-ultra/pack.cc +++ b/himbaechel/uarch/ng-ultra/pack.cc @@ -195,6 +195,16 @@ void NgUltraPacker::set_lut_input_if_constant(CellInfo *cell, IdString input) cell->disconnectPort(input); } +void NgUltraPacker::disconnect_if_gnd(CellInfo *cell, IdString input) +{ + NetInfo *net = cell->getPort(input); + if (!net) + return; + if (net->name.in(ctx->id("$PACKER_GND"))) { + cell->disconnectPort(input); + } +} + void NgUltraPacker::lut_to_fe(CellInfo *lut, CellInfo *fe, bool no_dff, Property lut_table) { fe->params[id_lut_table] = lut_table; @@ -782,10 +792,16 @@ ClusterPlacement getPortPlacement(Context *ctx, IdString port) 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) { + disconnect_if_gnd(xrf, in_port); NetInfo *net = xrf->getPort(in_port); NetInfo *net_out = nullptr; - if (out_port != IdString()) + if (out_port != IdString()) { net_out = xrf->getPort(out_port); + if (net_out->users.entries()==0) { + xrf->disconnectPort(out_port); + net_out = nullptr; + } + } if (!net && !net_out) return; CellInfo *fe = create_cell_ptr(id_BEYOND_FE, ctx->id(xrf->name.str(ctx) + "$" + in_port.c_str(ctx))); @@ -843,19 +859,24 @@ void NgUltraPacker::pack_rfs(void) CellInfo &ci = *cell.second; if (!ci.type.in(id_NX_RFB_U)) continue; + int mode = int_or_default(ci.params, ctx->id("mode"), 0); 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; + if (mode > 1) { + // XRF + ci.type = id_XRF; + 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); - //} + 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); @@ -1008,6 +1029,18 @@ void NgUltraPacker::promote_globals() if (ddfr_removed) log_info(" Removed %d unused DDFRs\n", ddfr_removed); } + +void NgUltraPacker::pack_rams(void) +{ + log_info("Packing RAMs..\n"); + for (auto &cell : ctx->cells) { + CellInfo &ci = *cell.second; + if (!ci.type.in(id_NX_RAM)) + continue; + ci.type = id_RAM; + } +} + void NgUltraImpl::pack() { const ArchArgs &args = ctx->args; @@ -1020,6 +1053,7 @@ void NgUltraImpl::pack() packer.update_dffs(); packer.pack_iobs(); packer.pack_ioms(); + packer.pack_rams(); packer.pack_rfs(); packer.pack_cys(); packer.pack_lut_dffs(); diff --git a/himbaechel/uarch/ng-ultra/pack.h b/himbaechel/uarch/ng-ultra/pack.h index 482afbb6..9840aa9b 100644 --- a/himbaechel/uarch/ng-ultra/pack.h +++ b/himbaechel/uarch/ng-ultra/pack.h @@ -50,6 +50,8 @@ struct NgUltraPacker void pack_cys(); void pack_rfs(); + void pack_rams(); + // IO void pack_iobs(); void pack_ioms(); @@ -66,6 +68,8 @@ private: 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); + void disconnect_if_gnd(CellInfo *cell, IdString input); + // General helper functions void flush_cells();