From 96b073c0017c2f592c0fdf9399d2c99465384d66 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 29 Nov 2024 09:45:16 +0100 Subject: [PATCH] clangformat --- himbaechel/uarch/ng-ultra/bitstream.cc | 313 ++++--- himbaechel/uarch/ng-ultra/csv.cc | 402 ++++----- himbaechel/uarch/ng-ultra/extra_data.h | 27 +- himbaechel/uarch/ng-ultra/location_map.cc | 762 ++++++++-------- himbaechel/uarch/ng-ultra/location_map.h | 2 +- himbaechel/uarch/ng-ultra/ng_ultra.cc | 802 +++++++++-------- himbaechel/uarch/ng-ultra/ng_ultra.h | 21 +- himbaechel/uarch/ng-ultra/pack.cc | 973 ++++++++++++--------- himbaechel/uarch/ng-ultra/pack.h | 10 +- himbaechel/uarch/ng-ultra/tests/lut_dff.cc | 48 +- himbaechel/uarch/ng-ultra/tests/main.cc | 2 +- 11 files changed, 1812 insertions(+), 1550 deletions(-) diff --git a/himbaechel/uarch/ng-ultra/bitstream.cc b/himbaechel/uarch/ng-ultra/bitstream.cc index b30cf13b..145218a3 100644 --- a/himbaechel/uarch/ng-ultra/bitstream.cc +++ b/himbaechel/uarch/ng-ultra/bitstream.cc @@ -44,7 +44,7 @@ struct BitstreamJsonBackend std::ostream &out; bool first_instance; - BitstreamJsonBackend(Context *ctx, NgUltraImpl *uarch, std::ostream &out) : ctx(ctx), uarch(uarch), out(out){}; + BitstreamJsonBackend(Context *ctx, NgUltraImpl *uarch, std::ostream &out) : ctx(ctx), uarch(uarch), out(out) {}; std::string get_string(std::string str) { @@ -59,40 +59,39 @@ struct BitstreamJsonBackend std::string update_name(std::string tile, std::string name) { - if (boost::starts_with(tile,"FENCE[")) { - char last = tile[tile.size()-2]; - switch(last) - { - case 'T': - case 'B': - case 'U': - case 'L': - std::string loc = tile.substr(tile.find("[")+1, tile.find("x")-tile.find("[")); - boost::replace_all(name, "1x", loc); - return name; + if (boost::starts_with(tile, "FENCE[")) { + char last = tile[tile.size() - 2]; + switch (last) { + case 'T': + case 'B': + case 'U': + case 'L': + std::string loc = tile.substr(tile.find("[") + 1, tile.find("x") - tile.find("[")); + boost::replace_all(name, "1x", loc); + return name; } } - if (boost::starts_with(tile,"TILE[") && boost::algorithm::contains(name,".FE")) { + if (boost::starts_with(tile, "TILE[") && boost::algorithm::contains(name, ".FE")) { std::string last = name.substr(name.rfind('.') + 1); - if (last[0]=='D') { + if (last[0] == 'D') { boost::replace_all(name, ".D", "."); boost::replace_all(name, ".FE", ".DFF"); return name; } - if (last=="L" || last=="R") { + if (last == "L" || last == "R") { boost::replace_all(name, ".FE", ".DFF"); return name; } - if (last=="CK") { + if (last == "CK") { boost::replace_all(name, ".FE", ".DFF"); return name; } - if (last[0]=='L') { + if (last[0] == 'L') { boost::replace_all(name, ".L", "."); boost::replace_all(name, ".FE", ".LUT"); return name; } - if (last[0]=='P') { + if (last[0] == 'P') { boost::replace_all(name, ".PI", ".I"); boost::replace_all(name, ".FE", ".LUT"); return name; @@ -101,10 +100,13 @@ struct BitstreamJsonBackend return name; } - void add_net(std::set &nets, std::string src_tile, std::string src_name, std::string dst_tile, std::string dst_name, IdString src_type, IdString dst_type) + void add_net(std::set &nets, std::string src_tile, std::string src_name, std::string dst_tile, + std::string dst_name, IdString src_type, IdString dst_type) { - if (src_type.in(ctx->id("LUT_PERMUTATION_WIRE"), ctx->id("MUX_WIRE"), ctx->id("INTERCONNECT_INPUT"))) return; - if (boost::starts_with(src_type.c_str(ctx),"CROSSBAR_") && boost::ends_with(src_type.c_str(ctx),"INPUT_WIRE")) return; + if (src_type.in(ctx->id("LUT_PERMUTATION_WIRE"), ctx->id("MUX_WIRE"), ctx->id("INTERCONNECT_INPUT"))) + return; + if (boost::starts_with(src_type.c_str(ctx), "CROSSBAR_") && boost::ends_with(src_type.c_str(ctx), "INPUT_WIRE")) + return; if (dst_type == ctx->id("MUX_WIRE")) dst_name = dst_name.substr(0, dst_name.rfind('.')); src_name = update_name(src_tile, src_name); @@ -112,10 +114,10 @@ struct BitstreamJsonBackend nets.emplace(stringf("%s:%s->%s:%s", src_tile.c_str(), src_name.c_str(), dst_tile.c_str(), dst_name.c_str())); } - + std::string cleanup_name(std::string name) { - std::replace(name.begin(), name.end(), '$', '_'); + std::replace(name.begin(), name.end(), '$', '_'); return name; } @@ -125,8 +127,10 @@ struct BitstreamJsonBackend bool first_net = true; for (auto &net : ctx->nets) { NetInfo *ni = net.second.get(); - if (ni->wires.empty()) continue; - out << (first_net ? "" : ",\n"); first_net = false; + if (ni->wires.empty()) + continue; + out << (first_net ? "" : ",\n"); + first_net = false; out << stringf("\t\t%s: [\n", get_string(cleanup_name(ni->name.c_str(ctx))).c_str()); std::set nets; for (auto &w : ni->wires) { @@ -139,7 +143,8 @@ struct BitstreamJsonBackend IdString src_type = ctx->getWireType(swire); IdString src_orig = IdString(chip_tile_info(ctx->chip_info, pip.tile).wires[pd.src_wire].name); - IdString src_orig_type = IdString(chip_tile_info(ctx->chip_info, pip.tile).wires[pd.src_wire].wire_type); + IdString src_orig_type = + IdString(chip_tile_info(ctx->chip_info, pip.tile).wires[pd.src_wire].wire_type); WireId dwire = ctx->getPipDstWire(pip); IdString dst = ctx->getWireName(dwire)[1]; @@ -147,26 +152,31 @@ struct BitstreamJsonBackend std::string s_tile_name = uarch->tile_name(swire.tile); std::string tile_name = uarch->tile_name(pip.tile); - - if (src_orig!=src) - add_net(nets, s_tile_name, src.c_str(ctx), tile_name, src_orig.c_str(ctx), src_type, src_orig_type); - if (!extra_data.name || (extra_data.type != PipExtra::PIP_EXTRA_BYPASS && extra_data.type != PipExtra::PIP_EXTRA_VIRTUAL && extra_data.type != PipExtra::PIP_EXTRA_MUX)) - add_net(nets, tile_name, src_orig.c_str(ctx), tile_name, dst.c_str(ctx), src_orig_type, dst_type); - } else if (ni->wires.size()==1) { + + if (src_orig != src) + add_net(nets, s_tile_name, src.c_str(ctx), tile_name, src_orig.c_str(ctx), src_type, + src_orig_type); + if (!extra_data.name || + (extra_data.type != PipExtra::PIP_EXTRA_BYPASS && + extra_data.type != PipExtra::PIP_EXTRA_VIRTUAL && extra_data.type != PipExtra::PIP_EXTRA_MUX)) + add_net(nets, tile_name, src_orig.c_str(ctx), tile_name, dst.c_str(ctx), src_orig_type, + dst_type); + } else if (ni->wires.size() == 1) { IdString src = ctx->getWireName(w.first)[1]; IdString src_type = ctx->getWireType(w.first); std::string s_tile_name = uarch->tile_name(w.first.tile); - for (auto &u : ni->users){ + for (auto &u : ni->users) { std::string tile_name = uarch->tile_name(u.cell->bel.tile); IdString bel_name = ctx->getBelName(u.cell->bel)[1]; - add_net(nets, s_tile_name, src.c_str(ctx), tile_name, stringf("%s.%s", bel_name.c_str(ctx), u.port.c_str(ctx)), src_type, src_type); + add_net(nets, s_tile_name, src.c_str(ctx), tile_name, + stringf("%s.%s", bel_name.c_str(ctx), u.port.c_str(ctx)), src_type, src_type); } } } bool first = true; for (auto &str : nets) { out << (first ? "" : ",\n"); - out << stringf("\t\t\t%s",get_string(str).c_str()); + out << stringf("\t\t\t%s", get_string(str).c_str()); first = false; } out << "\n\t\t]"; @@ -206,7 +216,8 @@ struct BitstreamJsonBackend } }; - template std::string extract_bits_or_default(const dict &ct, const KeyType &key, int bits, int def = 0) + 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; @@ -218,27 +229,30 @@ struct BitstreamJsonBackend void open_instance(CellInfo *cell, std::string rename = "") { - out << stringf("%s", first_instance ? "" : ",\n"); first_instance = false; - out << stringf("\t\t%s: {\n", get_string(cleanup_name(rename.empty() ? cell->name.c_str(ctx) : rename.c_str())).c_str()); + out << stringf("%s", first_instance ? "" : ",\n"); + first_instance = false; + out << stringf("\t\t%s: {\n", + get_string(cleanup_name(rename.empty() ? cell->name.c_str(ctx) : rename.c_str())).c_str()); std::string tile_name = uarch->tile_name(cell->bel.tile); IdString idx = ctx->getBelName(cell->bel)[1]; std::string belname = idx.c_str(ctx); config.clear(); - out << stringf("\t\t\t\"location\": %s,\n",get_string(tile_name + ":" + belname).c_str()); - out << stringf("\t\t\t\"type\": %s",get_string(cell->type.c_str(ctx)).c_str()); + out << stringf("\t\t\t\"location\": %s,\n", get_string(tile_name + ":" + belname).c_str()); + out << stringf("\t\t\t\"type\": %s", get_string(cell->type.c_str(ctx)).c_str()); } void open_instance_fe(CellInfo *cell, std::string type, std::string replace, std::string postfix = "") { - out << stringf("%s", first_instance ? "" : ",\n"); first_instance = false; + out << stringf("%s", first_instance ? "" : ",\n"); + first_instance = false; out << stringf("\t\t%s: {\n", get_string(cleanup_name(cell->name.c_str(ctx)) + postfix).c_str()); std::string tile_name = uarch->tile_name(cell->bel.tile); IdString idx = ctx->getBelName(cell->bel)[1]; std::string belname = idx.c_str(ctx); boost::replace_all(belname, ".FE", replace); config.clear(); - out << stringf("\t\t\t\"location\": %s,\n",get_string(tile_name + ":" + belname).c_str()); - out << stringf("\t\t\t\"type\": %s",get_string(type).c_str()); + out << stringf("\t\t\t\"location\": %s,\n", get_string(tile_name + ":" + belname).c_str()); + out << stringf("\t\t\t\"type\": %s", get_string(type).c_str()); } inline void add_config(std::string name, int val) @@ -256,20 +270,24 @@ struct BitstreamJsonBackend config.push_back(stringf("\t\t\t\t%s:%s", get_string(name).c_str(), get_string(val).c_str())); } - void close_instance() { + void close_instance() + { bool first = true; - if (!config.empty()) out << ",\n\t\t\t\"config\": {\n"; + if (!config.empty()) + out << ",\n\t\t\t\"config\": {\n"; for (auto &str : config) { out << (first ? "" : ",\n"); out << str.c_str(); first = false; } - if (!config.empty()) out << "\n\t\t\t}"; + if (!config.empty()) + out << "\n\t\t\t}"; out << "\n\t\t}"; config.clear(); } - void write_iop(CellInfo *cell) { + void write_iop(CellInfo *cell) + { open_instance(cell, str_or_default(cell->params, id_iobname, "")); add_config("location", str_or_default(cell->params, id_location, "")); add_config("differential", str_or_n_value_lower(cell->params, id_differential, "false")); @@ -294,15 +312,16 @@ struct BitstreamJsonBackend close_instance(); std::string tile_name = uarch->tile_name(cell->bel.tile); std::string bank = tile_name.substr(0, tile_name.rfind(':')); - if (uarch->bank_voltage.count(bank)==0) { - if (bank=="IOB0" || bank=="IOB1" || bank=="IOB6" || bank=="IOB7") + if (uarch->bank_voltage.count(bank) == 0) { + if (bank == "IOB0" || bank == "IOB1" || bank == "IOB6" || bank == "IOB7") uarch->bank_voltage[bank] = "3.3V"; else uarch->bank_voltage[bank] = "1.8V"; } } - void write_ddfr(CellInfo *cell) { + void write_ddfr(CellInfo *cell) + { open_instance(cell); add_config("dff_load", bool_or_default(cell->params, id_dff_load, false)); add_config("dff_sync", bool_or_default(cell->params, id_dff_sync, false)); @@ -312,7 +331,8 @@ struct BitstreamJsonBackend close_instance(); } - void write_dfr(CellInfo *cell) { + void write_dfr(CellInfo *cell) + { open_instance(cell); add_config("data_inv", bool_or_default(cell->params, id_data_inv, false)); add_config("dff_edge", bool_or_default(cell->params, id_dff_edge, false)); @@ -325,7 +345,8 @@ struct BitstreamJsonBackend close_instance(); } - void write_bfr(CellInfo *cell) { + void write_bfr(CellInfo *cell) + { open_instance(cell); add_config("mode", int_or_default(cell->params, id_mode, 2)); add_config("iobname", str_or_default(cell->params, id_iobname, "")); @@ -335,14 +356,16 @@ struct BitstreamJsonBackend close_instance(); } - void write_cy(CellInfo *cell) { + void write_cy(CellInfo *cell) + { open_instance(cell); add_config("add_carry", int_or_default(cell->params, id_add_carry, 0)); add_config("shifter", bool_or_default(cell->params, id_shifter, false)); close_instance(); } - void write_fe(CellInfo *cell) { + void write_fe(CellInfo *cell) + { if (bool_or_default(cell->params, id_lut_used)) { open_instance_fe(cell, "LUT", ".LUT"); add_config("lut_table", extract_bits_or_default(cell->params, id_lut_table, 16)); @@ -351,7 +374,7 @@ struct BitstreamJsonBackend if (bool_or_default(cell->params, id_dff_used)) { std::string subtype = str_or_default(cell->params, id_type, "DFF"); open_instance_fe(cell, subtype, ".DFF", "_D"); - if (subtype =="DFF") { + if (subtype == "DFF") { add_config("dff_ctxt", std::to_string(int_or_default(cell->params, id_dff_ctxt, 0))); add_config("dff_edge", bool_or_default(cell->params, id_dff_edge, false)); add_config("dff_init", bool_or_default(cell->params, id_dff_init, false)); @@ -363,19 +386,22 @@ struct BitstreamJsonBackend } } - void write_xlut(CellInfo *cell) { + void write_xlut(CellInfo *cell) + { open_instance(cell); add_config("lut_table", extract_bits_or_default(cell->params, id_lut_table, 16)); close_instance(); } - void write_iom(CellInfo *cell) { + void write_iom(CellInfo *cell) + { open_instance(cell); add_config("pads_path", str_or_default(cell->params, id_pads_path, ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;")); close_instance(); } - void write_gck(CellInfo *cell) { + void write_gck(CellInfo *cell) + { open_instance(cell); add_config("inv_in", bool_or_default(cell->params, id_inv_in, false)); add_config("inv_out", bool_or_default(cell->params, id_inv_out, false)); @@ -383,7 +409,8 @@ struct BitstreamJsonBackend close_instance(); } - void write_wfb(CellInfo *cell) { + void write_wfb(CellInfo *cell) + { open_instance(cell); add_config("delay_on", bool_or_default(cell->params, id_delay_on, false)); add_config("delay", int_or_default(cell->params, id_delay, 0)); @@ -391,7 +418,8 @@ struct BitstreamJsonBackend close_instance(); } - void write_wfg(CellInfo *cell) { + void write_wfg(CellInfo *cell) + { open_instance(cell); add_config("mode", int_or_default(cell->params, id_mode, 0)); add_config("delay_on", bool_or_default(cell->params, id_delay_on, false)); @@ -403,11 +431,12 @@ struct BitstreamJsonBackend add_config("div_phase", bool_or_default(cell->params, id_div_phase, false)); add_config("reset_on_pll_lock_n", bool_or_default(cell->params, id_reset_on_pll_lock_n, false)); add_config("reset_on_pll_locka_n", bool_or_default(cell->params, id_reset_on_pll_locka_n, false)); - add_config("reset_on_cal_lock_n", bool_or_default(cell->params, id_reset_on_cal_lock_n, false)); + add_config("reset_on_cal_lock_n", bool_or_default(cell->params, id_reset_on_cal_lock_n, false)); close_instance(); } - void write_pll(CellInfo *cell) { + void write_pll(CellInfo *cell) + { open_instance(cell); add_config("clk_outdiv1", extract_bits_or_default(cell->params, id_clk_outdiv1, 3)); add_config("clk_outdiv2", extract_bits_or_default(cell->params, id_clk_outdiv2, 3)); @@ -437,15 +466,18 @@ struct BitstreamJsonBackend close_instance(); } - void write_rfb(CellInfo *cell) { + void write_rfb(CellInfo *cell) + { open_instance(cell); std::string context = str_or_default(cell->params, id_mem_ctxt, ""); - if (!context.empty()) add_config("mem_ctxt", context); + if (!context.empty()) + add_config("mem_ctxt", context); add_config("wck_edge", bool_or_default(cell->params, id_wck_edge, false)); close_instance(); } - void write_ram(CellInfo *cell) { + void write_ram(CellInfo *cell) + { open_instance(cell); add_config("mcka_edge", bool_or_default(cell->params, id_mcka_edge, false)); add_config("mckb_edge", bool_or_default(cell->params, id_mckb_edge, false)); @@ -454,11 +486,13 @@ struct BitstreamJsonBackend add_config("raw_config0", extract_bits_or_default(cell->params, id_raw_config0, 4)); add_config("raw_config1", extract_bits_or_default(cell->params, id_raw_config1, 16)); std::string context = str_or_default(cell->params, id_mem_ctxt, ""); - if (!context.empty()) add_config("mem_ctxt", context); + if (!context.empty()) + add_config("mem_ctxt", context); close_instance(); } - void write_dsp(CellInfo *cell) { + void write_dsp(CellInfo *cell) + { open_instance(cell); add_config("raw_config0", extract_bits_or_default(cell->params, id_raw_config0, 27)); add_config("raw_config1", extract_bits_or_default(cell->params, id_raw_config1, 24)); @@ -467,7 +501,8 @@ struct BitstreamJsonBackend close_instance(); } - void write_cdc(CellInfo *cell) { + void write_cdc(CellInfo *cell) + { open_instance(cell); if (cell->type.in(id_DDE, id_TDE, id_CDC, id_XCDC)) { add_config("ck0_edge", bool_or_default(cell->params, id_ck0_edge, false)); @@ -495,7 +530,8 @@ struct BitstreamJsonBackend close_instance(); } - void write_fifo(CellInfo *cell) { + void write_fifo(CellInfo *cell) + { open_instance(cell); add_config("rck_edge", bool_or_default(cell->params, id_rck_edge, false)); add_config("wck_edge", bool_or_default(cell->params, id_wck_edge, false)); @@ -511,29 +547,33 @@ struct BitstreamJsonBackend { for (auto &net : ctx->nets) { NetInfo *ni = net.second.get(); - if (ni->wires.size()==0) continue; + if (ni->wires.size() == 0) + continue; std::vector nets; for (auto &w : ni->wires) { if (w.second.pip != PipId()) { PipId pip = w.second.pip; const auto &extra_data = *uarch->pip_extra_data(w.second.pip); - if (!extra_data.name || extra_data.type != PipExtra::PIP_EXTRA_INTERCONNECT) continue; + if (!extra_data.name || extra_data.type != PipExtra::PIP_EXTRA_INTERCONNECT) + continue; auto &pd = chip_pip_info(ctx->chip_info, pip); IdString src = IdString(chip_tile_info(ctx->chip_info, pip.tile).wires[pd.src_wire].name); std::string tile_name = uarch->tile_name(pip.tile); std::string src_name = src.c_str(ctx); std::string type = "OTC"; - if (src_name.find("UI1x") != std::string::npos) + if (src_name.find("UI1x") != std::string::npos) type = "ITC"; - if (boost::starts_with(src_name,"SO1.")) type = "OTS"; - if (boost::starts_with(src_name,"SI1.")) type = "ITS"; + if (boost::starts_with(src_name, "SO1.")) + type = "OTS"; + if (boost::starts_with(src_name, "SI1.")) + type = "ITS"; src_name = update_name(tile_name, src_name); src_name = src_name.substr(0, src_name.size() - 2); - std::string name = cleanup_name(std::string(ni->name.c_str(ctx))+ "_" + src_name.substr(4)); + std::string name = cleanup_name(std::string(ni->name.c_str(ctx)) + "_" + src_name.substr(4)); out << stringf(",\n\t\t%s: {\n", get_string(name).c_str()); - out << stringf("\t\t\t\"location\": %s,\n",get_string(tile_name + ":" + src_name).c_str()); - out << stringf("\t\t\t\"type\": %s\n\t\t}",get_string(type).c_str()); + out << stringf("\t\t\t\"location\": %s,\n", get_string(tile_name + ":" + src_name).c_str()); + out << stringf("\t\t\t\"type\": %s\n\t\t}", get_string(type).c_str()); } } } @@ -545,52 +585,87 @@ struct BitstreamJsonBackend first_instance = true; for (auto &cell : ctx->cells) { switch (cell.second->type.index) { - case id_BEYOND_FE.index: write_fe(cell.second.get()); break; - case id_IOP.index: - case id_IP.index: - case id_OP.index: - case id_IOTP.index: - case id_ITP.index: - case id_OTP.index: write_iop(cell.second.get()); break; - case id_CY.index: write_cy(cell.second.get()); break; - case id_WFB.index: write_wfb(cell.second.get()); break; - case id_WFG.index: write_wfg(cell.second.get()); break; - case id_GCK.index: write_gck(cell.second.get()); break; - case id_IOM.index: write_iom(cell.second.get()); break; - case id_BFR.index: write_bfr(cell.second.get()); break; - case id_DDFR.index: write_ddfr(cell.second.get()); break; - case id_DFR.index: write_dfr(cell.second.get()); break; - case id_RAM.index: write_ram(cell.second.get()); break; - case id_RF.index: - case id_RFSP.index: - case id_XHRF.index: - case id_XWRF.index: - case id_XPRF.index: write_rfb(cell.second.get()); break; - case id_XLUT.index: write_xlut(cell.second.get()); break; - case id_FIFO.index: // mode 0 - case id_XHFIFO.index: // mode 1 - case id_XWFIFO.index: write_fifo(cell.second.get()); break; // mode 2 - case id_DDE.index: // mode 0 - case id_TDE.index: // mode 1 - case id_CDC.index: // mode 2 - case id_BGC.index: // mode 3 - case id_GBC.index: // mode 4 - case id_XCDC.index: write_cdc(cell.second.get()); break; // mode 5 - case id_DSP.index: write_dsp(cell.second.get()); break; - case id_PLL.index: write_pll(cell.second.get()); break; - //case id_CRX.index: - //case id_CTX.index: - //case id_PMA.index: - //case id_Service.index: - //case id_SOCIF.index: - default: - log_error("Unhandled cell %s of type %s\n", cell.second.get()->name.c_str(ctx), cell.second->type.c_str(ctx)); + case id_BEYOND_FE.index: + write_fe(cell.second.get()); + break; + case id_IOP.index: + case id_IP.index: + case id_OP.index: + case id_IOTP.index: + case id_ITP.index: + case id_OTP.index: + write_iop(cell.second.get()); + break; + case id_CY.index: + write_cy(cell.second.get()); + break; + case id_WFB.index: + write_wfb(cell.second.get()); + break; + case id_WFG.index: + write_wfg(cell.second.get()); + break; + case id_GCK.index: + write_gck(cell.second.get()); + break; + case id_IOM.index: + write_iom(cell.second.get()); + break; + case id_BFR.index: + write_bfr(cell.second.get()); + break; + case id_DDFR.index: + write_ddfr(cell.second.get()); + break; + case id_DFR.index: + write_dfr(cell.second.get()); + break; + case id_RAM.index: + write_ram(cell.second.get()); + break; + case id_RF.index: + case id_RFSP.index: + case id_XHRF.index: + case id_XWRF.index: + case id_XPRF.index: + write_rfb(cell.second.get()); + break; + case id_XLUT.index: + write_xlut(cell.second.get()); + break; + case id_FIFO.index: // mode 0 + case id_XHFIFO.index: // mode 1 + case id_XWFIFO.index: + write_fifo(cell.second.get()); + break; // mode 2 + case id_DDE.index: // mode 0 + case id_TDE.index: // mode 1 + case id_CDC.index: // mode 2 + case id_BGC.index: // mode 3 + case id_GBC.index: // mode 4 + case id_XCDC.index: + write_cdc(cell.second.get()); + break; // mode 5 + case id_DSP.index: + write_dsp(cell.second.get()); + break; + case id_PLL.index: + write_pll(cell.second.get()); + break; + // case id_CRX.index: + // case id_CTX.index: + // case id_PMA.index: + // case id_Service.index: + // case id_SOCIF.index: + default: + log_error("Unhandled cell %s of type %s\n", cell.second.get()->name.c_str(ctx), + cell.second->type.c_str(ctx)); } } write_interconnections(); out << "\n\t},\n"; } - + void write_setup() { out << "\t\"setup\": {\n"; @@ -599,7 +674,7 @@ struct BitstreamJsonBackend bool first = true; for (auto &bank : uarch->bank_voltage) { out << (first ? "" : ",\n"); - out << stringf("\t\t\t%s:%s",get_string(bank.first).c_str(),get_string(bank.second).c_str()); + out << stringf("\t\t\t%s:%s", get_string(bank.first).c_str(), get_string(bank.second).c_str()); first = false; } out << "\n\t\t}\n\t}\n"; diff --git a/himbaechel/uarch/ng-ultra/csv.cc b/himbaechel/uarch/ng-ultra/csv.cc index dbf1cebc..32e0861a 100644 --- a/himbaechel/uarch/ng-ultra/csv.cc +++ b/himbaechel/uarch/ng-ultra/csv.cc @@ -82,217 +82,219 @@ void NgUltraImpl::parse_csv(const std::string &filename) boost::split(arguments, line, boost::is_any_of(",")); if (arguments.empty()) continue; - switch(line_type) { - case IO_PADS: - { - if (arguments.size()==1 && arguments[0][0]=='!') { - line_type = IO_BANKS; - continue; - } - if (arguments.size()!=15) - log_error("number of parameters in line %d must be 15\n", lineno); + switch (line_type) { + case IO_PADS: { + if (arguments.size() == 1 && arguments[0][0] == '!') { + line_type = IO_BANKS; + continue; + } + if (arguments.size() != 15) + log_error("number of parameters in line %d must be 15\n", lineno); - std::string arg_iobname = arguments.at(0); - std::string arg_location = arguments.at(1); - std::string arg_standard = arguments.at(2); - std::string arg_drive = arguments.at(3); - std::string arg_slewRate = arguments.at(4); - std::string arg_inputDelayLine = arguments.at(5); - std::string arg_outputDelayLine = arguments.at(6); - std::string arg_differential = arguments.at(7); - std::string arg_weakTermination = arguments.at(8); - std::string arg_termination = arguments.at(9); - std::string arg_terminationReference = arguments.at(10); - std::string arg_turbo = arguments.at(11); - std::string arg_inputSignalSlope = arguments.at(12); - std::string arg_outputCapacity = arguments.at(13); - std::string arg_registered = arguments.at(14); + std::string arg_iobname = arguments.at(0); + std::string arg_location = arguments.at(1); + std::string arg_standard = arguments.at(2); + std::string arg_drive = arguments.at(3); + std::string arg_slewRate = arguments.at(4); + std::string arg_inputDelayLine = arguments.at(5); + std::string arg_outputDelayLine = arguments.at(6); + std::string arg_differential = arguments.at(7); + std::string arg_weakTermination = arguments.at(8); + std::string arg_termination = arguments.at(9); + std::string arg_terminationReference = arguments.at(10); + std::string arg_turbo = arguments.at(11); + std::string arg_inputSignalSlope = arguments.at(12); + std::string arg_outputCapacity = arguments.at(13); + std::string arg_registered = arguments.at(14); - // TODO: Remove this block - const std::vector weak_values_check = { "None", "PullDown", "PullUp", "Keeper" }; - auto it2 = std::find(std::begin(weak_values_check),std::end(weak_values_check), arguments.at(4)); - if (it2 != std::end(weak_values_check)) { - if (!old_format) { - log_warning("Old CSV format detected. Please update file.\n"); - old_format = true; - } - arg_weakTermination = arguments.at(4); - arg_slewRate = arguments.at(5); - arg_termination = arguments.at(6); - arg_inputDelayLine = arguments.at(7); - arg_outputDelayLine = arguments.at(8); - arg_differential = arguments.at(9); - } - // End of block - - if (!(boost::starts_with(arg_location, "IOB") && boost::contains(arg_location,"_D"))) - log_error("invalid location name '%s' must start with 'IOB' in line %d\n", arg_location.c_str(), lineno); - - const std::vector standard_values = { "LVDS", "LVCMOS", "SSTL", "HSTL" }; // , "POD" - auto it = std::find(std::begin(standard_values),std::end(standard_values), arg_standard); - if (it == std::end(standard_values)) - log_error("unknown standard value '%s' in line %d\n", arg_standard.c_str(), lineno); - - const std::vector drive_values = { "2mA", "4mA", "8mA", "16mA", "CatI", "CatII", "Undefined" }; // "6mA", "12mA", - it = std::find(std::begin(drive_values),std::end(drive_values), arg_drive); - if (it == std::end(drive_values)) - log_error("unknown drive value '%s' in line %d\n", arg_drive.c_str(), lineno); - - const std::vector slew_values = { "Slow", "Medium", "Fast" }; - it = std::find(std::begin(slew_values),std::end(slew_values), arg_slewRate); - if (it == std::end(slew_values)) - log_error("unknown weak termination value '%s' in line %d\n", arg_slewRate.c_str(), lineno); - - if (!is_number(arg_inputDelayLine)) { - log_error("input delay must be number, value '%s' in line %d\n", arg_inputDelayLine.c_str(), lineno); - } else { - int delay = std::stoi(arg_inputDelayLine); - if (delay<0 || delay >63) - log_error("input delay value must be in range from 0 to 63 in line %d\n", lineno); - } - if (!is_number(arg_outputDelayLine)) { - log_error("output delay must be number, value '%s' in line %d\n", arg_outputDelayLine.c_str(), lineno); - } else { - int delay = std::stoi(arg_outputDelayLine); - if (delay<0 || delay >63) - log_error("output delay value must be in range from 0 to 63 in line %d\n", lineno); - } - - if (!arg_differential.empty() && arg_differential != "True" && arg_differential != "False") - log_error("differential must be boolean, value '%s' in line %d\n", arg_differential.c_str(), lineno); - - const std::vector weak_values = { "None", "PullDown", "PullUp", "Keeper" }; - it = std::find(std::begin(weak_values),std::end(weak_values), arg_weakTermination); - if (it == std::end(weak_values)) - log_error("unknown weak termination value '%s' in line %d\n", arg_weakTermination.c_str(), lineno); - - if (!arg_termination.empty()) { - if (!is_number(arg_termination)) { - log_error("termination must be string containing int, value '%s' in line %d\n", arg_termination.c_str(), lineno); - } else { - int termination = std::stoi(arg_termination); - if (termination<30 || termination >80) - log_error("termination value must be in range from 30 to 80 in line %d\n", lineno); - } - } - - const std::vector termref_values = { "Floating", "VT" }; - it = std::find(std::begin(termref_values),std::end(termref_values), arg_terminationReference); - if (it == std::end(termref_values)) - log_error("unknown termination reference value '%s' in line %d\n", arg_terminationReference.c_str(), lineno); - - if (!arg_turbo.empty() && arg_turbo != "True" && arg_turbo != "False") - log_error("turbo must be boolean, value '%s' in line %d\n", arg_turbo.c_str(), lineno); - - if (!arg_inputSignalSlope.empty() && !is_number(arg_inputSignalSlope)) - log_error("signal slope must be number, value '%s' in line %d\n", arg_inputSignalSlope.c_str(), lineno); - if (!arg_outputCapacity.empty() && !is_number(arg_outputCapacity)) - log_error("output capacity must be number, value '%s' in line %d\n", arg_outputCapacity.c_str(), lineno); - - const std::vector registered_values = { "Auto", "I", "IC", "O", "OC", "IO", "IOC" }; - it = std::find(std::begin(registered_values),std::end(registered_values), arg_registered); - if (it == std::end(registered_values)) - log_error("unknown registered value '%s' in line %d\n", arg_registered.c_str(), lineno); - - if (arg_standard=="LVDS" && arg_drive!="Undefined") - log_error("for port in line %d when standard is 'LVDS' drive must be 'Undefined'\n", lineno); - if (arg_standard=="LVCMOS" && !boost::ends_with(arg_drive,"mA")) - log_error("for port in line %d when standard is 'LVCMOS' drive current must be in mA\n", lineno); - if ((arg_standard=="SSTL" || arg_standard=="HSTL") && !boost::starts_with(arg_drive,"Cat")) - log_error("for port in line %d when standard is 'SSTL' or 'HSTL' drive current must be in 'CatI' or 'CatII'\n", lineno); - - - if (arg_terminationReference=="Floating") { - if (!(arg_differential == "True" && arg_weakTermination == "None")) { - log_error("for floating termination, differential myst be 'True' and weakTermination must be 'None' in line %d\n", lineno); - } - } - std::vector dest = get_cells(arg_iobname); - for (auto c : dest) { - c->params[id_iobname] = arg_iobname; - c->params[id_location] = arg_location; - c->params[id_standard] = arg_standard; - c->params[id_drive] = arg_drive; - c->params[id_slewRate] = arg_slewRate; - c->params[id_inputDelayLine] = arg_inputDelayLine; - c->params[id_outputDelayLine] = arg_outputDelayLine; - c->params[id_inputDelayOn] = std::string((std::stoi(arg_inputDelayLine)!=0) ? "True" : "False"); - c->params[id_outputDelayOn] = std::string((std::stoi(arg_outputDelayLine)!=0) ? "True" : "False"); - c->params[id_differential] = arg_differential; - c->params[id_weakTermination] = arg_weakTermination; - if (!arg_termination.empty()) { - c->params[id_termination] = arg_termination; - c->params[id_terminationReference] = arg_terminationReference; - } - c->params[id_turbo] = arg_turbo; - c->params[id_inputSignalSlope] = arg_inputSignalSlope; - c->params[id_outputCapacity] = arg_outputCapacity; - c->params[id_registered] = arg_registered; - } - if (dest.size()==0) - log_warning("Pad with name '%s' not found in netlist.\n", arg_iobname.c_str()); - - std::string bank_name = arg_location.substr(0,arg_location.find_first_of('_')); - banks_used.emplace(bank_name); + // TODO: Remove this block + const std::vector weak_values_check = {"None", "PullDown", "PullUp", "Keeper"}; + auto it2 = std::find(std::begin(weak_values_check), std::end(weak_values_check), arguments.at(4)); + if (it2 != std::end(weak_values_check)) { + if (!old_format) { + log_warning("Old CSV format detected. Please update file.\n"); + old_format = true; } - break; - case IO_BANKS: - { - if (arguments.size()==1 && arguments[0][0]=='!') { - line_type = IO_GCKS; - continue; - } - if (arguments.size()!=3) - log_error("number of parameters in line %d must be 3\n", lineno); + arg_weakTermination = arguments.at(4); + arg_slewRate = arguments.at(5); + arg_termination = arguments.at(6); + arg_inputDelayLine = arguments.at(7); + arg_outputDelayLine = arguments.at(8); + arg_differential = arguments.at(9); + } + // End of block - if (!boost::starts_with(arguments.at(0), "IOB")) - log_error("wrong bank name '%s' in line %d\n", arguments.at(0).c_str(), lineno); - - const char* voltages[] = { "1.2V", "1.5V", "1.8V", "2.5V", "3.3V" }; - auto it = std::find(std::begin(voltages),std::end(voltages), arguments.at(1)); - if (it == std::end(voltages)) - log_error("unknown voltage level '%s' in line %d\n", arguments.at(1).c_str(), lineno); + if (!(boost::starts_with(arg_location, "IOB") && boost::contains(arg_location, "_D"))) + log_error("invalid location name '%s' must start with 'IOB' in line %d\n", arg_location.c_str(), + lineno); - const char * direct_io_voltages[] = { "1.8V", "2.5V", "3.3V" }; - const char * complex_io_voltages[] = { "1.2V", "1.5V", "1.8V" }; + const std::vector standard_values = {"LVDS", "LVCMOS", "SSTL", "HSTL"}; // , "POD" + auto it = std::find(std::begin(standard_values), std::end(standard_values), arg_standard); + if (it == std::end(standard_values)) + log_error("unknown standard value '%s' in line %d\n", arg_standard.c_str(), lineno); - int bank = std::stoi(arguments.at(0).substr(3)); - switch(bank) { - // direct - case 0: - case 1: - case 6: - case 7: - { - auto it = std::find(std::begin(direct_io_voltages),std::end(direct_io_voltages), arguments.at(1)); - if (it == std::end(direct_io_voltages)) - log_error("unsupported voltage level '%s' for bank '%s'\n", arguments.at(1).c_str(), arguments.at(0).c_str()); - } - break; - // complex - default: - auto it = std::find(std::begin(complex_io_voltages),std::end(complex_io_voltages), arguments.at(1)); - if (it == std::end(complex_io_voltages)) - log_error("unsupported voltage level '%s' for bank '%s'\n", arguments.at(1).c_str(), arguments.at(0).c_str()); - } - bank_voltage[arguments.at(0)] = arguments.at(1); + const std::vector drive_values = {"2mA", "4mA", "8mA", "16mA", + "CatI", "CatII", "Undefined"}; // "6mA", "12mA", + it = std::find(std::begin(drive_values), std::end(drive_values), arg_drive); + if (it == std::end(drive_values)) + log_error("unknown drive value '%s' in line %d\n", arg_drive.c_str(), lineno); + + const std::vector slew_values = {"Slow", "Medium", "Fast"}; + it = std::find(std::begin(slew_values), std::end(slew_values), arg_slewRate); + if (it == std::end(slew_values)) + log_error("unknown weak termination value '%s' in line %d\n", arg_slewRate.c_str(), lineno); + + if (!is_number(arg_inputDelayLine)) { + log_error("input delay must be number, value '%s' in line %d\n", arg_inputDelayLine.c_str(), lineno); + } else { + int delay = std::stoi(arg_inputDelayLine); + if (delay < 0 || delay > 63) + log_error("input delay value must be in range from 0 to 63 in line %d\n", lineno); + } + if (!is_number(arg_outputDelayLine)) { + log_error("output delay must be number, value '%s' in line %d\n", arg_outputDelayLine.c_str(), lineno); + } else { + int delay = std::stoi(arg_outputDelayLine); + if (delay < 0 || delay > 63) + log_error("output delay value must be in range from 0 to 63 in line %d\n", lineno); + } + + if (!arg_differential.empty() && arg_differential != "True" && arg_differential != "False") + log_error("differential must be boolean, value '%s' in line %d\n", arg_differential.c_str(), lineno); + + const std::vector weak_values = {"None", "PullDown", "PullUp", "Keeper"}; + it = std::find(std::begin(weak_values), std::end(weak_values), arg_weakTermination); + if (it == std::end(weak_values)) + log_error("unknown weak termination value '%s' in line %d\n", arg_weakTermination.c_str(), lineno); + + if (!arg_termination.empty()) { + if (!is_number(arg_termination)) { + log_error("termination must be string containing int, value '%s' in line %d\n", + arg_termination.c_str(), lineno); + } else { + int termination = std::stoi(arg_termination); + if (termination < 30 || termination > 80) + log_error("termination value must be in range from 30 to 80 in line %d\n", lineno); } - break; - case IO_GCKS: - { - if (arguments.size()==1 && arguments[0][0]=='!') { - line_type = IO_ERROR; - continue; - } - if (arguments.size()!=2) - log_error("number of parameters in line %d must be 2\n", lineno); + } + + const std::vector termref_values = {"Floating", "VT"}; + it = std::find(std::begin(termref_values), std::end(termref_values), arg_terminationReference); + if (it == std::end(termref_values)) + log_error("unknown termination reference value '%s' in line %d\n", arg_terminationReference.c_str(), + lineno); + + if (!arg_turbo.empty() && arg_turbo != "True" && arg_turbo != "False") + log_error("turbo must be boolean, value '%s' in line %d\n", arg_turbo.c_str(), lineno); + + if (!arg_inputSignalSlope.empty() && !is_number(arg_inputSignalSlope)) + log_error("signal slope must be number, value '%s' in line %d\n", arg_inputSignalSlope.c_str(), lineno); + if (!arg_outputCapacity.empty() && !is_number(arg_outputCapacity)) + log_error("output capacity must be number, value '%s' in line %d\n", arg_outputCapacity.c_str(), + lineno); + + const std::vector registered_values = {"Auto", "I", "IC", "O", "OC", "IO", "IOC"}; + it = std::find(std::begin(registered_values), std::end(registered_values), arg_registered); + if (it == std::end(registered_values)) + log_error("unknown registered value '%s' in line %d\n", arg_registered.c_str(), lineno); + + if (arg_standard == "LVDS" && arg_drive != "Undefined") + log_error("for port in line %d when standard is 'LVDS' drive must be 'Undefined'\n", lineno); + if (arg_standard == "LVCMOS" && !boost::ends_with(arg_drive, "mA")) + log_error("for port in line %d when standard is 'LVCMOS' drive current must be in mA\n", lineno); + if ((arg_standard == "SSTL" || arg_standard == "HSTL") && !boost::starts_with(arg_drive, "Cat")) + log_error("for port in line %d when standard is 'SSTL' or 'HSTL' drive current must be in 'CatI' or " + "'CatII'\n", + lineno); + + if (arg_terminationReference == "Floating") { + if (!(arg_differential == "True" && arg_weakTermination == "None")) { + log_error("for floating termination, differential myst be 'True' and weakTermination must be " + "'None' in line %d\n", + lineno); } - break; + } + std::vector dest = get_cells(arg_iobname); + for (auto c : dest) { + c->params[id_iobname] = arg_iobname; + c->params[id_location] = arg_location; + c->params[id_standard] = arg_standard; + c->params[id_drive] = arg_drive; + c->params[id_slewRate] = arg_slewRate; + c->params[id_inputDelayLine] = arg_inputDelayLine; + c->params[id_outputDelayLine] = arg_outputDelayLine; + c->params[id_inputDelayOn] = std::string((std::stoi(arg_inputDelayLine) != 0) ? "True" : "False"); + c->params[id_outputDelayOn] = std::string((std::stoi(arg_outputDelayLine) != 0) ? "True" : "False"); + c->params[id_differential] = arg_differential; + c->params[id_weakTermination] = arg_weakTermination; + if (!arg_termination.empty()) { + c->params[id_termination] = arg_termination; + c->params[id_terminationReference] = arg_terminationReference; + } + c->params[id_turbo] = arg_turbo; + c->params[id_inputSignalSlope] = arg_inputSignalSlope; + c->params[id_outputCapacity] = arg_outputCapacity; + c->params[id_registered] = arg_registered; + } + if (dest.size() == 0) + log_warning("Pad with name '%s' not found in netlist.\n", arg_iobname.c_str()); + + std::string bank_name = arg_location.substr(0, arg_location.find_first_of('_')); + banks_used.emplace(bank_name); + } break; + case IO_BANKS: { + if (arguments.size() == 1 && arguments[0][0] == '!') { + line_type = IO_GCKS; + continue; + } + if (arguments.size() != 3) + log_error("number of parameters in line %d must be 3\n", lineno); + + if (!boost::starts_with(arguments.at(0), "IOB")) + log_error("wrong bank name '%s' in line %d\n", arguments.at(0).c_str(), lineno); + + const char *voltages[] = {"1.2V", "1.5V", "1.8V", "2.5V", "3.3V"}; + auto it = std::find(std::begin(voltages), std::end(voltages), arguments.at(1)); + if (it == std::end(voltages)) + log_error("unknown voltage level '%s' in line %d\n", arguments.at(1).c_str(), lineno); + + const char *direct_io_voltages[] = {"1.8V", "2.5V", "3.3V"}; + const char *complex_io_voltages[] = {"1.2V", "1.5V", "1.8V"}; + + int bank = std::stoi(arguments.at(0).substr(3)); + switch (bank) { + // direct + case 0: + case 1: + case 6: + case 7: { + auto it = std::find(std::begin(direct_io_voltages), std::end(direct_io_voltages), arguments.at(1)); + if (it == std::end(direct_io_voltages)) + log_error("unsupported voltage level '%s' for bank '%s'\n", arguments.at(1).c_str(), + arguments.at(0).c_str()); + } break; + // complex default: - log_error("switching to unknown block of data in line %d\n", lineno); + auto it = std::find(std::begin(complex_io_voltages), std::end(complex_io_voltages), arguments.at(1)); + if (it == std::end(complex_io_voltages)) + log_error("unsupported voltage level '%s' for bank '%s'\n", arguments.at(1).c_str(), + arguments.at(0).c_str()); + } + bank_voltage[arguments.at(0)] = arguments.at(1); + } break; + case IO_GCKS: { + if (arguments.size() == 1 && arguments[0][0] == '!') { + line_type = IO_ERROR; + continue; + } + if (arguments.size() != 2) + log_error("number of parameters in line %d must be 2\n", lineno); + } break; + default: + log_error("switching to unknown block of data in line %d\n", lineno); } } - for(auto& bank_name : banks_used) { + for (auto &bank_name : banks_used) { if (bank_voltage.count(bank_name) == 0) { log_error("IO for bank '%s' defined, but no bank configuration.\n", bank_name.c_str()); } diff --git a/himbaechel/uarch/ng-ultra/extra_data.h b/himbaechel/uarch/ng-ultra/extra_data.h index 056998a2..efd922fe 100644 --- a/himbaechel/uarch/ng-ultra/extra_data.h +++ b/himbaechel/uarch/ng-ultra/extra_data.h @@ -40,8 +40,15 @@ NPNR_PACKED_STRUCT(struct NGUltraPipExtraDataPOD { NPNR_PACKED_STRUCT(struct NGUltraBelExtraDataPOD { int32_t flags; }); -struct GckConfig { - explicit GckConfig(BelId belid) { bel = belid; si1 = IdString(); si2 = IdString(); used = false; } +struct GckConfig +{ + explicit GckConfig(BelId belid) + { + bel = belid; + si1 = IdString(); + si2 = IdString(); + used = false; + } BelId bel; IdString si1; IdString si2; @@ -50,16 +57,16 @@ struct GckConfig { enum TILETypeZ { - BEL_LUT_Z = 0, + BEL_LUT_Z = 0, BEL_LUT_MAX_Z = 31, - BEL_CY_Z = 32, - BEL_XLUT_Z = BEL_CY_Z + 4, - BEL_RF_Z = BEL_XLUT_Z + 8, - BEL_XRF_Z = BEL_RF_Z + 2, - BEL_FIFO_Z = BEL_XRF_Z + 1, + BEL_CY_Z = 32, + BEL_XLUT_Z = BEL_CY_Z + 4, + BEL_RF_Z = BEL_XLUT_Z + 8, + BEL_XRF_Z = BEL_RF_Z + 2, + BEL_FIFO_Z = BEL_XRF_Z + 1, BEL_XFIFO_Z = BEL_FIFO_Z + 2, - BEL_CDC_Z = BEL_XFIFO_Z + 1, - BEL_XCDC_Z = BEL_CDC_Z + 2 + BEL_CDC_Z = BEL_XFIFO_Z + 1, + BEL_XCDC_Z = BEL_CDC_Z + 2 }; enum ClusterPlacement diff --git a/himbaechel/uarch/ng-ultra/location_map.cc b/himbaechel/uarch/ng-ultra/location_map.cc index 0ded4c01..d3e38173 100644 --- a/himbaechel/uarch/ng-ultra/location_map.cc +++ b/himbaechel/uarch/ng-ultra/location_map.cc @@ -24,440 +24,433 @@ NEXTPNR_NAMESPACE_BEGIN namespace { const Loc ng_ultra_place_cy_map[24] = { - { 0, 1, 0 }, // S1 0 -> S2 0 CY24->CY1 - { 0, 0, -1 }, // S1 1 -> S1 0 CY23->CY24 - { 0, 0, -1 }, // S1 2 -> S1 1 CY22->CY23 - { 0, 0, -1 }, // S1 3 -> S1 2 CY21->CY22 + {0, 1, 0}, // S1 0 -> S2 0 CY24->CY1 + {0, 0, -1}, // S1 1 -> S1 0 CY23->CY24 + {0, 0, -1}, // S1 2 -> S1 1 CY22->CY23 + {0, 0, -1}, // S1 3 -> S1 2 CY21->CY22 - {-1, 0,+3}, // S5 0 -> S1 1 CY20->CY21 - {0, 0, -1}, // S5 1 -> S5 0 CY19->CY20 - {0, 0, -1}, // S5 2 -> S5 1 CY18->CY19 - {0, 0, -1}, // S5 3 -> S5 2 CY17->CY18 + {-1, 0, +3}, // S5 0 -> S1 1 CY20->CY21 + {0, 0, -1}, // S5 1 -> S5 0 CY19->CY20 + {0, 0, -1}, // S5 2 -> S5 1 CY18->CY19 + {0, 0, -1}, // S5 3 -> S5 2 CY17->CY18 - {-1, 0,+3}, // S9 0 -> S5 1 CY16->CY17 - {0, 0, -1}, // S9 1 -> S9 0 CY15->CY16 - {0, 0, -1}, // S9 2 -> S9 1 CY14->CY15 - {0, 0, -1}, // S9 3 -> S9 2 CY13->CY14 + {-1, 0, +3}, // S9 0 -> S5 1 CY16->CY17 + {0, 0, -1}, // S9 1 -> S9 0 CY15->CY16 + {0, 0, -1}, // S9 2 -> S9 1 CY14->CY15 + {0, 0, -1}, // S9 3 -> S9 2 CY13->CY14 - {0, 0, +1}, // S2 0 -> S2 1 CY1->CY2 - {0, 0, +1}, // S2 1 -> S2 2 CY2->CY3 - {0, 0, +1}, // S2 2 -> S2 3 CY3->CY4 - {1, 0, -3}, // S2 3 -> S6 0 CY4->CY5 + {0, 0, +1}, // S2 0 -> S2 1 CY1->CY2 + {0, 0, +1}, // S2 1 -> S2 2 CY2->CY3 + {0, 0, +1}, // S2 2 -> S2 3 CY3->CY4 + {1, 0, -3}, // S2 3 -> S6 0 CY4->CY5 - {0, 0, +1}, // S6 0 -> S6 1 CY5->CY6 - {0, 0, +1}, // S6 1 -> S6 2 CY6->CY7 - {0, 0, +1}, // S6 2 -> S6 3 CY7->CY8 - {1, 0, -3}, // S6 3 -> S10 0 CY8->CY9 + {0, 0, +1}, // S6 0 -> S6 1 CY5->CY6 + {0, 0, +1}, // S6 1 -> S6 2 CY6->CY7 + {0, 0, +1}, // S6 2 -> S6 3 CY7->CY8 + {1, 0, -3}, // S6 3 -> S10 0 CY8->CY9 - {0, 0, +1}, // S10 0 -> S10 1 CY9->CY10 - {0, 0, +1}, // S10 1 -> S10 2 CY10->CY11 - {0, 0, +1}, // S10 2 -> S10 3 CY11->CY12 - {0,-1, 0}, // S10 3 -> S9 3 CY12->CY13 + {0, 0, +1}, // S10 0 -> S10 1 CY9->CY10 + {0, 0, +1}, // S10 1 -> S10 2 CY10->CY11 + {0, 0, +1}, // S10 2 -> S10 3 CY11->CY12 + {0, -1, 0}, // S10 3 -> S9 3 CY12->CY13 }; -const Loc ng_ultra_place_xrf[] = -{ - {-1, 0, 1},// I/O1 - {-1, 0, 2},// I/O2 - {-1, 0, 5},// I/O3 - {-1, 0, 6},// I/O4 - {-1, 0, 7},// I/O5 - {-1, 0, 9},// I/O6 - {-1, 0, 10},// I/O7 - {-1, 0, 13},// I/O8 - {-1, 0, 14},// I/O9 - {-1, 0, 15},// I/O10 - {-1, 0, 16},// I/O11 - {-1, 0, 17},// I/O12 - {-1, 0, 18},// I/O13 - {-1, 0, 21},// I/O14 - {-1, 0, 24},// I/O15 - {-1, 0, 25},// I/O16 - {-1, 0, 26},// I/O17 - {-1, 0, 29},// I/O18 +const Loc ng_ultra_place_xrf[] = { + {-1, 0, 1}, // I/O1 + {-1, 0, 2}, // I/O2 + {-1, 0, 5}, // I/O3 + {-1, 0, 6}, // I/O4 + {-1, 0, 7}, // I/O5 + {-1, 0, 9}, // I/O6 + {-1, 0, 10}, // I/O7 + {-1, 0, 13}, // I/O8 + {-1, 0, 14}, // I/O9 + {-1, 0, 15}, // I/O10 + {-1, 0, 16}, // I/O11 + {-1, 0, 17}, // I/O12 + {-1, 0, 18}, // I/O13 + {-1, 0, 21}, // I/O14 + {-1, 0, 24}, // I/O15 + {-1, 0, 25}, // I/O16 + {-1, 0, 26}, // I/O17 + {-1, 0, 29}, // I/O18 - {+1, 0, 1},// I/O19 - {+1, 0, 2},// I/O20 - {+1, 0, 5},// I/O21 - {+1, 0, 6},// I/O22 - {+1, 0, 7},// I/O23 - {+1, 0, 9},// I/O24 - {+1, 0, 10},// I/O25 - {+1, 0, 13},// I/O26 - {+1, 0, 14},// I/O27 - {+1, 0, 15},// I/O28 - {+1, 0, 16},// I/O29 - {+1, 0, 17},// I/O30 - {+1, 0, 18},// I/O31 - {+1, 0, 21},// I/O32 - {+1, 0, 24},// I/O33 - {+1, 0, 25},// I/O34 - {+1, 0, 26},// I/O35 - {+1, 0, 29},// I/O36 + {+1, 0, 1}, // I/O19 + {+1, 0, 2}, // I/O20 + {+1, 0, 5}, // I/O21 + {+1, 0, 6}, // I/O22 + {+1, 0, 7}, // I/O23 + {+1, 0, 9}, // I/O24 + {+1, 0, 10}, // I/O25 + {+1, 0, 13}, // I/O26 + {+1, 0, 14}, // I/O27 + {+1, 0, 15}, // I/O28 + {+1, 0, 16}, // I/O29 + {+1, 0, 17}, // I/O30 + {+1, 0, 18}, // I/O31 + {+1, 0, 21}, // I/O32 + {+1, 0, 24}, // I/O33 + {+1, 0, 25}, // I/O34 + {+1, 0, 26}, // I/O35 + {+1, 0, 29}, // I/O36 - {-1, 0, 4},// RA1 - {-1, 0, 12},// RA2 - {-1, 0, 20},// RA3 - {-1, 0, 27},// RA4 - {-1, 0, 31},// RA5 + {-1, 0, 4}, // RA1 + {-1, 0, 12}, // RA2 + {-1, 0, 20}, // RA3 + {-1, 0, 27}, // RA4 + {-1, 0, 31}, // RA5 - {+1, 0, 4},// RA6 - {+1, 0, 12},// RA7 - {+1, 0, 20},// RA8 - {+1, 0, 27},// RA9 - {+1, 0, 31},// RA10 + {+1, 0, 4}, // RA6 + {+1, 0, 12}, // RA7 + {+1, 0, 20}, // RA8 + {+1, 0, 27}, // RA9 + {+1, 0, 31}, // RA10 - {-1, 0, 3},// WA1 - {-1, 0, 11},// WA2 - {-1, 0, 19},// WA3 - {-1, 0, 23},// WA4 - {-1, 0, 28},// WA5 - - {+1, 0, 3},// WA6 + {-1, 0, 3}, // WA1 + {-1, 0, 11}, // WA2 + {-1, 0, 19}, // WA3 + {-1, 0, 23}, // WA4 + {-1, 0, 28}, // WA5 - {-1, 0, 0},// WE - {-1, 0, 8},// WEA + {+1, 0, 3}, // WA6 + + {-1, 0, 0}, // WE + {-1, 0, 8}, // WEA }; -const Loc ng_ultra_place_cdc1[] = -{ - {+1, 0, 1}, // AI1 - {+1, 0, 2}, // AI2 - {+1, 0, 9}, // AI3 - {+1, 0, 17},// AI4 - {+1, 0, 18},// AI5 - {+1, 0, 25},// AI6 +const Loc ng_ultra_place_cdc1[] = { + {+1, 0, 1}, // AI1 + {+1, 0, 2}, // AI2 + {+1, 0, 9}, // AI3 + {+1, 0, 17}, // AI4 + {+1, 0, 18}, // AI5 + {+1, 0, 25}, // AI6 - {+1, 0, 3}, // BI1 - {+1, 0, 10},// BI2 - {+1, 0, 11},// BI3 - {+1, 0, 19},// BI4 - {+1, 0, 26},// BI5 - {+1, 0, 27},// BI6 - - { 0, 0, 22},// ASRSTI - { 0, 0, 30},// ADRSTI - {+1, 0, 24},// BSRSTI - {+1, 0, 8}, // BDRSTI + {+1, 0, 3}, // BI1 + {+1, 0, 10}, // BI2 + {+1, 0, 11}, // BI3 + {+1, 0, 19}, // BI4 + {+1, 0, 26}, // BI5 + {+1, 0, 27}, // BI6 + + {0, 0, 22}, // ASRSTI + {0, 0, 30}, // ADRSTI + {+1, 0, 24}, // BSRSTI + {+1, 0, 8}, // BDRSTI }; -const Loc ng_ultra_place_cdc2[] = -{ - {-1, 0, 4}, // AI1 - {-1, 0, 5}, // AI2 - {-1, 0, 12},// AI3 - {-1, 0, 20},// AI4 - {-1, 0, 21},// AI5 - {-1, 0, 28},// AI6 +const Loc ng_ultra_place_cdc2[] = { + {-1, 0, 4}, // AI1 + {-1, 0, 5}, // AI2 + {-1, 0, 12}, // AI3 + {-1, 0, 20}, // AI4 + {-1, 0, 21}, // AI5 + {-1, 0, 28}, // AI6 - {-1, 0, 6}, // BI1 - {-1, 0, 13},// BI2 - {-1, 0, 14},// BI3 - {-1, 0, 22},// BI4 - {-1, 0, 29},// BI5 - {-1, 0, 30},// BI6 + {-1, 0, 6}, // BI1 + {-1, 0, 13}, // BI2 + {-1, 0, 14}, // BI3 + {-1, 0, 22}, // BI4 + {-1, 0, 29}, // BI5 + {-1, 0, 30}, // BI6 - { 0, 0, 22},// ASRSTI - { 0, 0, 30},// ADRSTI - {-1, 0, 23},// BSRSTI - {-1, 0, 7}, // BDRSTI + {0, 0, 22}, // ASRSTI + {0, 0, 30}, // ADRSTI + {-1, 0, 23}, // BSRSTI + {-1, 0, 7}, // BDRSTI }; -const Loc ng_ultra_place_xcdc[] = -{ - { 0, 0, 1}, // AI1 - { 0, 0, 2}, // AI2 - { 0, 0, 9}, // AI3 - { 0, 0, 17},// AI4 - { 0, 0, 18},// AI5 - { 0, 0, 25},// AI6 +const Loc ng_ultra_place_xcdc[] = { + {0, 0, 1}, // AI1 + {0, 0, 2}, // AI2 + {0, 0, 9}, // AI3 + {0, 0, 17}, // AI4 + {0, 0, 18}, // AI5 + {0, 0, 25}, // AI6 - { 0, 0, 4}, // BI1 - { 0, 0, 5}, // BI2 - { 0, 0, 12},// BI3 - { 0, 0, 20},// BI4 - { 0, 0, 21},// BI5 - { 0, 0, 28},// BI6 + {0, 0, 4}, // BI1 + {0, 0, 5}, // BI2 + {0, 0, 12}, // BI3 + {0, 0, 20}, // BI4 + {0, 0, 21}, // BI5 + {0, 0, 28}, // BI6 - {-1, 0, 22},// ASRSTI - {-1, 0, 30},// ADRSTI - {+1, 0, 22},// BSRSTI - {+1, 0, 30},// BDRSTI - - { 0, 0, 3}, // CI1 - { 0, 0, 10},// CI2 - { 0, 0, 11},// CI3 - { 0, 0, 19},// CI4 - { 0, 0, 26},// CI5 - { 0, 0, 27},// CI6 + {-1, 0, 22}, // ASRSTI + {-1, 0, 30}, // ADRSTI + {+1, 0, 22}, // BSRSTI + {+1, 0, 30}, // BDRSTI - { 0, 0, 6}, // DI1 - { 0, 0, 13},// DI2 - { 0, 0, 14},// DI3 - { 0, 0, 22},// DI4 - { 0, 0, 29},// DI5 - { 0, 0, 30},// DI6 + {0, 0, 3}, // CI1 + {0, 0, 10}, // CI2 + {0, 0, 11}, // CI3 + {0, 0, 19}, // CI4 + {0, 0, 26}, // CI5 + {0, 0, 27}, // CI6 - { 0, 0, 24},// CSRSTI - { 0, 0, 8}, // CDRSTI - { 0, 0, 23},// DSRSTI - { 0, 0, 7}, // DDRSTI + {0, 0, 6}, // DI1 + {0, 0, 13}, // DI2 + {0, 0, 14}, // DI3 + {0, 0, 22}, // DI4 + {0, 0, 29}, // DI5 + {0, 0, 30}, // DI6 + + {0, 0, 24}, // CSRSTI + {0, 0, 8}, // CDRSTI + {0, 0, 23}, // DSRSTI + {0, 0, 7}, // DDRSTI }; -const Loc ng_ultra_place_fifo1[] = -{ - {-1, 0, 1}, // I/O1 - {-1, 0, 2}, // I/O2 - {-1, 0, 5}, // I/O3 - {-1, 0, 6}, // I/O4 - {-1, 0, 7}, // I/O5 - {-1, 0, 9}, // I/O6 - {-1, 0, 10},// I/O7 - {-1, 0, 13},// I/O8 - {-1, 0, 14},// I/O9 - {-1, 0, 15},// I/O10 - {-1, 0, 16},// I/O11 - {-1, 0, 17},// I/O12 - {-1, 0, 18},// I/O13 - {-1, 0, 21},// I/O14 - {-1, 0, 24},// I/O15 - {-1, 0, 25},// I/O16 - {-1, 0, 26},// I/O17 - {-1, 0, 29},// I/O18 +const Loc ng_ultra_place_fifo1[] = { + {-1, 0, 1}, // I/O1 + {-1, 0, 2}, // I/O2 + {-1, 0, 5}, // I/O3 + {-1, 0, 6}, // I/O4 + {-1, 0, 7}, // I/O5 + {-1, 0, 9}, // I/O6 + {-1, 0, 10}, // I/O7 + {-1, 0, 13}, // I/O8 + {-1, 0, 14}, // I/O9 + {-1, 0, 15}, // I/O10 + {-1, 0, 16}, // I/O11 + {-1, 0, 17}, // I/O12 + {-1, 0, 18}, // I/O13 + {-1, 0, 21}, // I/O14 + {-1, 0, 24}, // I/O15 + {-1, 0, 25}, // I/O16 + {-1, 0, 26}, // I/O17 + {-1, 0, 29}, // I/O18 - { 0, 0, 0},// I/O19 - { 0, 0, 0},// I/O20 - { 0, 0, 0},// I/O21 - { 0, 0, 0},// I/O22 - { 0, 0, 0},// I/O23 - { 0, 0, 0},// I/O24 - { 0, 0, 0},// I/O25 - { 0, 0, 0},// I/O26 - { 0, 0, 0},// I/O27 - { 0, 0, 0},// I/O28 - { 0, 0, 0},// I/O29 - { 0, 0, 0},// I/O30 - { 0, 0, 0},// I/O31 - { 0, 0, 0},// I/O32 - { 0, 0, 0},// I/O33 - { 0, 0, 0},// I/O34 - { 0, 0, 0},// I/O35 - { 0, 0, 0},// I/O36 + {0, 0, 0}, // I/O19 + {0, 0, 0}, // I/O20 + {0, 0, 0}, // I/O21 + {0, 0, 0}, // I/O22 + {0, 0, 0}, // I/O23 + {0, 0, 0}, // I/O24 + {0, 0, 0}, // I/O25 + {0, 0, 0}, // I/O26 + {0, 0, 0}, // I/O27 + {0, 0, 0}, // I/O28 + {0, 0, 0}, // I/O29 + {0, 0, 0}, // I/O30 + {0, 0, 0}, // I/O31 + {0, 0, 0}, // I/O32 + {0, 0, 0}, // I/O33 + {0, 0, 0}, // I/O34 + {0, 0, 0}, // I/O35 + {0, 0, 0}, // I/O36 - { 0, 0, 3}, // RAI1/RAO1 - { 0, 0, 10},// RAI2/RAO2 - { 0, 0, 11},// RAI3/RAO3 - { 0, 0, 19},// RAI4/RAO4 - { 0, 0, 26},// RAI5/RAO5 - { 0, 0, 27},// RAI6/RAO6 - { 0, 0, 0},// RAI7/RAO7 + {0, 0, 3}, // RAI1/RAO1 + {0, 0, 10}, // RAI2/RAO2 + {0, 0, 11}, // RAI3/RAO3 + {0, 0, 19}, // RAI4/RAO4 + {0, 0, 26}, // RAI5/RAO5 + {0, 0, 27}, // RAI6/RAO6 + {0, 0, 0}, // RAI7/RAO7 - { 0, 0, 1}, // WAI1/WAO1 - { 0, 0, 2}, // WAI2/WAO2 - { 0, 0, 9}, // WAI3/WAO3 - { 0, 0, 17},// WAI4/WAO4 - { 0, 0, 18},// WAI5/WAO5 - { 0, 0, 25},// WAI6/WAO6 - { 0, 0, 0},// WAI7/WAO7 + {0, 0, 1}, // WAI1/WAO1 + {0, 0, 2}, // WAI2/WAO2 + {0, 0, 9}, // WAI3/WAO3 + {0, 0, 17}, // WAI4/WAO4 + {0, 0, 18}, // WAI5/WAO5 + {0, 0, 25}, // WAI6/WAO6 + {0, 0, 0}, // WAI7/WAO7 - {-1, 0, 0}, // WE - {-1, 0, 8}, // WEA + {-1, 0, 0}, // WE + {-1, 0, 8}, // WEA - {-1, 0, 22},// WRSTI1/WRSTO - {-1, 0, 30},// RRSTI1/RRSTO - { 0, 0, 8}, // WRSTI2 - { 0, 0, 24},// RRSTI2 - { 0, 0, 0}, // WRSTI3/WRSTO - { 0, 0, 0}, // RRSTI3/RRSTO - { 0, 0, 0}, // WRSTI4 - { 0, 0, 0}, // RRSTI4 + {-1, 0, 22}, // WRSTI1/WRSTO + {-1, 0, 30}, // RRSTI1/RRSTO + {0, 0, 8}, // WRSTI2 + {0, 0, 24}, // RRSTI2 + {0, 0, 0}, // WRSTI3/WRSTO + {0, 0, 0}, // RRSTI3/RRSTO + {0, 0, 0}, // WRSTI4 + {0, 0, 0}, // RRSTI4 - {-1, 0, 3}, // WEQ - {-1, 0, 4}, // REQ - // {-1, 0, 11}, WEQ - // {-1, 0, 12}, REQ - // {-1, 0, 19}, WEQ - // {-1, 0, 20}, REQ - // {-1, 0, 27}, WEQ - // {-1, 0, 28}, REQ - { 0, 0, 0}, // WEQ2 - { 0, 0, 0}, // REQ2 + {-1, 0, 3}, // WEQ + {-1, 0, 4}, // REQ + // {-1, 0, 11}, WEQ + // {-1, 0, 12}, REQ + // {-1, 0, 19}, WEQ + // {-1, 0, 20}, REQ + // {-1, 0, 27}, WEQ + // {-1, 0, 28}, REQ + {0, 0, 0}, // WEQ2 + {0, 0, 0}, // REQ2 }; -const Loc ng_ultra_place_fifo2[] = -{ - {+1, 0, 1}, // I/O1 - {+1, 0, 2}, // I/O2 - {+1, 0, 5}, // I/O3 - {+1, 0, 6}, // I/O4 - {+1, 0, 7}, // I/O5 - {+1, 0, 9}, // I/O6 - {+1, 0, 10},// I/O7 - {+1, 0, 13},// I/O8 - {+1, 0, 14},// I/O9 - {+1, 0, 15},// I/O10 - {+1, 0, 16},// I/O11 - {+1, 0, 17},// I/O12 - {+1, 0, 18},// I/O13 - {+1, 0, 21},// I/O14 - {+1, 0, 24},// I/O15 - {+1, 0, 25},// I/O16 - {+1, 0, 26},// I/O17 - {+1, 0, 29},// I/O18 +const Loc ng_ultra_place_fifo2[] = { + {+1, 0, 1}, // I/O1 + {+1, 0, 2}, // I/O2 + {+1, 0, 5}, // I/O3 + {+1, 0, 6}, // I/O4 + {+1, 0, 7}, // I/O5 + {+1, 0, 9}, // I/O6 + {+1, 0, 10}, // I/O7 + {+1, 0, 13}, // I/O8 + {+1, 0, 14}, // I/O9 + {+1, 0, 15}, // I/O10 + {+1, 0, 16}, // I/O11 + {+1, 0, 17}, // I/O12 + {+1, 0, 18}, // I/O13 + {+1, 0, 21}, // I/O14 + {+1, 0, 24}, // I/O15 + {+1, 0, 25}, // I/O16 + {+1, 0, 26}, // I/O17 + {+1, 0, 29}, // I/O18 - { 0, 0, 0},// I/O19 - { 0, 0, 0},// I/O20 - { 0, 0, 0},// I/O21 - { 0, 0, 0},// I/O22 - { 0, 0, 0},// I/O23 - { 0, 0, 0},// I/O24 - { 0, 0, 0},// I/O25 - { 0, 0, 0},// I/O26 - { 0, 0, 0},// I/O27 - { 0, 0, 0},// I/O28 - { 0, 0, 0},// I/O29 - { 0, 0, 0},// I/O30 - { 0, 0, 0},// I/O31 - { 0, 0, 0},// I/O32 - { 0, 0, 0},// I/O33 - { 0, 0, 0},// I/O34 - { 0, 0, 0},// I/O35 - { 0, 0, 0},// I/O36 + {0, 0, 0}, // I/O19 + {0, 0, 0}, // I/O20 + {0, 0, 0}, // I/O21 + {0, 0, 0}, // I/O22 + {0, 0, 0}, // I/O23 + {0, 0, 0}, // I/O24 + {0, 0, 0}, // I/O25 + {0, 0, 0}, // I/O26 + {0, 0, 0}, // I/O27 + {0, 0, 0}, // I/O28 + {0, 0, 0}, // I/O29 + {0, 0, 0}, // I/O30 + {0, 0, 0}, // I/O31 + {0, 0, 0}, // I/O32 + {0, 0, 0}, // I/O33 + {0, 0, 0}, // I/O34 + {0, 0, 0}, // I/O35 + {0, 0, 0}, // I/O36 - { 0, 0, 6}, // RAI1/RAO1 - { 0, 0, 13},// RAI2/RAO2 - { 0, 0, 14},// RAI3/RAO3 - { 0, 0, 22},// RAI4/RAO4 - { 0, 0, 29},// RAI5/RAO5 - { 0, 0, 30},// RAI6/RAO6 - { 0, 0, 0},// RAI7/RAO7 + {0, 0, 6}, // RAI1/RAO1 + {0, 0, 13}, // RAI2/RAO2 + {0, 0, 14}, // RAI3/RAO3 + {0, 0, 22}, // RAI4/RAO4 + {0, 0, 29}, // RAI5/RAO5 + {0, 0, 30}, // RAI6/RAO6 + {0, 0, 0}, // RAI7/RAO7 - { 0, 0, 4}, // WAI1/WAO1 - { 0, 0, 5}, // WAI2/WAO2 - { 0, 0, 12},// WAI3/WAO3 - { 0, 0, 20},// WAI4/WAO4 - { 0, 0, 21},// WAI5/WAO5 - { 0, 0, 28},// WAI6/WAO6 - { 0, 0, 0},// WAI7/WAO7 + {0, 0, 4}, // WAI1/WAO1 + {0, 0, 5}, // WAI2/WAO2 + {0, 0, 12}, // WAI3/WAO3 + {0, 0, 20}, // WAI4/WAO4 + {0, 0, 21}, // WAI5/WAO5 + {0, 0, 28}, // WAI6/WAO6 + {0, 0, 0}, // WAI7/WAO7 - {+1, 0, 0}, // WE - {+1, 0, 8}, // WEA + {+1, 0, 0}, // WE + {+1, 0, 8}, // WEA - {+1, 0, 22},// WRSTI1/WRSTO - {+1, 0, 30},// RRSTI1/RRSTO - { 0, 0, 7}, // WRSTI2 - { 0, 0, 23},// RRSTI2 - { 0, 0, 0}, // WRSTI3/WRSTO - { 0, 0, 0}, // RRSTI3/RRSTO - { 0, 0, 0}, // WRSTI4 - { 0, 0, 0}, // RRSTI4 + {+1, 0, 22}, // WRSTI1/WRSTO + {+1, 0, 30}, // RRSTI1/RRSTO + {0, 0, 7}, // WRSTI2 + {0, 0, 23}, // RRSTI2 + {0, 0, 0}, // WRSTI3/WRSTO + {0, 0, 0}, // RRSTI3/RRSTO + {0, 0, 0}, // WRSTI4 + {0, 0, 0}, // RRSTI4 - {+1, 0, 3}, // WEQ - {+1, 0, 4}, // REQ - // {+1, 0, 11}, WEQ - // {+1, 0, 12}, REQ - // {+1, 0, 19}, WEQ - // {+1, 0, 20}, REQ - // {+1, 0, 27}, WEQ - // {+1, 0, 28}, REQ - { 0, 0, 0}, // WEQ2 - { 0, 0, 0}, // REQ2 + {+1, 0, 3}, // WEQ + {+1, 0, 4}, // REQ + // {+1, 0, 11}, WEQ + // {+1, 0, 12}, REQ + // {+1, 0, 19}, WEQ + // {+1, 0, 20}, REQ + // {+1, 0, 27}, WEQ + // {+1, 0, 28}, REQ + {0, 0, 0}, // WEQ2 + {0, 0, 0}, // REQ2 }; -const Loc ng_ultra_place_xfifo[] = -{ - {-1, 0, 1}, // I/O1 - {-1, 0, 2}, // I/O2 - {-1, 0, 5}, // I/O3 - {-1, 0, 6}, // I/O4 - {-1, 0, 7}, // I/O5 - {-1, 0, 9}, // I/O6 - {-1, 0, 10},// I/O7 - {-1, 0, 13},// I/O8 - {-1, 0, 14},// I/O9 - {-1, 0, 15},// I/O10 - {-1, 0, 16},// I/O11 - {-1, 0, 17},// I/O12 - {-1, 0, 18},// I/O13 - {-1, 0, 21},// I/O14 - {-1, 0, 24},// I/O15 - {-1, 0, 25},// I/O16 - {-1, 0, 26},// I/O17 - {-1, 0, 29},// I/O18 - {+1, 0, 1}, // I/O19 - {+1, 0, 2}, // I/O20 - {+1, 0, 5}, // I/O21 - {+1, 0, 6}, // I/O22 - {+1, 0, 7}, // I/O23 - {+1, 0, 9}, // I/O24 - {+1, 0, 10},// I/O25 - {+1, 0, 13},// I/O26 - {+1, 0, 14},// I/O27 - {+1, 0, 15},// I/O28 - {+1, 0, 16},// I/O29 - {+1, 0, 17},// I/O30 - {+1, 0, 18},// I/O31 - {+1, 0, 21},// I/O32 - {+1, 0, 24},// I/O33 - {+1, 0, 25},// I/O34 - {+1, 0, 26},// I/O35 - {+1, 0, 29},// I/O36 +const Loc ng_ultra_place_xfifo[] = { + {-1, 0, 1}, // I/O1 + {-1, 0, 2}, // I/O2 + {-1, 0, 5}, // I/O3 + {-1, 0, 6}, // I/O4 + {-1, 0, 7}, // I/O5 + {-1, 0, 9}, // I/O6 + {-1, 0, 10}, // I/O7 + {-1, 0, 13}, // I/O8 + {-1, 0, 14}, // I/O9 + {-1, 0, 15}, // I/O10 + {-1, 0, 16}, // I/O11 + {-1, 0, 17}, // I/O12 + {-1, 0, 18}, // I/O13 + {-1, 0, 21}, // I/O14 + {-1, 0, 24}, // I/O15 + {-1, 0, 25}, // I/O16 + {-1, 0, 26}, // I/O17 + {-1, 0, 29}, // I/O18 + {+1, 0, 1}, // I/O19 + {+1, 0, 2}, // I/O20 + {+1, 0, 5}, // I/O21 + {+1, 0, 6}, // I/O22 + {+1, 0, 7}, // I/O23 + {+1, 0, 9}, // I/O24 + {+1, 0, 10}, // I/O25 + {+1, 0, 13}, // I/O26 + {+1, 0, 14}, // I/O27 + {+1, 0, 15}, // I/O28 + {+1, 0, 16}, // I/O29 + {+1, 0, 17}, // I/O30 + {+1, 0, 18}, // I/O31 + {+1, 0, 21}, // I/O32 + {+1, 0, 24}, // I/O33 + {+1, 0, 25}, // I/O34 + {+1, 0, 26}, // I/O35 + {+1, 0, 29}, // I/O36 - { 0, 0, 3}, // RAI1/RAO1 - { 0, 0, 10},// RAI2/RAO2 - { 0, 0, 11},// RAI3/RAO3 - { 0, 0, 19},// RAI4/RAO4 - { 0, 0, 26},// RAI5/RAO5 - { 0, 0, 27},// RAI6/RAO6 - { 0, 0, 6}, // RAI7/RAO7 + {0, 0, 3}, // RAI1/RAO1 + {0, 0, 10}, // RAI2/RAO2 + {0, 0, 11}, // RAI3/RAO3 + {0, 0, 19}, // RAI4/RAO4 + {0, 0, 26}, // RAI5/RAO5 + {0, 0, 27}, // RAI6/RAO6 + {0, 0, 6}, // RAI7/RAO7 - { 0, 0, 1}, // WAI1/WAO1 - { 0, 0, 2}, // WAI2/WAO2 - { 0, 0, 9}, // WAI3/WAO3 - { 0, 0, 17},// WAI4/WAO4 - { 0, 0, 18},// WAI5/WAO5 - { 0, 0, 25},// WAI6/WAO6 - { 0, 0, 4}, // WAI7/WAO7 + {0, 0, 1}, // WAI1/WAO1 + {0, 0, 2}, // WAI2/WAO2 + {0, 0, 9}, // WAI3/WAO3 + {0, 0, 17}, // WAI4/WAO4 + {0, 0, 18}, // WAI5/WAO5 + {0, 0, 25}, // WAI6/WAO6 + {0, 0, 4}, // WAI7/WAO7 - {-1, 0, 0}, // WE - {-1, 0, 8}, // WEA + {-1, 0, 0}, // WE + {-1, 0, 8}, // WEA - {-1, 0, 22},// WRSTI1/WRSTO - {-1, 0, 30},// RRSTI1/RRSTO - { 0, 0, 8}, // WRSTI2 - { 0, 0, 24},// RRSTI2 - {+1, 0, 22},// WRSTI3/WRSTO - {+1, 0, 30},// RRSTI3/RRSTO - { 0, 0, 7}, // WRSTI4 - { 0, 0, 23},// RRSTI4 + {-1, 0, 22}, // WRSTI1/WRSTO + {-1, 0, 30}, // RRSTI1/RRSTO + {0, 0, 8}, // WRSTI2 + {0, 0, 24}, // RRSTI2 + {+1, 0, 22}, // WRSTI3/WRSTO + {+1, 0, 30}, // RRSTI3/RRSTO + {0, 0, 7}, // WRSTI4 + {0, 0, 23}, // RRSTI4 - {-1, 0, 3}, // WEQ1 - {-1, 0, 4}, // REQ1 - // {-1, 0, 11}, WEQ1 - // {-1, 0, 12}, REQ1 - // {-1, 0, 19}, WEQ1 - // {-1, 0, 20}, REQ1 - // {-1, 0, 27}, WEQ1 - // {-1, 0, 28}, REQ1 - {+1, 0, 3}, // WEQ2 - {+1, 0, 4}, // REQ2 - // {+1, 0, 11}, WEQ2 - // {+1, 0, 12}, REQ2 - // {+1, 0, 19}, WEQ2 - // {+1, 0, 20}, REQ2 - // {+1, 0, 27}, WEQ2 - // {+1, 0, 28}, REQ2 + {-1, 0, 3}, // WEQ1 + {-1, 0, 4}, // REQ1 + // {-1, 0, 11}, WEQ1 + // {-1, 0, 12}, REQ1 + // {-1, 0, 19}, WEQ1 + // {-1, 0, 20}, REQ1 + // {-1, 0, 27}, WEQ1 + // {-1, 0, 28}, REQ1 + {+1, 0, 3}, // WEQ2 + {+1, 0, 4}, // REQ2 + // {+1, 0, 11}, WEQ2 + // {+1, 0, 12}, REQ2 + // {+1, 0, 19}, WEQ2 + // {+1, 0, 20}, REQ2 + // {+1, 0, 27}, WEQ2 + // {+1, 0, 28}, REQ2 }; -}; +}; // namespace namespace ng_ultra { Loc getNextLocInDSPChain(const NgUltraImpl *impl, Loc loc) { BelId bel = impl->ctx->getBelByLocation(loc); - if (impl->dsp_cascade.count(bel)==0) { + if (impl->dsp_cascade.count(bel) == 0) { loc.z = -1; // End of chain return loc; } @@ -495,16 +488,17 @@ Loc getNextLocInDFFChain(Loc loc) result.z = 0; result.x++; return result; - } + } int z = loc.z + 8; - if (z>31) z++; + if (z > 31) + z++; result.z = z % 32; // BEL_LUT_Z is 0 return result; } Loc getCYFE(Loc root, int pos) { - int p[] = { 2-1, 25-1, 10-1, 17-1 }; + int p[] = {2 - 1, 25 - 1, 10 - 1, 17 - 1}; int cy = root.z - BEL_CY_Z; Loc result; result.x = root.x; @@ -528,7 +522,7 @@ Loc getXRFFE(Loc root, int pos) if (root.z == BEL_XRF_Z) { // XRF1 result.x += root.x; - } else { + } else { // RF1 or RF2 result.x = root.x + ((root.z == BEL_RF_Z) ? -1 : +1); } @@ -541,7 +535,7 @@ Loc getCDCFE(Loc root, int pos) Loc result; if (root.z == BEL_CDC_Z) { result = ng_ultra_place_cdc1[pos]; - } else if (root.z == BEL_CDC_Z+1) { + } else if (root.z == BEL_CDC_Z + 1) { result = ng_ultra_place_cdc2[pos]; } else if (root.z == BEL_XCDC_Z) { result = ng_ultra_place_xcdc[pos]; @@ -558,7 +552,7 @@ Loc getFIFOFE(Loc root, int pos) Loc result; if (root.z == BEL_FIFO_Z) { result = ng_ultra_place_fifo1[pos]; - } else if (root.z == BEL_FIFO_Z+1) { + } else if (root.z == BEL_FIFO_Z + 1) { result = ng_ultra_place_fifo2[pos]; } else if (root.z == BEL_XFIFO_Z) { result = ng_ultra_place_xfifo[pos]; @@ -570,5 +564,5 @@ Loc getFIFOFE(Loc root, int pos) return result; } -}; +}; // namespace ng_ultra NEXTPNR_NAMESPACE_END diff --git a/himbaechel/uarch/ng-ultra/location_map.h b/himbaechel/uarch/ng-ultra/location_map.h index 858f2368..f856e729 100644 --- a/himbaechel/uarch/ng-ultra/location_map.h +++ b/himbaechel/uarch/ng-ultra/location_map.h @@ -37,7 +37,7 @@ Loc getXRFFE(Loc root, int pos); Loc getCDCFE(Loc root, int pos); Loc getFIFOFE(Loc root, int pos); -}; +}; // namespace ng_ultra NEXTPNR_NAMESPACE_END #endif diff --git a/himbaechel/uarch/ng-ultra/ng_ultra.cc b/himbaechel/uarch/ng-ultra/ng_ultra.cc index 2d10c4e6..f5932e71 100644 --- a/himbaechel/uarch/ng-ultra/ng_ultra.cc +++ b/himbaechel/uarch/ng-ultra/ng_ultra.cc @@ -21,18 +21,18 @@ #include #include -#include "himbaechel_api.h" #include "design_utils.h" +#include "extra_data.h" +#include "himbaechel_api.h" #include "log.h" #include "nextpnr.h" -#include "util.h" -#include "extra_data.h" #include "placer_heap.h" +#include "util.h" #include "himbaechel_helpers.h" -#include "ng_ultra.h" #include "location_map.h" +#include "ng_ultra.h" #define GEN_INIT_CONSTIDS #define HIMBAECHEL_CONSTIDS "uarch/ng-ultra/constids.inc" @@ -41,7 +41,7 @@ using namespace NEXTPNR_NAMESPACE_PREFIX ng_ultra; NEXTPNR_NAMESPACE_BEGIN -NgUltraImpl::~NgUltraImpl(){}; +NgUltraImpl::~NgUltraImpl() {}; void NgUltraImpl::init_database(Arch *arch) { @@ -54,56 +54,56 @@ void NgUltraImpl::init_database(Arch *arch) void NgUltraImpl::init(Context *ctx) { HimbaechelAPI::init(ctx); - for (int i=1;i<=8;i++) - for (int j=0;j<20;j++) + for (int i = 1; i <= 8; i++) + for (int j = 0; j < 20; j++) gck_per_lobe[i].push_back(GckConfig(BelId())); for (auto bel : ctx->getBels()) { if (ctx->getBelType(bel) == id_IOM) { std::set ckg; IdString bank = tile_name_id(bel.tile); - iom_bels.emplace(bank,bel); - WireId belpin = ctx->getBelPinWire(bel,id_CKO1); + iom_bels.emplace(bank, bel); + WireId belpin = ctx->getBelPinWire(bel, id_CKO1); for (auto dh : ctx->getPipsDownhill(belpin)) { WireId pip_dst = ctx->getPipDstWire(dh); for (const auto &item : ctx->getWireBelPins(pip_dst)) { - if (boost::contains(ctx->nameOfBel(item.bel),"WFG_C")) { + if (boost::contains(ctx->nameOfBel(item.bel), "WFG_C")) { unused_wfg[item.bel] = tile_name_id(item.bel.tile); - } - else if (boost::contains(ctx->nameOfBel(item.bel),"PLL")) { + } else if (boost::contains(ctx->nameOfBel(item.bel), "PLL")) { ckg.emplace(tile_name_id(item.bel.tile)); unused_pll[item.bel] = tile_name_id(item.bel.tile); } } } - std::pair p; + std::pair p; p.first = *ckg.begin(); - if (ckg.size()==2) p.second = *(ckg.begin()++); + if (ckg.size() == 2) + p.second = *(ckg.begin()++); bank_to_ckg[bank] = p; } else if (ctx->getBelType(bel) == id_IOTP) { if (ctx->getBelName(bel)[1] == ctx->id("D08P_CLK.IOTP")) { - global_capable_bels.emplace(bel,id_P17RI); + global_capable_bels.emplace(bel, id_P17RI); } else if (ctx->getBelName(bel)[1] == ctx->id("D09P_CLK.IOTP")) { - global_capable_bels.emplace(bel,id_P19RI); + global_capable_bels.emplace(bel, id_P19RI); } } else if (ctx->getBelType(bel) == id_GCK) { std::string name = ctx->getBelName(bel)[1].c_str(ctx); - int lobe = std::stoi(name.substr(1,1)); - int num = std::stoi(name.substr(4,2).c_str()); - gck_per_lobe[lobe][num-1] = GckConfig(bel); + int lobe = std::stoi(name.substr(1, 1)); + int num = std::stoi(name.substr(4, 2).c_str()); + gck_per_lobe[lobe][num - 1] = GckConfig(bel); } - locations.emplace(stringf("%s:%s",tile_name(bel.tile).c_str(), ctx->getBelName(bel)[1].c_str(ctx)),bel); + locations.emplace(stringf("%s:%s", tile_name(bel.tile).c_str(), ctx->getBelName(bel)[1].c_str(ctx)), bel); Loc loc = ctx->getBelLocation(bel); - tile_locations.emplace(tile_name(bel.tile).c_str(),Loc(loc.x & 0xfffe, loc.y & 0xfffe, 0)); + tile_locations.emplace(tile_name(bel.tile).c_str(), Loc(loc.x & 0xfffe, loc.y & 0xfffe, 0)); } for (auto bel : ctx->getBels()) { if (ctx->getBelType(bel) == id_DSP) { - WireId cco = ctx->getBelPinWire(bel,id_CCO); + WireId cco = ctx->getBelPinWire(bel, id_CCO); WireId cci; for (auto dh : ctx->getPipsDownhill(cco)) { cci = ctx->getPipDstWire(dh); } - if (cci!=WireId()) { - std::string loc = stringf("%s:%s",tile_name(cci.tile).c_str(), ctx->getWireName(cci)[1].c_str(ctx)); + if (cci != WireId()) { + std::string loc = stringf("%s:%s", tile_name(cci.tile).c_str(), ctx->getWireName(cci)[1].c_str(ctx)); loc.erase(loc.find(".CCI")); BelId dsp_bel = locations[loc]; dsp_cascade.emplace(dsp_bel, bel); @@ -115,75 +115,72 @@ void NgUltraImpl::init(Context *ctx) namespace { // Note: These are per Cell type not Bel type // Sinks -const dict> fabric_lowskew_sinks = { - // TILE - DFF - { id_BEYOND_FE, { id_CK, id_L, id_R }}, - // { id_DFF, { id_CK }}, // This is part of BEYOND_FE - // TILE - Register file - { id_RF, { id_WCK }}, - { id_RFSP, { id_WCK }}, - { id_XHRF, { id_WCK1, id_WCK2 }}, - { id_XWRF, { id_WCK1, id_WCK2 }}, - { id_XPRF, { id_WCK1, id_WCK2 }}, - // TILE - CDC - { id_CDC, { id_CK1, id_CK2 }}, - { id_DDE, { id_CK1, id_CK2 }}, - { id_TDE, { id_CK1, id_CK2 }}, - { id_XCDC, { id_CK1, id_CK2 }}, - // TILE - FIFO - { id_FIFO, { id_RCK, id_WCK }}, - { id_XHFIFO, { id_RCK1, id_RCK2, id_WCK1, id_WCK2 }}, - { id_XWFIFO, { id_RCK1, id_RCK2, id_WCK1, id_WCK2 }}, - // CGB - RAM - { id_RAM, { id_ACK, id_BCK }}, - // CGB - DSP - { id_DSP, {id_CK }}, +const dict> fabric_lowskew_sinks = { + // TILE - DFF + {id_BEYOND_FE, {id_CK, id_L, id_R}}, + // { id_DFF, { id_CK }}, // This is part of BEYOND_FE + // TILE - Register file + {id_RF, {id_WCK}}, + {id_RFSP, {id_WCK}}, + {id_XHRF, {id_WCK1, id_WCK2}}, + {id_XWRF, {id_WCK1, id_WCK2}}, + {id_XPRF, {id_WCK1, id_WCK2}}, + // TILE - CDC + {id_CDC, {id_CK1, id_CK2}}, + {id_DDE, {id_CK1, id_CK2}}, + {id_TDE, {id_CK1, id_CK2}}, + {id_XCDC, {id_CK1, id_CK2}}, + // TILE - FIFO + {id_FIFO, {id_RCK, id_WCK}}, + {id_XHFIFO, {id_RCK1, id_RCK2, id_WCK1, id_WCK2}}, + {id_XWFIFO, {id_RCK1, id_RCK2, id_WCK1, id_WCK2}}, + // CGB - RAM + {id_RAM, {id_ACK, id_BCK}}, + // CGB - DSP + {id_DSP, {id_CK}}, }; -const dict> ring_clock_sinks = { - // CKG - { id_PLL, { id_CLK_CAL, id_FBK, id_REF }}, - { id_WFB, { id_ZI }}, - { id_WFG, { id_ZI }} +const dict> ring_clock_sinks = { + // CKG + {id_PLL, {id_CLK_CAL, id_FBK, id_REF}}, + {id_WFB, {id_ZI}}, + {id_WFG, {id_ZI}}}; + +const dict> ring_over_tile_clock_sinks = { + // IOB + {id_DFR, {id_CK}}, + {id_DDFR, {id_CK, id_CKF}}, +}; +// IOB +// { id_IOM, { id_ALCK1, id_ALCK2, id_ALCK3, id_CCK, id_FCK1, id_FCK2, id_FDCK, +// id_LDSCK1, id_LDSCK2, id_LDSCK3, id_SWRX1CK, id_SWRX2CK }}, + +// HSSL +// { id_CRX, { id_LINK }}, +// { id_CTX, { id_LINK }}, +// { id_PMA, { id_hssl_clock_i1, id_hssl_clock_i2, id_hssl_clock_i3, id_hssl_clock_i4 }, + +const dict> tube_clock_sinks = { + // TUBE + {id_GCK, {id_SI1, id_SI2}}, +}; +// Sources +// CKG +const dict> ring_clock_source = { + {id_IOM, {id_CKO1, id_CKO2}}, + {id_WFB, {id_ZO}}, + {id_WFG, {id_ZO}}, + {id_PLL, + {id_OSC, id_VCO, id_REFO, id_LDFO, id_CLK_DIV1, id_CLK_DIV2, id_CLK_DIV3, id_CLK_DIV4, id_CLK_DIVD1, + id_CLK_DIVD2, id_CLK_DIVD3, id_CLK_DIVD4, id_CLK_DIVD5, id_CLK_CAL_DIV}}}; +// TUBE +const dict> tube_clock_source = { + {id_GCK, {id_SO}}, }; -const dict> ring_over_tile_clock_sinks = { - // IOB - { id_DFR, { id_CK }}, - { id_DDFR, { id_CK, id_CKF }}, -}; - // IOB - // { id_IOM, { id_ALCK1, id_ALCK2, id_ALCK3, id_CCK, id_FCK1, id_FCK2, id_FDCK, - // id_LDSCK1, id_LDSCK2, id_LDSCK3, id_SWRX1CK, id_SWRX2CK }}, +}; // namespace - // HSSL - // { id_CRX, { id_LINK }}, - // { id_CTX, { id_LINK }}, - // { id_PMA, { id_hssl_clock_i1, id_hssl_clock_i2, id_hssl_clock_i3, id_hssl_clock_i4 }, - -const dict> tube_clock_sinks = { - // TUBE - { id_GCK, { id_SI1, id_SI2 }}, -}; - // Sources - // CKG -const dict> ring_clock_source = { - { id_IOM, { id_CKO1, id_CKO2 }}, - { id_WFB, { id_ZO }}, - { id_WFG, { id_ZO }}, - { id_PLL, { id_OSC, id_VCO, id_REFO, id_LDFO, - id_CLK_DIV1, id_CLK_DIV2, id_CLK_DIV3, id_CLK_DIV4, - id_CLK_DIVD1, id_CLK_DIVD2, id_CLK_DIVD3, id_CLK_DIVD4, id_CLK_DIVD5, - id_CLK_CAL_DIV }} -}; - // TUBE -const dict> tube_clock_source = { - { id_GCK, { id_SO }}, -}; - -}; - -const dict>& NgUltraImpl::get_fabric_lowskew_sinks() { return fabric_lowskew_sinks; } +const dict> &NgUltraImpl::get_fabric_lowskew_sinks() { return fabric_lowskew_sinks; } bool NgUltraImpl::is_fabric_lowskew_sink(const PortRef &ref) { @@ -197,7 +194,8 @@ bool NgUltraImpl::is_ring_clock_sink(const PortRef &ref) bool NgUltraImpl::is_ring_over_tile_clock_sink(const PortRef &ref) { - return ring_over_tile_clock_sinks.count(ref.cell->type) && ring_over_tile_clock_sinks.at(ref.cell->type).count(ref.port); + return ring_over_tile_clock_sinks.count(ref.cell->type) && + ring_over_tile_clock_sinks.at(ref.cell->type).count(ref.port); } bool NgUltraImpl::is_tube_clock_sink(const PortRef &ref) @@ -236,10 +234,7 @@ IdString NgUltraImpl::tile_name_id(int tile) const return IdString(data.name); } -std::string NgUltraImpl::tile_name(int tile) const -{ - return stringf("%s", tile_name_id(tile).c_str(ctx)); -} +std::string NgUltraImpl::tile_name(int tile) const { return stringf("%s", tile_name_id(tile).c_str(ctx)); } int NgUltraImpl::tile_lobe(int tile) const { @@ -264,7 +259,8 @@ bool NgUltraImpl::get_mux_data(WireId wire, uint8_t *value) if (!ctx->getBoundPipNet(pip)) continue; const auto &extra_data = *pip_extra_data(pip); - if (!extra_data.name) continue; + if (!extra_data.name) + continue; if (extra_data.type == PipExtra::PIP_EXTRA_MUX) { *value = extra_data.input; return true; @@ -286,7 +282,7 @@ bool NgUltraImpl::update_bff_to_csc(CellInfo *cell, BelId bel, PipId dst_pip) if (!ctx->getBoundPipNet(pip2)) continue; IdString dst = ctx->getWireName(ctx->getPipDstWire(pip2))[1]; - if (boost::ends_with(dst.c_str(ctx),".DS")) { + if (boost::ends_with(dst.c_str(ctx), ".DS")) { cell->setParam(id_type, Property("CSC")); return true; } @@ -309,7 +305,7 @@ bool NgUltraImpl::update_bff_to_scc(CellInfo *cell, BelId bel, PipId dst_pip) if (!ctx->getBoundPipNet(pip2)) continue; IdString dst = ctx->getWireName(ctx->getPipSrcWire(pip2))[1]; - if (boost::starts_with(dst.c_str(ctx),"SYSTEM.ST1")) { + if (boost::starts_with(dst.c_str(ctx), "SYSTEM.ST1")) { cell->setParam(id_type, Property("SCC")); return true; } @@ -330,44 +326,48 @@ void NgUltraImpl::postRoute() for (auto &w : ni->wires) { if (w.second.pip != PipId()) { const auto &extra_data = *pip_extra_data(w.second.pip); - if (!extra_data.name) continue; + if (!extra_data.name) + continue; if (extra_data.type == PipExtra::PIP_EXTRA_BYPASS) { IdStringList id = ctx->getPipName(w.second.pip); BelId bel = ctx->getBelByName(IdStringList::concat(id[0], IdString(extra_data.name))); IdString type = ctx->getBelType(bel); if (!ctx->getBoundBelCell(bel)) { CellInfo *cell = ctx->createCell(ctx->id(ctx->nameOfBel(bel)), type); - ctx->bindBel(bel,cell,PlaceStrength::STRENGTH_FIXED); - if (type==id_BEYOND_FE) fe_new++; + ctx->bindBel(bel, cell, PlaceStrength::STRENGTH_FIXED); + if (type == id_BEYOND_FE) + fe_new++; } CellInfo *cell = ctx->getBoundBelCell(bel); - switch(type.index) { - case id_BEYOND_FE.index : - if (extra_data.input==0) { - // set bypass mode for DFF - cell->setParam(id_type, Property("BFF")); - cell->params[id_dff_used] = Property(1,1); - // Note: no conflict, CSC and SCC modes are never available on same position - if (update_bff_to_csc(cell, bel, w.second.pip)) - csc_count++; - else if(update_bff_to_scc(cell, bel, w.second.pip)) - scc_count++; - else - bff_count++; - } else { - lut_bypass++; - cell->params[id_lut_used] = Property(1,1); - cell->params[id_lut_table] = Property(0xaaaa, 16); - } - break; - case id_WFG.index : wfg_bypass++; - cell->type = id_WFB; - break; - case id_GCK.index : gck_bypass++; - cell->setParam(id_std_mode, extra_data.input == 0 ? Property("BYPASS") : Property("CSC")); - break; - default: - log_error("Unmaped bel type '%s' for routing\n",type.c_str(ctx)); + switch (type.index) { + case id_BEYOND_FE.index: + if (extra_data.input == 0) { + // set bypass mode for DFF + cell->setParam(id_type, Property("BFF")); + cell->params[id_dff_used] = Property(1, 1); + // Note: no conflict, CSC and SCC modes are never available on same position + if (update_bff_to_csc(cell, bel, w.second.pip)) + csc_count++; + else if (update_bff_to_scc(cell, bel, w.second.pip)) + scc_count++; + else + bff_count++; + } else { + lut_bypass++; + cell->params[id_lut_used] = Property(1, 1); + cell->params[id_lut_table] = Property(0xaaaa, 16); + } + break; + case id_WFG.index: + wfg_bypass++; + cell->type = id_WFB; + break; + case id_GCK.index: + gck_bypass++; + cell->setParam(id_std_mode, extra_data.input == 0 ? Property("BYPASS") : Property("CSC")); + break; + default: + log_error("Unmaped bel type '%s' for routing\n", type.c_str(ctx)); } } } @@ -377,9 +377,9 @@ void NgUltraImpl::postRoute() log_info(" %6d DFFs used as BFF\n", bff_count); if (csc_count) log_info(" %6d DFFs used as CSC\n", csc_count); - if (scc_count) + if (scc_count) log_info(" %6d DFFs used as SCC\n", scc_count); - if(lut_bypass) + if (lut_bypass) log_info(" %6d LUTs used in bypass mode\n", lut_bypass); if (fe_new) log_info(" %6d newly allocated FEs\n", fe_new); @@ -402,7 +402,8 @@ void NgUltraImpl::postRoute() if (!ctx->getBoundPipNet(pip)) continue; const auto &extra_data = *pip_extra_data(pip); - if (!extra_data.name) continue; + if (!extra_data.name) + continue; if (extra_data.type == PipExtra::PIP_EXTRA_LUT_PERMUTATION) { NPNR_ASSERT(extra_data.output == i); phys_to_log[extra_data.input].push_back(i); @@ -443,7 +444,7 @@ void NgUltraImpl::configurePlacerHeap(PlacerHeapCfg &cfg) namespace { -template bool check_assign_sig(std::array &sig_set, const NetInfo *sig) +template bool check_assign_sig(std::array &sig_set, const NetInfo *sig) { if (sig == nullptr) return true; @@ -459,16 +460,16 @@ template bool check_assign_sig(std::array &sig_set struct SectionFEWorker { - std::array clk{}; // from local system matrix - std::array reset{}; // from local system matrix - std::array load{}; // from local system matrix + std::array clk{}; // from local system matrix + std::array reset{}; // from local system matrix + std::array load{}; // from local system matrix std::array shared{}; // 1 from local system matrix // Additional R and L can be used from RI network - bool run(const NgUltraImpl *impl,const Context *ctx, BelId bel, CellInfo *cell) + bool run(const NgUltraImpl *impl, const Context *ctx, BelId bel, CellInfo *cell) { Loc loc = ctx->getBelLocation(bel); for (uint8_t id = 0; id <= BEL_LUT_MAX_Z; id++) { - const CellInfo *ff = ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,id))); + const CellInfo *ff = ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, id))); if (ff == nullptr) continue; if (!check_assign_sig(reset, ff->getPort(id_R))) { @@ -485,8 +486,10 @@ struct SectionFEWorker const auto &extra_data = *impl->bel_extra_data(bel); if (cell->params.count(id_type)) { const std::string &type = cell->params[id_type].as_string(); - if (type=="CSC" && (extra_data.flags & BEL_EXTRA_FE_CSC) == 0) return false; // No CSC capability on FE - if (type=="SCC" && (extra_data.flags & BEL_EXTRA_FE_SCC) == 0) return false; // No SCC capability on FE + if (type == "CSC" && (extra_data.flags & BEL_EXTRA_FE_CSC) == 0) + return false; // No CSC capability on FE + if (type == "SCC" && (extra_data.flags & BEL_EXTRA_FE_SCC) == 0) + return false; // No SCC capability on FE } if (extra_data.flags & BEL_EXTRA_FE_CSC) return false; @@ -505,83 +508,109 @@ bool NgUltraImpl::isBelLocationValid(BelId bel, bool explain_invalid) const if (ctx->getBelType(bel) == id_BEYOND_FE) { SectionFEWorker worker; return worker.run(this, ctx, bel, cell); - } - else if (ctx->getBelType(bel).in(id_RF, id_XRF)) { + } else if (ctx->getBelType(bel).in(id_RF, id_XRF)) { Loc loc = ctx->getBelLocation(bel); if (loc.z == BEL_XRF_Z) { // If we used any of RFs we can not used XRF - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_RF_Z)))) return false; - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_RF_Z+1)))) return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_RF_Z)))) + return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_RF_Z + 1)))) + return false; // If we used any FIFO we can not use XRF - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_FIFO_Z)))) return false; - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_FIFO_Z+1)))) return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_FIFO_Z)))) + return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_FIFO_Z + 1)))) + return false; // If we used XFIFO we can not use XRF - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_XFIFO_Z)))) return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_XFIFO_Z)))) + return false; } else { // If we used XRF we can not use individual RF - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_XRF_Z)))) return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_XRF_Z)))) + return false; // If we used XFIFO we can not use RF - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_XFIFO_Z)))) return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_XFIFO_Z)))) + return false; int index = loc.z - BEL_RF_Z; // If we used coresponding FIFO we can not use RF - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_FIFO_Z + index)))) return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_FIFO_Z + index)))) + return false; } - } - else if (ctx->getBelType(bel).in(id_FIFO, id_XFIFO)) { + } else if (ctx->getBelType(bel).in(id_FIFO, id_XFIFO)) { Loc loc = ctx->getBelLocation(bel); if (loc.z == BEL_XFIFO_Z) { // If we used any of RFs we can not used XFIFO - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_RF_Z)))) return false; - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_RF_Z+1)))) return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_RF_Z)))) + return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_RF_Z + 1)))) + return false; // If we used any FIFO we can not use XFIFO - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_FIFO_Z)))) return false; - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_FIFO_Z+1)))) return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_FIFO_Z)))) + return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_FIFO_Z + 1)))) + return false; // If we used XFIFO we can not use XFIFO - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_XFIFO_Z)))) return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_XFIFO_Z)))) + return false; // If we used any CDC we can not use XFIFO // NOTE: CDC1 is in S4 and CDC2 is S12 - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x-1,loc.y,BEL_CDC_Z)))) return false; - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x+1,loc.y,BEL_CDC_Z+1)))) return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x - 1, loc.y, BEL_CDC_Z)))) + return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x + 1, loc.y, BEL_CDC_Z + 1)))) + return false; // If we used XCDC we can not use XFIFO - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_XCDC_Z)))) return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_XCDC_Z)))) + return false; } else { // If we used XFIFO we can not use individual FIFO - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_XFIFO_Z)))) return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_XFIFO_Z)))) + return false; // If we used XRF we can not use FIFO - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_XRF_Z)))) return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_XRF_Z)))) + return false; // If we used XCDC we can not use FIFO - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_XCDC_Z)))) return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_XCDC_Z)))) + return false; int index = loc.z - BEL_FIFO_Z; // If we used coresponding RF we can not use FIFO - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_RF_Z + index)))) return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_RF_Z + index)))) + return false; // If we used coresponding CDC we can not use FIFO // NOTE: CDC1 is in S4 and CDC2 is S12 int rel = (index == 0) ? -1 : +1; - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x + rel,loc.y,BEL_CDC_Z + index)))) return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x + rel, loc.y, BEL_CDC_Z + index)))) + return false; } - } - else if (ctx->getBelType(bel).in(id_CDC, id_XCDC)) { + } else if (ctx->getBelType(bel).in(id_CDC, id_XCDC)) { Loc loc = ctx->getBelLocation(bel); if (loc.z == BEL_XCDC_Z) { // If we used any of CDCs we can not used XCDC // NOTE: CDC1 is in S4 and CDC2 is S12 - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x-1,loc.y,BEL_CDC_Z)))) return false; - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x+1,loc.y,BEL_CDC_Z+1)))) return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x - 1, loc.y, BEL_CDC_Z)))) + return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x + 1, loc.y, BEL_CDC_Z + 1)))) + return false; // If we used any FIFO we can not use XCDC - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_FIFO_Z)))) return false; - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_FIFO_Z+1)))) return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_FIFO_Z)))) + return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_FIFO_Z + 1)))) + return false; // If we used XFIFO we can not use XCDC - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_XFIFO_Z)))) return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_XFIFO_Z)))) + return false; } else { // NOTE: CDC1 is in S4 and CDC2 is S12 so we move calculation relative to S8 int index = loc.z - BEL_CDC_Z; int fix = (index == 0) ? +1 : -1; // If we used XCDC we can not use individual CDC - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x+fix,loc.y,BEL_XCDC_Z)))) return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x + fix, loc.y, BEL_XCDC_Z)))) + return false; // If we used XFIFO we can not use CDC - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x+fix,loc.y,BEL_XFIFO_Z)))) return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x + fix, loc.y, BEL_XFIFO_Z)))) + return false; // If we used coresponding FIFO we can not use CDC - if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x+fix,loc.y,BEL_FIFO_Z + index)))) return false; + if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x + fix, loc.y, BEL_FIFO_Z + index)))) + return false; } } return true; @@ -590,7 +619,7 @@ bool NgUltraImpl::isBelLocationValid(BelId bel, bool explain_invalid) const // Bel bucket functions IdString NgUltraImpl::getBelBucketForCellType(IdString cell_type) const { - if (cell_type.in(id_IOP,id_IP,id_OP,id_IOTP,id_ITP,id_OTP)) + if (cell_type.in(id_IOP, id_IP, id_OP, id_IOTP, id_ITP, id_OTP)) return ctx->idf("IOP/IOTP"); else if (cell_type.in(id_BFR, id_DFR, id_DDFR)) return ctx->idf("DFR/DDFR"); @@ -626,17 +655,17 @@ bool NgUltraImpl::isValidBelForCellType(IdString cell_type, BelId bel) const { IdString bel_type = ctx->getBelType(bel); if (bel_type == id_IOTP) - return cell_type.in(id_IOP,id_IP,id_OP,id_IOTP,id_ITP,id_OTP); + return cell_type.in(id_IOP, id_IP, id_OP, id_IOTP, id_ITP, id_OTP); else if (bel_type == id_IOP) - return cell_type.in(id_IOP,id_IP,id_OP); + return cell_type.in(id_IOP, id_IP, id_OP); else if (bel_type == id_DDFR) - return cell_type.in(id_BFR,id_DFR,id_DDFR); + return cell_type.in(id_BFR, id_DFR, id_DDFR); else if (bel_type == id_DFR) - return cell_type.in(id_BFR,id_DFR); + return cell_type.in(id_BFR, id_DFR); else if (bel_type == id_RF) - return cell_type.in(id_RF,id_RFSP); + return cell_type.in(id_RF, id_RFSP); else if (bel_type == id_XRF) - return cell_type.in(id_XHRF,id_XWRF,id_XPRF); + 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) @@ -646,7 +675,7 @@ bool NgUltraImpl::isValidBelForCellType(IdString cell_type, BelId bel) const 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); + return cell_type.in(id_WFB, id_WFG); else return (bel_type == cell_type); } @@ -657,35 +686,55 @@ bool NgUltraImpl::getChildPlacement(const BaseClusterInfo *cluster, Loc root_loc Loc prev = root_loc; for (auto child : cluster->constr_children) { Loc child_loc; - switch(child->constr_z) { - case PLACE_CY_CHAIN :child_loc = getNextLocInCYChain(prev); prev = child_loc; break; - case PLACE_LUT_CHAIN : child_loc = getNextLocInLUTChain(prev); prev = child_loc; break; - case PLACE_DFF_CHAIN : child_loc = getNextLocInDFFChain(prev); prev = child_loc; break; - case PLACE_CY_FE1 ... PLACE_CY_FE4: child_loc = getCYFE(root_loc, child->constr_z - PLACE_CY_FE1 ); break; - case PLACE_XLUT_FE1 ... PLACE_XLUT_FE4: child_loc = getXLUTFE(root_loc, child->constr_z - PLACE_XLUT_FE1 );break; - case PLACE_XRF_I1 ... PLACE_XRF_WEA: - child_loc = getXRFFE(root_loc, child->constr_z - PLACE_XRF_I1 ); break; - case PLACE_CDC_AI1 ... PLACE_CDC_DDRSTI: - child_loc = getCDCFE(root_loc, child->constr_z - PLACE_CDC_AI1 ); break; - case PLACE_FIFO_I1 ... PLACE_FIFO_REQ2: - child_loc = getFIFOFE(root_loc, child->constr_z - PLACE_FIFO_I1 ); break; - case PLACE_DSP_CHAIN : child_loc = getNextLocInDSPChain(this, prev); prev = child_loc; break; - default: - child_loc.x = root_loc.x + child->constr_x; - child_loc.y = root_loc.y + child->constr_y; - child_loc.z = child->constr_abs_z ? child->constr_z : (root_loc.z + child->constr_z); + switch (child->constr_z) { + case PLACE_CY_CHAIN: + child_loc = getNextLocInCYChain(prev); + prev = child_loc; + break; + case PLACE_LUT_CHAIN: + child_loc = getNextLocInLUTChain(prev); + prev = child_loc; + break; + case PLACE_DFF_CHAIN: + child_loc = getNextLocInDFFChain(prev); + prev = child_loc; + break; + case PLACE_CY_FE1 ... PLACE_CY_FE4: + child_loc = getCYFE(root_loc, child->constr_z - PLACE_CY_FE1); + break; + case PLACE_XLUT_FE1 ... PLACE_XLUT_FE4: + child_loc = getXLUTFE(root_loc, child->constr_z - PLACE_XLUT_FE1); + break; + case PLACE_XRF_I1 ... PLACE_XRF_WEA: + child_loc = getXRFFE(root_loc, child->constr_z - PLACE_XRF_I1); + break; + case PLACE_CDC_AI1 ... PLACE_CDC_DDRSTI: + child_loc = getCDCFE(root_loc, child->constr_z - PLACE_CDC_AI1); + break; + case PLACE_FIFO_I1 ... PLACE_FIFO_REQ2: + child_loc = getFIFOFE(root_loc, child->constr_z - PLACE_FIFO_I1); + break; + case PLACE_DSP_CHAIN: + child_loc = getNextLocInDSPChain(this, prev); + prev = child_loc; + break; + default: + child_loc.x = root_loc.x + child->constr_x; + child_loc.y = root_loc.y + child->constr_y; + child_loc.z = child->constr_abs_z ? child->constr_z : (root_loc.z + child->constr_z); } BelId child_bel = ctx->getBelByLocation(child_loc); if (child_bel == BelId() || !this->isValidBelForCellType(child->type, child_bel)) return false; placement.emplace_back(child, child_bel); - if (!getChildPlacement(child, child_loc, placement)) return false; + if (!getChildPlacement(child, child_loc, placement)) + return false; } return true; } bool NgUltraImpl::getClusterPlacement(ClusterId cluster, BelId root_bel, - std::vector> &placement) const + std::vector> &placement) const { CellInfo *root_cell = get_cluster_root(ctx, cluster); placement.clear(); @@ -704,8 +753,8 @@ bool NgUltraImpl::getClusterPlacement(ClusterId cluster, BelId root_bel, BoundingBox NgUltraImpl::getRouteBoundingBox(WireId src, WireId dst) const { - if ((tile_type(src.tile)!=TILE_EXTRA_FABRIC || tile_type(dst.tile)!=TILE_EXTRA_FABRIC)) { - return { 0, 0, ctx->getGridDimX(), ctx->getGridDimY() }; + if ((tile_type(src.tile) != TILE_EXTRA_FABRIC || tile_type(dst.tile) != TILE_EXTRA_FABRIC)) { + return {0, 0, ctx->getGridDimX(), ctx->getGridDimY()}; } int x0, y0, x1, y1; auto expand = [&](int x, int y) { @@ -721,10 +770,10 @@ BoundingBox NgUltraImpl::getRouteBoundingBox(WireId src, WireId dst) const tile_xy(ctx->chip_info, dst.tile, dx, dy); expand(dx, dy); // Reach 7 MESH above and below (3 left and 3 right of TILE/CGB) - return {(x0 & 0xfffc) - 3*4, // 3 MESH on left - (y0 & 0xfffc) - 4, // row above - (x1 & 0xfffc) + 4*4, // MESH bellow and 3 right - (y1 & 0xfffc) + 8}; // current and row bellow + return {(x0 & 0xfffc) - 3 * 4, // 3 MESH on left + (y0 & 0xfffc) - 4, // row above + (x1 & 0xfffc) + 4 * 4, // MESH bellow and 3 right + (y1 & 0xfffc) + 8}; // current and row bellow } void NgUltraImpl::expandBoundingBox(BoundingBox &bb) const @@ -743,42 +792,41 @@ delay_t NgUltraImpl::estimateDelay(WireId src, WireId dst) const int sx, sy, dx, dy; tile_xy(ctx->chip_info, src.tile, sx, sy); tile_xy(ctx->chip_info, dst.tile, dx, dy); - if (sx==dx && sy==dy) { + if (sx == dx && sy == dy) { // Same sub tile return 50; } else if (((sx & 0xfffc) == (dx & 0xfffc)) && ((sy & 0xfffc) == (dy & 0xfffc))) { // Same "TILE" return 200; } - return 500 + 100 * (std::abs(dy - sy)/4 + std::abs(dx - sx)/4); + return 500 + 100 * (std::abs(dy - sy) / 4 + std::abs(dx - sx) / 4); } - delay_t NgUltraImpl::predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const { Loc src_loc = ctx->getBelLocation(src_bel), dst_loc = ctx->getBelLocation(dst_bel); - if (src_loc.x==dst_loc.x && src_loc.y==dst_loc.y) { + if (src_loc.x == dst_loc.x && src_loc.y == dst_loc.y) { // Same sub tile return 50; } else if (((src_loc.x & 0xfffc) == (dst_loc.x & 0xfffc)) && ((src_loc.y & 0xfffc) == (dst_loc.y & 0xfffc))) { // Same "TILE" return 200; } - return 500 + 100 * (std::abs(dst_loc.y - src_loc.y)/4 + std::abs(dst_loc.x - src_loc.x)/4); + return 500 + 100 * (std::abs(dst_loc.y - src_loc.y) / 4 + std::abs(dst_loc.x - src_loc.x) / 4); } void NgUltraImpl::fixup_crossbars() { - auto is_crossbar_pip = [&] (PipId pip) { + auto is_crossbar_pip = [&](PipId pip) { const auto &extra_data = *pip_extra_data(pip); return (extra_data.name && extra_data.type == PipExtra::PIP_EXTRA_CROSSBAR); }; - auto crossbar_key = [&] (PipId pip) { + auto crossbar_key = [&](PipId pip) { const auto &extra_data = *pip_extra_data(pip); return std::make_pair(pip.tile, IdString(extra_data.name)); - }; + }; for (auto &net : ctx->nets) { NetInfo *ni = net.second.get(); @@ -823,7 +871,8 @@ void NgUltraImpl::fixup_crossbars() } NPNR_ASSERT(found_pip != PipId()); // rebind - //log_info(" replacing crossbar pip %s with %s on %s\n", ctx->nameOfPip(pip), ctx->nameOfPip(found_pip), ctx->nameOf(ni)); + // log_info(" replacing crossbar pip %s with %s on %s\n", ctx->nameOfPip(pip), + // ctx->nameOfPip(found_pip), ctx->nameOf(ni)); ctx->bindPip(found_pip, ni, STRENGTH_STRONG); } } @@ -842,177 +891,174 @@ void NgUltraImpl::drawBel(std::vector &g, GraphicElement::style_ GraphicElement el; el.type = GraphicElement::TYPE_BOX; el.style = style; - switch (bel_type.index) - { - case id_BEYOND_FE.index : - el.x1 = loc.x + 0.15 + (loc.z % 8) * 0.1; - el.x2 = el.x1 + 0.05; - el.y1 = loc.y + 0.9 - (loc.z / 8) * 0.15; - el.y2 = el.y1 - 0.05; - g.push_back(el); - break; - case id_XLUT.index : - el.x1 = loc.x + 0.15 + ((loc.z - BEL_XLUT_Z) % 8) * 0.1; - el.x2 = el.x1 + 0.05; - el.y1 = loc.y + 0.9 - 4 * 0.15; - el.y2 = el.y1 - 0.1; - g.push_back(el); - break; - case id_CY.index : - el.x1 = loc.x + 0.15 + ((loc.z-BEL_CY_Z) % 4) * 0.2; - el.x2 = el.x1 + 0.15; - el.y1 = loc.y + 0.9 - 4 * 0.15; - el.y2 = el.y1 - 0.1; - g.push_back(el); - break; - case id_RF.index : - el.x1 = loc.x + 0.15 + ((loc.z-BEL_RF_Z) % 2) * 0.6; - el.x2 = el.x1 + 0.15; - el.y1 = loc.y + 0.9 - 4 * 0.15; - el.y2 = el.y1 - 0.05; - g.push_back(el); - break; - case id_XRF.index : - el.x1 = loc.x + 0.15 + 0.2; - el.x2 = el.x1 + 0.35; - el.y1 = loc.y + 0.9 - 4 * 0.15; - el.y2 = el.y1 - 0.05; - g.push_back(el); - break; - case id_CDC.index : - el.x1 = loc.x + 0.15 + ((loc.z-BEL_CDC_Z) % 2) * 0.6; - el.x2 = el.x1 + 0.15; - el.y1 = loc.y + 0.9 - 4 * 0.15 - 0.1; - el.y2 = el.y1 - 0.05; - g.push_back(el); - break; - case id_XCDC.index : - el.x1 = loc.x + 0.15 + 0.2; - el.x2 = el.x1 + 0.35; - el.y1 = loc.y + 0.9 - 4 * 0.15 - 0.1; - el.y2 = el.y1 - 0.05; - g.push_back(el); - break; - case id_FIFO.index : - el.x1 = loc.x + 0.15 + ((loc.z-BEL_FIFO_Z) % 2) * 0.6; - el.x2 = el.x1 + 0.15; - el.y1 = loc.y + 0.9 - 4 * 0.15 - 0.2; - el.y2 = el.y1 - 0.05; - g.push_back(el); - break; - case id_XFIFO.index : - el.x1 = loc.x + 0.15 + 0.2; - el.x2 = el.x1 + 0.35; - el.y1 = loc.y + 0.9 - 4 * 0.15 - 0.2; - el.y2 = el.y1 - 0.05; - g.push_back(el); - break; - case id_IOTP.index : - el.x1 = loc.x + 0.15 + loc.z / 4 * 0.11; - el.x2 = el.x1 + 0.06; - if (loc.y==3) { // bottom - el.y1 = 0.1; - el.y2 = el.y1 + 0.2; - } else { // top - el.y1 = loc.y + 0.9; - el.y2 = el.y1 - 0.2; - } - g.push_back(el); - break; - case id_IOM.index : - el.x1 = loc.x + 0.15; - el.x2 = el.x1 + 33 * 0.11 + 0.06; - if (loc.y==3) { // bottom - el.y1 = 0.4; - el.y2 = el.y1 + 0.2; - } else { // top - el.y1 = loc.y + 0.6; - el.y2 = el.y1 - 0.2; - } - g.push_back(el); - break; - case id_DDFR.index : - el.x1 = loc.x + 0.15 + loc.z / 4 * 0.11 + (loc.z % 4 - 1) * 0.02; - el.x2 = el.x1 + 0.015; - if (loc.y==3) { // bottom - el.y1 = 0.7; - el.y2 = el.y1 + 0.1; - } else { // top - el.y1 = loc.y + 0.3; - el.y2 = el.y1 - 0.1; - } - g.push_back(el); - break; - case id_IOP.index : - if (loc.x==ctx->getGridDimX()-4) { // right - el.x1 = ctx->getGridDimX() - 0.1; - el.x2 = el.x1 - 0.2; - } else { // left - el.x1 = loc.x + 0.1; - el.x2 = el.x1 + 0.2; - } - el.y1 = loc.y + 0.85 - loc.z / 4 * 0.11; - el.y2 = el.y1 - 0.06; - g.push_back(el); - break; - case id_DFR.index : - if (loc.x==ctx->getGridDimX()-4) { // right - el.x1 = ctx->getGridDimX() - 0.4; - el.x2 = el.x1 - 0.1; - } else { // left - el.x1 = loc.x + 0.4; - el.x2 = el.x1 + 0.1; - } - el.y1 = loc.y + 0.85 - loc.z / 4 * 0.11 - (loc.z % 4 - 1) * 0.02 - 0.02; - el.y2 = el.y1 + 0.015; - g.push_back(el); - break; - case id_PLL.index : - el.x1 = loc.x + 0.1; - el.x2 = el.x1 + 0.8; + switch (bel_type.index) { + case id_BEYOND_FE.index: + el.x1 = loc.x + 0.15 + (loc.z % 8) * 0.1; + el.x2 = el.x1 + 0.05; + el.y1 = loc.y + 0.9 - (loc.z / 8) * 0.15; + el.y2 = el.y1 - 0.05; + g.push_back(el); + break; + case id_XLUT.index: + el.x1 = loc.x + 0.15 + ((loc.z - BEL_XLUT_Z) % 8) * 0.1; + el.x2 = el.x1 + 0.05; + el.y1 = loc.y + 0.9 - 4 * 0.15; + el.y2 = el.y1 - 0.1; + g.push_back(el); + break; + case id_CY.index: + el.x1 = loc.x + 0.15 + ((loc.z - BEL_CY_Z) % 4) * 0.2; + el.x2 = el.x1 + 0.15; + el.y1 = loc.y + 0.9 - 4 * 0.15; + el.y2 = el.y1 - 0.1; + g.push_back(el); + break; + case id_RF.index: + el.x1 = loc.x + 0.15 + ((loc.z - BEL_RF_Z) % 2) * 0.6; + el.x2 = el.x1 + 0.15; + el.y1 = loc.y + 0.9 - 4 * 0.15; + el.y2 = el.y1 - 0.05; + g.push_back(el); + break; + case id_XRF.index: + el.x1 = loc.x + 0.15 + 0.2; + el.x2 = el.x1 + 0.35; + el.y1 = loc.y + 0.9 - 4 * 0.15; + el.y2 = el.y1 - 0.05; + g.push_back(el); + break; + case id_CDC.index: + el.x1 = loc.x + 0.15 + ((loc.z - BEL_CDC_Z) % 2) * 0.6; + el.x2 = el.x1 + 0.15; + el.y1 = loc.y + 0.9 - 4 * 0.15 - 0.1; + el.y2 = el.y1 - 0.05; + g.push_back(el); + break; + case id_XCDC.index: + el.x1 = loc.x + 0.15 + 0.2; + el.x2 = el.x1 + 0.35; + el.y1 = loc.y + 0.9 - 4 * 0.15 - 0.1; + el.y2 = el.y1 - 0.05; + g.push_back(el); + break; + case id_FIFO.index: + el.x1 = loc.x + 0.15 + ((loc.z - BEL_FIFO_Z) % 2) * 0.6; + el.x2 = el.x1 + 0.15; + el.y1 = loc.y + 0.9 - 4 * 0.15 - 0.2; + el.y2 = el.y1 - 0.05; + g.push_back(el); + break; + case id_XFIFO.index: + el.x1 = loc.x + 0.15 + 0.2; + el.x2 = el.x1 + 0.35; + el.y1 = loc.y + 0.9 - 4 * 0.15 - 0.2; + el.y2 = el.y1 - 0.05; + g.push_back(el); + break; + case id_IOTP.index: + el.x1 = loc.x + 0.15 + loc.z / 4 * 0.11; + el.x2 = el.x1 + 0.06; + if (loc.y == 3) { // bottom + el.y1 = 0.1; + el.y2 = el.y1 + 0.2; + } else { // top el.y1 = loc.y + 0.9; - el.y2 = el.y1 - 0.8; - g.push_back(el); - break; - case id_WFG.index : - el.x1 = loc.x + 1.1; - el.x2 = el.x1 + 0.8; - el.y1 = loc.y + 0.95 - (loc.z-1) * 0.25 + 3; el.y2 = el.y1 - 0.2; - g.push_back(el); - break; - case id_RAM.index: - el.x1 = loc.x + 0.2; - el.x2 = el.x1 + 3.6; - el.y1 = loc.y + 0.8; - el.y2 = el.y1 - 1.6; - g.push_back(el); - break; - case id_DSP.index: - el.x1 = (loc.x - 1) + 0.2; - el.x2 = el.x1 + 1.6; - el.y1 = loc.y + 0.8; - el.y2 = el.y1 - 1.6; - g.push_back(el); - break; - case id_GCK.index: - { - int lobe = loc.z / 20; - el.x1 = (47 + (lobe % 2)*3) *4 + 0.1; - el.x2 = el.x1 + 0.8; - el.y1 = (ctx->getGridDimY() - 1 - (7*4 + 12*4*(lobe>>1))) + 0.95 - (loc.z % 20) * 0.25; - el.y2 = el.y1 - 0.2; - g.push_back(el); - } - break; - default: - break; + } + g.push_back(el); + break; + case id_IOM.index: + el.x1 = loc.x + 0.15; + el.x2 = el.x1 + 33 * 0.11 + 0.06; + if (loc.y == 3) { // bottom + el.y1 = 0.4; + el.y2 = el.y1 + 0.2; + } else { // top + el.y1 = loc.y + 0.6; + el.y2 = el.y1 - 0.2; + } + g.push_back(el); + break; + case id_DDFR.index: + el.x1 = loc.x + 0.15 + loc.z / 4 * 0.11 + (loc.z % 4 - 1) * 0.02; + el.x2 = el.x1 + 0.015; + if (loc.y == 3) { // bottom + el.y1 = 0.7; + el.y2 = el.y1 + 0.1; + } else { // top + el.y1 = loc.y + 0.3; + el.y2 = el.y1 - 0.1; + } + g.push_back(el); + break; + case id_IOP.index: + if (loc.x == ctx->getGridDimX() - 4) { // right + el.x1 = ctx->getGridDimX() - 0.1; + el.x2 = el.x1 - 0.2; + } else { // left + el.x1 = loc.x + 0.1; + el.x2 = el.x1 + 0.2; + } + el.y1 = loc.y + 0.85 - loc.z / 4 * 0.11; + el.y2 = el.y1 - 0.06; + g.push_back(el); + break; + case id_DFR.index: + if (loc.x == ctx->getGridDimX() - 4) { // right + el.x1 = ctx->getGridDimX() - 0.4; + el.x2 = el.x1 - 0.1; + } else { // left + el.x1 = loc.x + 0.4; + el.x2 = el.x1 + 0.1; + } + el.y1 = loc.y + 0.85 - loc.z / 4 * 0.11 - (loc.z % 4 - 1) * 0.02 - 0.02; + el.y2 = el.y1 + 0.015; + g.push_back(el); + break; + case id_PLL.index: + el.x1 = loc.x + 0.1; + el.x2 = el.x1 + 0.8; + el.y1 = loc.y + 0.9; + el.y2 = el.y1 - 0.8; + g.push_back(el); + break; + case id_WFG.index: + el.x1 = loc.x + 1.1; + el.x2 = el.x1 + 0.8; + el.y1 = loc.y + 0.95 - (loc.z - 1) * 0.25 + 3; + el.y2 = el.y1 - 0.2; + g.push_back(el); + break; + case id_RAM.index: + el.x1 = loc.x + 0.2; + el.x2 = el.x1 + 3.6; + el.y1 = loc.y + 0.8; + el.y2 = el.y1 - 1.6; + g.push_back(el); + break; + case id_DSP.index: + el.x1 = (loc.x - 1) + 0.2; + el.x2 = el.x1 + 1.6; + el.y1 = loc.y + 0.8; + el.y2 = el.y1 - 1.6; + g.push_back(el); + break; + case id_GCK.index: { + int lobe = loc.z / 20; + el.x1 = (47 + (lobe % 2) * 3) * 4 + 0.1; + el.x2 = el.x1 + 0.8; + el.y1 = (ctx->getGridDimY() - 1 - (7 * 4 + 12 * 4 * (lobe >> 1))) + 0.95 - (loc.z % 20) * 0.25; + el.y2 = el.y1 - 0.2; + g.push_back(el); + } break; + default: + break; } } struct NgUltraArch : HimbaechelArch { - NgUltraArch() : HimbaechelArch("ng-ultra"){}; + NgUltraArch() : HimbaechelArch("ng-ultra") {}; bool match_device(const std::string &device) override { return device == "NG-ULTRA"; } std::unique_ptr create(const std::string &device, const dict &args) { diff --git a/himbaechel/uarch/ng-ultra/ng_ultra.h b/himbaechel/uarch/ng-ultra/ng_ultra.h index 8ea56e73..a5b6511d 100644 --- a/himbaechel/uarch/ng-ultra/ng_ultra.h +++ b/himbaechel/uarch/ng-ultra/ng_ultra.h @@ -59,25 +59,26 @@ struct NgUltraImpl : HimbaechelAPI bool getClusterPlacement(ClusterId cluster, BelId root_bel, std::vector> &placement) const override; bool getChildPlacement(const BaseClusterInfo *cluster, Loc root_loc, - std::vector> &placement) const; + std::vector> &placement) const; BoundingBox getRouteBoundingBox(WireId src, WireId dst) const override; delay_t estimateDelay(WireId src, WireId dst) const override; delay_t predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const override; - bool checkPipAvail(PipId pip) const override { return blocked_pips.count(pip)==0; } + bool checkPipAvail(PipId pip) const override { return blocked_pips.count(pip) == 0; } bool checkPipAvailForNet(PipId pip, const NetInfo *net) const override { return checkPipAvail(pip); }; void expandBoundingBox(BoundingBox &bb) const override; void drawBel(std::vector &g, GraphicElement::style_t style, IdString bel_type, Loc loc) override; -public: + + public: int tile_lobe(int tile) const; TileTypeExtra tile_type(int tile) const; IdString tile_name_id(int tile) const; std::string tile_name(int tile) const; - const dict>& get_fabric_lowskew_sinks(); + const dict> &get_fabric_lowskew_sinks(); bool is_fabric_lowskew_sink(const PortRef &ref); bool is_ring_clock_sink(const PortRef &ref); bool is_ring_over_tile_clock_sink(const PortRef &ref); @@ -89,15 +90,15 @@ public: const NGUltraPipExtraDataPOD *pip_extra_data(PipId pip) const; const NGUltraBelExtraDataPOD *bel_extra_data(BelId bel) const; - dict iom_bels; + dict iom_bels; dict bank_voltage; - dict global_capable_bels; - dict locations; - dict tile_locations; - dict> gck_per_lobe; + dict global_capable_bels; + dict locations; + dict tile_locations; + dict> gck_per_lobe; pool blocked_pips; - dict> bank_to_ckg; + dict> bank_to_ckg; dict unused_wfg; dict unused_pll; dict dsp_cascade; diff --git a/himbaechel/uarch/ng-ultra/pack.cc b/himbaechel/uarch/ng-ultra/pack.cc index 6c93720f..182be6b2 100644 --- a/himbaechel/uarch/ng-ultra/pack.cc +++ b/himbaechel/uarch/ng-ultra/pack.cc @@ -39,7 +39,7 @@ NEXTPNR_NAMESPACE_BEGIN inline bool is_lut(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_NX_LUT; } // Return true if a cell is a flipflop -inline bool is_dff(const BaseCtx *ctx, const CellInfo *cell) { return cell->type.in(id_NX_DFF,id_NX_BFF); } +inline bool is_dff(const BaseCtx *ctx, const CellInfo *cell) { return cell->type.in(id_NX_DFF, id_NX_BFF); } // Return true if a cell is a FE inline bool is_fe(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_BEYOND_FE; } @@ -72,8 +72,10 @@ void NgUltraPacker::pack_constants(void) { log_info("Packing constants..\n"); // Replace constants with LUTs - const dict vcc_params = {{id_lut_table, Property(0xFFFF, 16)}, {id_lut_used, Property(1,1)}, {id_dff_used, Property(1,1)}}; - const dict gnd_params = {{id_lut_table, Property(0x0000, 16)}, {id_lut_used, Property(1,1)}, {id_dff_used, Property(1,1)}}; + const dict vcc_params = { + {id_lut_table, Property(0xFFFF, 16)}, {id_lut_used, Property(1, 1)}, {id_dff_used, Property(1, 1)}}; + const dict gnd_params = { + {id_lut_table, Property(0x0000, 16)}, {id_lut_used, Property(1, 1)}, {id_dff_used, Property(1, 1)}}; h.replace_constants(CellTypePort(id_BEYOND_FE, id_LO), CellTypePort(id_BEYOND_FE, id_LO), vcc_params, gnd_params); } @@ -84,7 +86,7 @@ void NgUltraImpl::remove_constants() auto fnd_cell = ctx->cells.find(ctx->id("$PACKER_VCC_DRV")); if (fnd_cell != ctx->cells.end()) { auto fnd_net = ctx->nets.find(ctx->id("$PACKER_VCC")); - if (fnd_net != ctx->nets.end() && fnd_net->second->users.entries()==0) { + if (fnd_net != ctx->nets.end() && fnd_net->second->users.entries() == 0) { BelId bel = (*fnd_cell).second.get()->bel; if (bel != BelId()) ctx->unbindBel(bel); @@ -96,7 +98,7 @@ void NgUltraImpl::remove_constants() fnd_cell = ctx->cells.find(ctx->id("$PACKER_GND_DRV")); if (fnd_cell != ctx->cells.end()) { auto fnd_net = ctx->nets.find(ctx->id("$PACKER_GND")); - if (fnd_net != ctx->nets.end() && fnd_net->second->users.entries()==0) { + if (fnd_net != ctx->nets.end() && fnd_net->second->users.entries() == 0) { BelId bel = (*fnd_cell).second.get()->bel; if (bel != BelId()) ctx->unbindBel(bel); @@ -131,7 +133,7 @@ void NgUltraPacker::update_lut_init() void NgUltraPacker::dff_rewrite(CellInfo *cell) { - if (int_or_default(cell->params, id_dff_init, 0)==0) { + if (int_or_default(cell->params, id_dff_init, 0) == 0) { // Reset not used cell->disconnectPort(id_R); } else { @@ -140,7 +142,7 @@ void NgUltraPacker::dff_rewrite(CellInfo *cell) if (net) { if (net->name == ctx->id("$PACKER_GND")) { log_warning("Removing reset on '%s' since it is always 0.\n", cell->name.c_str(ctx)); - cell->setParam(id_dff_init, Property(0,1)); + cell->setParam(id_dff_init, Property(0, 1)); cell->disconnectPort(id_R); } else if (net->name == ctx->id("$PACKER_VCC")) { log_error("Invalid DFF configuration, reset on '%s' is always 1.\n", cell->name.c_str(ctx)); @@ -148,7 +150,7 @@ void NgUltraPacker::dff_rewrite(CellInfo *cell) } } - if (int_or_default(cell->params, id_dff_load, 0)==0) { + if (int_or_default(cell->params, id_dff_load, 0) == 0) { // Load not used cell->disconnectPort(id_L); } else { @@ -157,11 +159,11 @@ void NgUltraPacker::dff_rewrite(CellInfo *cell) if (net) { if (net->name == ctx->id("$PACKER_VCC")) { log_warning("Removing load enable on '%s' since it is always 1.\n", cell->name.c_str(ctx)); - cell->setParam(id_dff_load, Property(0,0)); + cell->setParam(id_dff_load, Property(0, 0)); cell->disconnectPort(id_L); } else if (net->name == ctx->id("$PACKER_GND")) { log_warning("Converting to self loop, since load enable on '%s' is always 0.\n", cell->name.c_str(ctx)); - cell->setParam(id_dff_load, Property(0,0)); + cell->setParam(id_dff_load, Property(0, 0)); cell->disconnectPort(id_L); cell->disconnectPort(id_I); NetInfo *out = cell->getPort(id_O); @@ -174,7 +176,7 @@ void NgUltraPacker::dff_rewrite(CellInfo *cell) void NgUltraPacker::ddfr_rewrite(CellInfo *cell) { // Reversed logic in comparison to DFF - if (int_or_default(cell->params, id_dff_load, 0)==1) { + if (int_or_default(cell->params, id_dff_load, 0) == 1) { // Load not used cell->disconnectPort(id_L); } else { @@ -183,7 +185,7 @@ void NgUltraPacker::ddfr_rewrite(CellInfo *cell) if (net) { if (net->name == ctx->id("$PACKER_VCC")) { log_warning("Removing load enable on '%s' since it is always 1.\n", cell->name.c_str(ctx)); - cell->setParam(id_dff_load, Property(0,0)); + cell->setParam(id_dff_load, Property(0, 0)); cell->disconnectPort(id_L); } } @@ -253,14 +255,15 @@ void NgUltraPacker::connect_gnd_if_unconnected(CellInfo *cell, IdString input, b if (fnd_net != ctx->nets.end()) { cell->connectPort(input, fnd_net->second.get()); if (warn) - log_warning("Connected GND to mandatory port '%s' of cell '%s'(%s).\n", input.c_str(ctx), cell->name.c_str(ctx), cell->type.c_str(ctx)); + log_warning("Connected GND to mandatory port '%s' of cell '%s'(%s).\n", input.c_str(ctx), + cell->name.c_str(ctx), cell->type.c_str(ctx)); } } void NgUltraPacker::lut_to_fe(CellInfo *lut, CellInfo *fe, bool no_dff, Property lut_table) { fe->params[id_lut_table] = lut_table; - fe->params[id_lut_used] = Property(1,1); + fe->params[id_lut_used] = Property(1, 1); lut->movePortTo(id_I1, fe, id_I1); lut->movePortTo(id_I2, fe, id_I2); lut->movePortTo(id_I3, fe, id_I3); @@ -277,18 +280,17 @@ void NgUltraPacker::dff_to_fe(CellInfo *dff, CellInfo *fe, bool pass_thru_lut) NetInfo *net = dff->getPort(id_I); if (net && net->name.in(ctx->id("$PACKER_GND"), ctx->id("$PACKER_VCC"))) { // special case if driver is constant - fe->params[id_lut_table] = Property((net->name ==ctx->id("$PACKER_GND")) ? 0x0000 : 0xffff, 16); + fe->params[id_lut_table] = Property((net->name == ctx->id("$PACKER_GND")) ? 0x0000 : 0xffff, 16); dff->disconnectPort(id_I); } else { // otherwise just passthru fe->params[id_lut_table] = Property(0xaaaa, 16); dff->movePortTo(id_I, fe, id_I1); } - fe->params[id_lut_used] = Property(1,1); - } - else + fe->params[id_lut_used] = Property(1, 1); + } else dff->movePortTo(id_I, fe, id_DI); - fe->params[id_dff_used] = Property(1,1); + fe->params[id_dff_used] = Property(1, 1); dff->movePortTo(id_O, fe, id_DO); if (dff->type == id_NX_BFF) { fe->setParam(id_type, Property("BFF")); @@ -299,15 +301,21 @@ void NgUltraPacker::dff_to_fe(CellInfo *dff, CellInfo *fe, bool pass_thru_lut) dff->movePortTo(id_CK, fe, id_CK); dff->movePortTo(id_L, fe, id_L); - if (dff->params.count(id_dff_ctxt)) fe->setParam(id_dff_ctxt,dff->params[id_dff_ctxt]); - if (dff->params.count(id_dff_edge)) fe->setParam(id_dff_edge,dff->params[id_dff_edge]); - if (dff->params.count(id_dff_init)) fe->setParam(id_dff_init,dff->params[id_dff_init]); - if (dff->params.count(id_dff_load)) fe->setParam(id_dff_load,dff->params[id_dff_load]); - if (dff->params.count(id_dff_sync)) fe->setParam(id_dff_sync,dff->params[id_dff_sync]); - if (dff->params.count(id_dff_type)) fe->setParam(id_dff_type,dff->params[id_dff_type]); + if (dff->params.count(id_dff_ctxt)) + fe->setParam(id_dff_ctxt, dff->params[id_dff_ctxt]); + if (dff->params.count(id_dff_edge)) + fe->setParam(id_dff_edge, dff->params[id_dff_edge]); + if (dff->params.count(id_dff_init)) + fe->setParam(id_dff_init, dff->params[id_dff_init]); + if (dff->params.count(id_dff_load)) + fe->setParam(id_dff_load, dff->params[id_dff_load]); + if (dff->params.count(id_dff_sync)) + fe->setParam(id_dff_sync, dff->params[id_dff_sync]); + if (dff->params.count(id_dff_type)) + fe->setParam(id_dff_type, dff->params[id_dff_type]); } if (pass_thru_lut) { - NetInfo *new_out = ctx->createNet(ctx->idf("%s$LO",dff->name.c_str(ctx))); + NetInfo *new_out = ctx->createNet(ctx->idf("%s$LO", dff->name.c_str(ctx))); fe->connectPort(id_LO, new_out); fe->connectPort(id_DI, new_out); } @@ -317,7 +325,7 @@ void NgUltraPacker::bind_attr_loc(CellInfo *cell, dict *attr { if (attrs->count(id_LOC)) { std::string name = attrs->at(id_LOC).as_string(); - if (boost::starts_with(name,"TILE[")) { + if (boost::starts_with(name, "TILE[")) { boost::replace_all(name, ".DFF", ".FE"); boost::replace_all(name, ".LUT", ".FE"); } @@ -340,24 +348,25 @@ void NgUltraPacker::pack_xluts(void) if (!ci.params.count(id_lut_table)) log_error("Cell '%s' missing lut_table\n", ci.name.c_str(ctx)); - if (ci.cluster!=ClusterId()) + if (ci.cluster != ClusterId()) continue; CellInfo *lut[4]; int inputs_used = 0; int dff_parts_used = 0; - for(int i=0;i<4;i++) { - NetInfo *net = ci.getPort(ctx->idf("I%d",i+1)); + for (int i = 0; i < 4; i++) { + NetInfo *net = ci.getPort(ctx->idf("I%d", i + 1)); if (!net) continue; lut[i] = net_driven_by(ctx, net, is_lut, id_O); if (lut[i] == cell.second.get()) continue; if (lut[i]) { - if (net->users.entries()>1) dff_parts_used++; + if (net->users.entries() > 1) + dff_parts_used++; inputs_used++; } } - if (inputs_used!=4) + if (inputs_used != 4) continue; // we must have a route out for xlut output signal if (dff_parts_used > 3) @@ -370,16 +379,16 @@ void NgUltraPacker::pack_xluts(void) NetInfo *o = ci.getPort(id_O); CellInfo *orig_dff = o ? net_only_drives(ctx, o, is_dff, id_I, true) : nullptr; - for (int i=0;i<4;i++) { + for (int i = 0; i < 4; i++) { ci.constr_children.push_back(lut[i]); lut[i]->cluster = ci.cluster; lut[i]->type = id_BEYOND_FE; lut[i]->constr_z = PLACE_XLUT_FE1 + i; lut[i]->renamePort(id_O, id_LO); - lut[i]->params[id_lut_used] = Property(1,1); + lut[i]->params[id_lut_used] = Property(1, 1); NetInfo *net = lut[i]->getPort(id_LO); - if (net->users.entries()!=2) { - if (orig_dff && net->users.entries()==1) { + if (net->users.entries() != 2) { + if (orig_dff && net->users.entries() == 1) { // we place DFF on XLUT output on unused DFF dff_to_fe(orig_dff, lut[i], false); packed_cells.insert(orig_dff->name); @@ -391,9 +400,9 @@ void NgUltraPacker::pack_xluts(void) } } else { CellInfo *dff = (*net->users.begin()).cell; - if (dff->type!=id_NX_DFF) + if (dff->type != id_NX_DFF) dff = (*(++net->users.begin())).cell; - if (dff->type==id_NX_DFF) { + if (dff->type == id_NX_DFF) { dff_to_fe(dff, lut[i], false); packed_cells.insert(dff->name); lut_and_ff++; @@ -401,7 +410,7 @@ void NgUltraPacker::pack_xluts(void) lut[i]->timing_index = ctx->get_cell_timing_idx(id_BEYOND_FE_LUT); lut_only++; } - } + } } } if (xlut_used) @@ -416,24 +425,27 @@ void NgUltraPacker::pack_xluts(void) void NgUltraPacker::pack_dff_chains(void) { log_info("Pack DFF chains...\n"); - std::vector>> dff_chain_start; + std::vector>> dff_chain_start; for (auto &cell : ctx->cells) { CellInfo &ci = *cell.second; if (!ci.type.in(id_NX_DFF)) continue; NetInfo *inp = ci.getPort(id_I); - if (!inp || (inp->driver.cell && inp->driver.cell->type.in(id_NX_DFF))) continue; + if (!inp || (inp->driver.cell && inp->driver.cell->type.in(id_NX_DFF))) + continue; int cnt = 0; CellInfo *dff = &ci; - std::vector chain; - CellInfo* start_dff = &ci; - while(1) { + std::vector chain; + CellInfo *start_dff = &ci; + while (1) { NetInfo *o = dff->getPort(id_O); - if (!o) break; - if (o->users.entries() != 1) break; + if (!o) + break; + if (o->users.entries() != 1) + break; dff = (*o->users.begin()).cell; if (dff->type == id_NX_DFF && (*o->users.begin()).port == id_I) { - if (cnt==95) { // note that start_dff is also part of chain + if (cnt == 95) { // note that start_dff is also part of chain dff_chain_start.push_back(make_pair(start_dff, chain)); cnt = 0; start_dff = dff; @@ -442,7 +454,8 @@ void NgUltraPacker::pack_dff_chains(void) chain.push_back(dff); cnt++; } - } else break; + } else + break; } if (cnt) dff_chain_start.push_back(make_pair(start_dff, chain)); @@ -454,7 +467,7 @@ void NgUltraPacker::pack_dff_chains(void) CellInfo *root = create_cell_ptr(id_BEYOND_FE, ctx->idf("%s$fe", dff->name.c_str(ctx))); root->cluster = root->name; NetInfo *net = dff->getPort(id_I); - if (net && net->driver.cell->type == id_NX_LUT && net->users.entries()==1) { + if (net && net->driver.cell->type == id_NX_LUT && net->users.entries() == 1) { CellInfo *lut = net->driver.cell; if (!lut->params.count(id_lut_table)) log_error("Cell '%s' missing lut_table\n", lut->name.c_str(ctx)); @@ -468,7 +481,7 @@ void NgUltraPacker::pack_dff_chains(void) packed_cells.insert(dff->name); ++dff_only; } - for(auto dff : ch.second) { + for (auto dff : ch.second) { CellInfo *new_cell = create_cell_ptr(id_BEYOND_FE, ctx->idf("%s$fe", dff->name.c_str(ctx))); dff_to_fe(dff, new_cell, true); ++dff_only; @@ -489,7 +502,8 @@ 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;; + 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)) @@ -499,15 +513,16 @@ void NgUltraPacker::pack_lut_multi_dffs(void) NetInfo *o = ci.getPort(id_O); if (o) { - if (o->users.entries()<2) continue; + if (o->users.entries() < 2) + continue; int cnt = 0; - for (auto u : o->users) - { + for (auto u : o->users) { if (u.cell->type == id_NX_DFF && u.cell->getPort(id_I) == o) cnt++; } - if (cnt<2) continue; + if (cnt < 2) + continue; CellInfo *root = create_cell_ptr(id_BEYOND_FE, ctx->idf("%s$fe", ci.name.c_str(ctx))); packed_cells.insert(ci.name); @@ -515,14 +530,13 @@ void NgUltraPacker::pack_lut_multi_dffs(void) 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 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) - { + for (auto u : o->users) { if (u.cell->type == id_NX_DFF && u.cell->getPort(id_I) == o) { - if (i==0) { + if (i == 0) { packed_cells.insert(u.cell->name); dff_to_fe(u.cell, root, false); ++lut_and_ff; @@ -547,8 +561,8 @@ void NgUltraPacker::pack_lut_multi_dffs(void) } } if (use_bff) { - CellInfo *new_cell = create_cell_ptr(id_BEYOND_FE, ctx->idf("%s$bff",ci.name.c_str(ctx))); - new_cell->params[id_dff_used] = Property(1,1); + CellInfo *new_cell = create_cell_ptr(id_BEYOND_FE, ctx->idf("%s$bff", ci.name.c_str(ctx))); + new_cell->params[id_dff_used] = Property(1, 1); new_cell->setParam(id_type, Property("BFF")); new_cell->connectPort(id_DI, o); root->constr_children.push_back(new_cell); @@ -557,7 +571,7 @@ void NgUltraPacker::pack_lut_multi_dffs(void) bff_only++; NetInfo *new_out = ctx->createNet(ctx->idf("%s$new", o->name.c_str(ctx))); new_cell->connectPort(id_DO, new_out); - for(auto &user : users) { + for (auto &user : users) { user.cell->connectPort(user.port, new_out); } } @@ -577,7 +591,7 @@ void NgUltraPacker::pack_lut_dffs(void) log_info("Pack LUT-DFFs...\n"); int lut_only = 0, lut_and_ff = 0; - std::vector lut_list; + std::vector lut_list; for (auto &cell : ctx->cells) { CellInfo &ci = *cell.second; if (!ci.type.in(id_NX_LUT)) @@ -622,7 +636,7 @@ void NgUltraPacker::pack_lut_dffs(void) void NgUltraPacker::pack_dffs(void) { int dff_only = 0; - std::vector dff_list; + std::vector dff_list; for (auto &cell : ctx->cells) { CellInfo &ci = *cell.second; if (!ci.type.in(id_NX_DFF, id_NX_BFF)) @@ -690,7 +704,7 @@ void NgUltraPacker::pack_iobs(void) } if (!is_npnr_iob) log_error("Port '%s' doesn't seem to have a corresponding top level IO (internal cell type mismatch)\n", - ctx->nameOf(port.first)); + ctx->nameOf(port.first)); if (top_port.cell == nullptr) { log_info("Trimming port '%s' as it is unused.\n", ctx->nameOf(port.first)); @@ -709,7 +723,7 @@ void NgUltraPacker::pack_iobs(void) ci->disconnectPort(id_O); ctx->cells.erase(port.first); } - std::vector to_update; + std::vector to_update; for (auto &cell : ctx->cells) { CellInfo &ci = *cell.second; if (!ci.type.in(id_NX_IOB_I, id_NX_IOB_O, id_NX_IOB)) @@ -733,16 +747,21 @@ void NgUltraPacker::pack_iobs(void) if (ci.getPort(id_T)) { // In case T input is used must use different types new_type = id_IOTP; - if (ci.type==id_NX_IOB_O) new_type = id_OTP; - if (ci.type==id_NX_IOB_I) new_type = id_ITP; + if (ci.type == id_NX_IOB_O) + new_type = id_OTP; + if (ci.type == id_NX_IOB_I) + new_type = id_ITP; } else { - if (ci.type==id_NX_IOB_O) new_type = id_OP; - if (ci.type==id_NX_IOB_I) new_type = id_IP; + if (ci.type == id_NX_IOB_O) + new_type = id_OP; + if (ci.type == id_NX_IOB_I) + new_type = id_IP; } ci.type = new_type; ctx->bindBel(bel, &ci, PlaceStrength::STRENGTH_LOCKED); - if (!ctx->isValidBelForCellType(new_type,bel)) - log_error("Invalid type of IO for specified location %s %s.\n", new_type.c_str(ctx), ctx->getBelType(bel).c_str(ctx)); + if (!ctx->isValidBelForCellType(new_type, bel)) + log_error("Invalid type of IO for specified location %s %s.\n", new_type.c_str(ctx), + ctx->getBelType(bel).c_str(ctx)); to_update.push_back(&ci); } int bfr_added = 0; @@ -770,17 +789,17 @@ void NgUltraPacker::pack_iobs(void) { CellInfo *iod = net_driven_by(ctx, c_net, is_dfr, id_O); - if (iod && c_net->users.entries()!=1) + if (iod && c_net->users.entries() != 1) log_error("NX_DFR '%s' can only directly drive IOB.\n", iod->name.c_str(ctx)); if (!iod) { iod = net_driven_by(ctx, c_net, is_ddfr, id_O); - if (iod && c_net->users.entries()!=1) + if (iod && c_net->users.entries() != 1) log_error("NX_DDFR '%s' can only directly drive IOB.\n", iod->name.c_str(ctx)); if (!iod) { bfr_added++; iod = create_cell_ptr(id_BFR, ctx->idf("%s$iod_cd", cell->name.c_str(ctx))); - NetInfo *new_out = ctx->createNet(ctx->idf("%s$O",iod->name.c_str(ctx))); - iod->setParam(id_iobname,str_or_default(cell->params, id_iobname, "")); + NetInfo *new_out = ctx->createNet(ctx->idf("%s$O", iod->name.c_str(ctx))); + iod->setParam(id_iobname, str_or_default(cell->params, id_iobname, "")); cell->disconnectPort(id_C); if (c_net->name == ctx->id("$PACKER_GND")) iod->setParam(id_mode, Property(0, 2)); @@ -792,11 +811,11 @@ void NgUltraPacker::pack_iobs(void) iod->setParam(id_data_inv, Property(0, 1)); } iod->connectPort(id_O, new_out); - cell->connectPort(id_C,new_out); + cell->connectPort(id_C, new_out); } else { ddfr_added++; iod->type = id_DDFR; - iod->setParam(id_iobname,str_or_default(cell->params, id_iobname, "")); + iod->setParam(id_iobname, str_or_default(cell->params, id_iobname, "")); iod->setParam(id_path, Property(2, 2)); ddfr_rewrite(iod); disconnect_unused(iod, id_O2); @@ -806,7 +825,7 @@ void NgUltraPacker::pack_iobs(void) } else { dfr_added++; iod->type = id_DFR; - iod->setParam(id_iobname,str_or_default(cell->params, id_iobname, "")); + iod->setParam(id_iobname, str_or_default(cell->params, id_iobname, "")); dff_rewrite(iod); } Loc cd_loc = cell->getLocation(); @@ -817,17 +836,17 @@ void NgUltraPacker::pack_iobs(void) NetInfo *i_net = cell->getPort(id_I); if (i_net) { CellInfo *iod = net_driven_by(ctx, i_net, is_dfr, id_O); - if (iod && i_net->users.entries()!=1) + if (iod && i_net->users.entries() != 1) log_error("NX_DFR '%s' can only directly drive IOB.\n", iod->name.c_str(ctx)); if (!iod) { iod = net_driven_by(ctx, i_net, is_ddfr, id_O); - if (iod && i_net->users.entries()!=1) + if (iod && i_net->users.entries() != 1) log_error("NX_DDFR '%s' can only directly drive IOB.\n", iod->name.c_str(ctx)); if (!iod) { bfr_added++; iod = create_cell_ptr(id_BFR, ctx->idf("%s$iod_od", cell->name.c_str(ctx))); NetInfo *new_out = ctx->createNet(ctx->idf("%s$O", iod->name.c_str(ctx))); - iod->setParam(id_iobname,str_or_default(cell->params, id_iobname, "")); + iod->setParam(id_iobname, str_or_default(cell->params, id_iobname, "")); cell->disconnectPort(id_I); if (i_net->name == ctx->id("$PACKER_GND")) iod->setParam(id_mode, Property(0, 2)); @@ -839,11 +858,11 @@ void NgUltraPacker::pack_iobs(void) iod->setParam(id_data_inv, Property(0, 1)); } iod->connectPort(id_O, new_out); - cell->connectPort(id_I,new_out); + cell->connectPort(id_I, new_out); } else { ddfr_added++; iod->type = id_DDFR; - iod->setParam(id_iobname,str_or_default(cell->params, id_iobname, "")); + iod->setParam(id_iobname, str_or_default(cell->params, id_iobname, "")); iod->setParam(id_path, Property(0, 2)); ddfr_rewrite(iod); disconnect_unused(iod, id_O2); @@ -853,7 +872,7 @@ void NgUltraPacker::pack_iobs(void) } else { dfr_added++; iod->type = id_DFR; - iod->setParam(id_iobname,str_or_default(cell->params, id_iobname, "")); + iod->setParam(id_iobname, str_or_default(cell->params, id_iobname, "")); dff_rewrite(iod); } Loc cd_loc = cell->getLocation(); @@ -865,7 +884,7 @@ void NgUltraPacker::pack_iobs(void) NetInfo *o_net = cell->getPort(id_O); if (o_net) { CellInfo *iod = net_only_drives(ctx, o_net, is_dfr, id_I, true); - if (!(o_net->users.entries()==1 && (*o_net->users.begin()).cell->type == id_NX_IOM_U)) { + if (!(o_net->users.entries() == 1 && (*o_net->users.begin()).cell->type == id_NX_IOM_U)) { bool bfr_mode = false; bool ddfr_mode = false; if (!iod) { @@ -874,19 +893,19 @@ void NgUltraPacker::pack_iobs(void) bfr_added++; iod = create_cell_ptr(id_BFR, ctx->idf("%s$iod_id", cell->name.c_str(ctx))); NetInfo *new_in = ctx->createNet(ctx->idf("%s$I", iod->name.c_str(ctx))); - iod->setParam(id_iobname,str_or_default(cell->params, id_iobname, "")); + iod->setParam(id_iobname, str_or_default(cell->params, id_iobname, "")); cell->disconnectPort(id_O); iod->connectPort(id_O, o_net); iod->setParam(id_mode, Property(2, 2)); iod->setParam(id_data_inv, Property(0, 1)); iod->connectPort(id_I, new_in); - cell->connectPort(id_O,new_in); + cell->connectPort(id_O, new_in); bfr_mode = true; } else { ddfr_mode = true; ddfr_added++; iod->type = id_DDFR; - iod->setParam(id_iobname,str_or_default(cell->params, id_iobname, "")); + iod->setParam(id_iobname, str_or_default(cell->params, id_iobname, "")); iod->setParam(id_path, Property(1, 2)); ddfr_rewrite(iod); disconnect_if_gnd(iod, id_I2); @@ -896,7 +915,7 @@ void NgUltraPacker::pack_iobs(void) } else { dfr_added++; iod->type = id_DFR; - iod->setParam(id_iobname,str_or_default(cell->params, id_iobname, "")); + iod->setParam(id_iobname, str_or_default(cell->params, id_iobname, "")); dff_rewrite(iod); } Loc cd_loc = cell->getLocation(); @@ -905,12 +924,14 @@ void NgUltraPacker::pack_iobs(void) ctx->bindBel(bel, iod, PlaceStrength::STRENGTH_LOCKED); // Depending of DDFR mode we must use one of dedicated routes (ITCs) - if (!ddfr_mode && ctx->getBelType(bel)==id_DDFR) { + if (!ddfr_mode && ctx->getBelType(bel) == id_DDFR) { WireId dwire = ctx->getBelPinWire(bel, id_O); for (PipId pip : ctx->getPipsDownhill(dwire)) { const auto &extra_data = *uarch->pip_extra_data(pip); - if (!extra_data.name) continue; - if (extra_data.type != PipExtra::PIP_EXTRA_MUX) continue; + if (!extra_data.name) + continue; + if (extra_data.type != PipExtra::PIP_EXTRA_MUX) + continue; if (bfr_mode && extra_data.input == 2) { uarch->blocked_pips.emplace(pip); } else if (!bfr_mode && extra_data.input == 1) { @@ -966,21 +987,22 @@ void NgUltraPacker::pack_ioms(void) } } -void NgUltraPacker::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 NgUltraPacker::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) { CellInfo *fe = create_cell_ptr(id_BEYOND_FE, ctx->idf("%s$%s", cy->name.c_str(ctx), in_port.c_str(ctx))); NetInfo *net = cy->getPort(in_port); 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); + fe->params[id_lut_table] = Property((net->name == ctx->id("$PACKER_GND")) ? 0x0000 : 0xffff, 16); + fe->params[id_lut_used] = Property(1, 1); cy->disconnectPort(in_port); NetInfo *new_out = ctx->createNet(ctx->idf("%s$o", fe->name.c_str(ctx))); fe->connectPort(id_LO, new_out); cy->connectPort(in_port, new_out); } else { fe->params[id_lut_table] = Property(0xaaaa, 16); - fe->params[id_lut_used] = Property(1,1); + fe->params[id_lut_used] = Property(1, 1); cy->disconnectPort(in_port); NetInfo *new_out = ctx->createNet(ctx->idf("%s$o", fe->name.c_str(ctx))); fe->connectPort(id_I1, net); @@ -999,7 +1021,7 @@ void NgUltraPacker::pack_cy_input_and_output(CellInfo *cy, IdString cluster, IdS if (net) { lut_only--; lut_and_ff++; - } else + } else dff_only++; } else { fe->timing_index = ctx->get_cell_timing_idx(id_BEYOND_FE_LUT); @@ -1041,30 +1063,30 @@ void NgUltraPacker::pack_cys(void) if (!ci_net || !ci_net->driver.cell || ci_net->driver.cell->type != id_NX_CY) { root_cys.push_back(ci); } - for (int i=1;i<=4;i++) { - connect_gnd_if_unconnected(ci, ctx->idf("A%d",i), false); - connect_gnd_if_unconnected(ci, ctx->idf("B%d",i), false); - exchange_if_constant(ci, ctx->idf("A%d",i), ctx->idf("B%d",i)); + for (int i = 1; i <= 4; i++) { + connect_gnd_if_unconnected(ci, ctx->idf("A%d", i), false); + connect_gnd_if_unconnected(ci, ctx->idf("B%d", i), false); + exchange_if_constant(ci, ctx->idf("A%d", i), ctx->idf("B%d", i)); } NetInfo *co_net = ci->getPort(id_CO); if (!co_net) { - disconnect_unused(ci,id_CO); + disconnect_unused(ci, id_CO); // Disconnect unused ports on last CY in chain // at least id_A1 and id_B1 will be connected // Reverse direction, must stop if used, then // rest is used as well if (!ci->getPort(id_S4)) { - disconnect_unused(ci,id_S4); - disconnect_unused(ci,id_A4); - disconnect_unused(ci,id_B4); + disconnect_unused(ci, id_S4); + disconnect_unused(ci, id_A4); + disconnect_unused(ci, id_B4); if (!ci->getPort(id_S3)) { - disconnect_unused(ci,id_S3); - disconnect_unused(ci,id_A3); - disconnect_unused(ci,id_B3); + disconnect_unused(ci, id_S3); + disconnect_unused(ci, id_A3); + disconnect_unused(ci, id_B3); if (!ci->getPort(id_S2)) { - disconnect_unused(ci,id_S2); - disconnect_unused(ci,id_A2); - disconnect_unused(ci,id_B2); + disconnect_unused(ci, id_S2); + disconnect_unused(ci, id_A2); + disconnect_unused(ci, id_B2); }; } } @@ -1081,13 +1103,14 @@ void NgUltraPacker::pack_cys(void) if (co_net && co_net->users.entries() > 0) { cy = (*co_net->users.begin()).cell; if (cy->type != id_NX_CY || co_net->users.entries() != 1) { - log_warning("Cells %s CO output connected to:\n",group.back()->name.c_str(ctx)); - for(auto user : co_net->users) - log_warning("\t%s of type %s\n",user.cell->name.c_str(ctx), user.cell->type.c_str(ctx)); + log_warning("Cells %s CO output connected to:\n", group.back()->name.c_str(ctx)); + for (auto user : co_net->users) + log_warning("\t%s of type %s\n", user.cell->name.c_str(ctx), user.cell->type.c_str(ctx)); log_error("NX_CY can only be chained with one other NX_CY cell\n"); } group.push_back(cy); - } else break; + } else + break; } groups.push_back(group); } @@ -1136,41 +1159,43 @@ void NgUltraPacker::pack_cys(void) flush_cells(); } - -void NgUltraPacker::pack_xrf_input_and_output(CellInfo *xrf, IdString cluster, IdString in_port, IdString out_port, ClusterPlacement placement, int &lut_only, int &lut_and_ff, int &dff_only) +void NgUltraPacker::pack_xrf_input_and_output(CellInfo *xrf, IdString cluster, IdString in_port, IdString out_port, + ClusterPlacement placement, 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_out && net_out->users.entries()==0) { + if (net_out && net_out->users.entries() == 0) { xrf->disconnectPort(out_port); net_out = nullptr; } } - if (!net && !net_out) return; + if (!net && !net_out) + return; IdString name = in_port; - if (name == IdString()) name = out_port; + if (name == IdString()) + name = out_port; CellInfo *fe = create_cell_ptr(id_BEYOND_FE, ctx->idf("%s$%s", xrf->name.c_str(ctx), name.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); + 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->idf("%s$o", fe->name.c_str(ctx))); 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 && 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); + fe->params[id_lut_used] = Property(1, 1); xrf->disconnectPort(in_port); NetInfo *new_out = ctx->createNet(ctx->idf("%s$o", fe->name.c_str(ctx))); fe->connectPort(id_I1, net); @@ -1190,7 +1215,7 @@ void NgUltraPacker::pack_xrf_input_and_output(CellInfo *xrf, IdString cluster, I if (net) { lut_only--; lut_and_ff++; - } else + } else dff_only++; } } @@ -1205,7 +1230,7 @@ void NgUltraPacker::disconnect_unused(CellInfo *cell, IdString port) if (net) { // NanoXplore tools usually connects 0 to unused port, no need to warn // Sometimes there is unused nets, so number of entries is zero - if (net->users.entries()!=0 && !net->name.in(ctx->id("$PACKER_GND"))) + if (net->users.entries() != 0 && !net->name.in(ctx->id("$PACKER_GND"))) log_warning("Disconnected unused port '%s' from cell '%s'.\n", port.c_str(ctx), cell->name.c_str(ctx)); cell->disconnectPort(port); } @@ -1220,61 +1245,74 @@ void NgUltraPacker::pack_rfs(void) if (!ci.type.in(id_NX_RFB_U)) continue; int mode = int_or_default(ci.params, id_mode, 0); - switch(mode) { - case 0 : ci.type = id_RF; break; - case 1 : ci.type = id_RFSP; break; - case 2 : ci.type = id_XHRF; break; - case 3 : ci.type = id_XWRF; break; - case 4 : ci.type = id_XPRF; break; - default: - log_error("Unknown mode %d for cell '%s'.\n", mode, ci.name.c_str(ctx)); - } + switch (mode) { + case 0: + ci.type = id_RF; + break; + case 1: + ci.type = id_RFSP; + break; + case 2: + ci.type = id_XHRF; + break; + case 3: + ci.type = id_XWRF; + break; + case 4: + ci.type = id_XPRF; + break; + default: + log_error("Unknown mode %d for cell '%s'.\n", mode, ci.name.c_str(ctx)); + } ci.cluster = ci.name; bind_attr_loc(&ci, &ci.attrs); for (int i = 1; i <= 18; i++) { - connect_gnd_if_unconnected(&ci, ctx->idf("I%d",i)); - pack_xrf_input_and_output(&ci, ci.name, ctx->idf("I%d",i), ctx->idf("O%d",i), ClusterPlacement(PLACE_XRF_I1 + i-1), lut_only, lut_and_ff, dff_only); + connect_gnd_if_unconnected(&ci, ctx->idf("I%d", i)); + pack_xrf_input_and_output(&ci, ci.name, ctx->idf("I%d", i), ctx->idf("O%d", i), + ClusterPlacement(PLACE_XRF_I1 + i - 1), lut_only, lut_and_ff, dff_only); } - if (mode!=1) { + if (mode != 1) { for (int i = 1; i <= 5; i++) { - connect_gnd_if_unconnected(&ci, ctx->idf("RA%d",i)); - pack_xrf_input_and_output(&ci, ci.name, ctx->idf("RA%d",i), IdString(), ClusterPlacement(PLACE_XRF_RA1 + i-1), lut_only, lut_and_ff, dff_only); + connect_gnd_if_unconnected(&ci, ctx->idf("RA%d", i)); + pack_xrf_input_and_output(&ci, ci.name, ctx->idf("RA%d", i), IdString(), + ClusterPlacement(PLACE_XRF_RA1 + i - 1), lut_only, lut_and_ff, dff_only); } } else { // SPREG mode does not use RA inputs for (int i = 1; i <= 5; i++) - disconnect_unused(&ci, ctx->idf("RA%d",i)); + disconnect_unused(&ci, ctx->idf("RA%d", i)); } - - if (mode==2 || mode==4) { + + if (mode == 2 || mode == 4) { connect_gnd_if_unconnected(&ci, id_RA6); pack_xrf_input_and_output(&ci, ci.name, id_RA6, IdString(), PLACE_XRF_RA6, lut_only, lut_and_ff, dff_only); } else { - disconnect_unused(&ci,id_RA6); + disconnect_unused(&ci, id_RA6); } - if (mode==4) { + if (mode == 4) { for (int i = 7; i <= 10; i++) { - connect_gnd_if_unconnected(&ci, ctx->idf("RA%d",i)); - pack_xrf_input_and_output(&ci, ci.name, ctx->idf("RA%d",i), IdString(), ClusterPlacement(PLACE_XRF_RA1 + i-1), lut_only, lut_and_ff, dff_only); + connect_gnd_if_unconnected(&ci, ctx->idf("RA%d", i)); + pack_xrf_input_and_output(&ci, ci.name, ctx->idf("RA%d", i), IdString(), + ClusterPlacement(PLACE_XRF_RA1 + i - 1), lut_only, lut_and_ff, dff_only); } } else { for (int i = 7; i <= 10; i++) - disconnect_unused(&ci, ctx->idf("RA%d",i)); + disconnect_unused(&ci, ctx->idf("RA%d", i)); } - for (int i = 1; i <= 5; i++) { - connect_gnd_if_unconnected(&ci, ctx->idf("WA%d",i)); - pack_xrf_input_and_output(&ci, ci.name, ctx->idf("WA%d",i), IdString(), ClusterPlacement(PLACE_XRF_WA1 + i-1), lut_only, lut_and_ff, dff_only); + connect_gnd_if_unconnected(&ci, ctx->idf("WA%d", i)); + pack_xrf_input_and_output(&ci, ci.name, ctx->idf("WA%d", i), IdString(), + ClusterPlacement(PLACE_XRF_WA1 + i - 1), lut_only, lut_and_ff, dff_only); } - - if (mode==2) { + + if (mode == 2) { connect_gnd_if_unconnected(&ci, id_WA6); pack_xrf_input_and_output(&ci, ci.name, id_WA6, IdString(), PLACE_XRF_WA6, lut_only, lut_and_ff, dff_only); } else { - disconnect_unused(&ci,id_WA6); + disconnect_unused(&ci, id_WA6); } connect_gnd_if_unconnected(&ci, id_WE); @@ -1285,18 +1323,20 @@ void NgUltraPacker::pack_rfs(void) if (mode == 3) { for (int i = 19; i <= 36; i++) { - connect_gnd_if_unconnected(&ci, ctx->idf("I%d",i)); - pack_xrf_input_and_output(&ci, ci.name, ctx->idf("I%d",i), ctx->idf("O%d",i), ClusterPlacement(PLACE_XRF_I1 + i-1), lut_only, lut_and_ff, dff_only); + connect_gnd_if_unconnected(&ci, ctx->idf("I%d", i)); + pack_xrf_input_and_output(&ci, ci.name, ctx->idf("I%d", i), ctx->idf("O%d", i), + ClusterPlacement(PLACE_XRF_I1 + i - 1), lut_only, lut_and_ff, dff_only); } } else if (mode == 4) { for (int i = 19; i <= 36; i++) { - disconnect_unused(&ci,ctx->idf("I%d",i)); - pack_xrf_input_and_output(&ci, ci.name, IdString(), ctx->idf("O%d",i), ClusterPlacement(PLACE_XRF_I1 + i-1), lut_only, lut_and_ff, dff_only); + disconnect_unused(&ci, ctx->idf("I%d", i)); + pack_xrf_input_and_output(&ci, ci.name, IdString(), ctx->idf("O%d", i), + ClusterPlacement(PLACE_XRF_I1 + i - 1), lut_only, lut_and_ff, dff_only); } } else { for (int i = 19; i <= 36; i++) { - disconnect_unused(&ci,ctx->idf("I%d",i)); - disconnect_unused(&ci,ctx->idf("O%d",i)); + disconnect_unused(&ci, ctx->idf("I%d", i)); + disconnect_unused(&ci, ctx->idf("O%d", i)); } } @@ -1333,41 +1373,57 @@ void NgUltraPacker::pack_cdcs(void) if (!ci.type.in(id_NX_CDC_U)) continue; int mode = int_or_default(ci.params, 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)); - } + 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); + 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)); + 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); + 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)); + 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)); } } @@ -1381,9 +1437,11 @@ void NgUltraPacker::pack_cdcs(void) 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); + 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); + 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); @@ -1392,9 +1450,11 @@ void NgUltraPacker::pack_cdcs(void) 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); + 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); + 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 @@ -1402,8 +1462,8 @@ void NgUltraPacker::pack_cdcs(void) 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, ctx->idf("CI%d", i)); + disconnect_unused(&ci, ctx->idf("CO%d", i)); } disconnect_unused(&ci, id_CSRSTI); disconnect_unused(&ci, id_CSRSTO); @@ -1411,20 +1471,24 @@ void NgUltraPacker::pack_cdcs(void) 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, 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); + 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); + 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); + 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); + 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) @@ -1445,23 +1509,29 @@ void NgUltraPacker::pack_fifos(void) if (!ci.type.in(id_NX_FIFO_U)) continue; int mode = int_or_default(ci.params, 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)); - } + 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; bool use_write_arst = bool_or_default(ci.params, id_use_write_arst, false); bool use_read_arst = bool_or_default(ci.params, id_use_read_arst, false); int rsti = (ci.type == id_FIFO) ? 2 : 4; - for (int i=1;i<=rsti;i++) { - IdString port = ctx->idf("WRSTI%d",i); + for (int i = 1; i <= rsti; i++) { + IdString port = ctx->idf("WRSTI%d", i); ci.ports[port].name = port; ci.ports[port].type = PORT_IN; - port = ctx->idf("RRSTI%d",i); + port = ctx->idf("RRSTI%d", i); ci.ports[port].name = port; ci.ports[port].type = PORT_IN; } @@ -1471,61 +1541,75 @@ void NgUltraPacker::pack_fifos(void) connect_gnd_if_unconnected(&ci, port); NetInfo *wrsti_net = ci.getPort(port); ci.disconnectPort(port); - for (int i=1;i<=rsti;i++) - ci.connectPort(ctx->idf("WRSTI%d",i), wrsti_net); - if (mode!=0) disconnect_unused(&ci, id_WRSTO); - pack_xrf_input_and_output(&ci, ci.name, id_WRSTI1, id_WRSTO, PLACE_FIFO_WRSTI1, lut_only, lut_and_ff, dff_only); - pack_xrf_input_and_output(&ci, ci.name, id_WRSTI2, IdString(), PLACE_FIFO_WRSTI2, lut_only, lut_and_ff, dff_only); + for (int i = 1; i <= rsti; i++) + ci.connectPort(ctx->idf("WRSTI%d", i), wrsti_net); + if (mode != 0) + disconnect_unused(&ci, id_WRSTO); + pack_xrf_input_and_output(&ci, ci.name, id_WRSTI1, id_WRSTO, PLACE_FIFO_WRSTI1, lut_only, lut_and_ff, + dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_WRSTI2, IdString(), PLACE_FIFO_WRSTI2, lut_only, lut_and_ff, + dff_only); if (mode != 0) { - pack_xrf_input_and_output(&ci, ci.name, id_WRSTI3, IdString(), PLACE_FIFO_WRSTI3, lut_only, lut_and_ff, dff_only); - pack_xrf_input_and_output(&ci, ci.name, id_WRSTI4, IdString(), PLACE_FIFO_WRSTI4, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_WRSTI3, IdString(), PLACE_FIFO_WRSTI3, lut_only, lut_and_ff, + dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_WRSTI4, IdString(), PLACE_FIFO_WRSTI4, lut_only, lut_and_ff, + dff_only); } } else { - disconnect_unused(&ci,id_WRSTI); + disconnect_unused(&ci, id_WRSTI); } if (use_read_arst) { IdString port = id_RRSTI; connect_gnd_if_unconnected(&ci, port); NetInfo *rrsti_net = ci.getPort(port); ci.disconnectPort(port); - for (int i=1;i<=rsti;i++) - ci.connectPort(ctx->idf("RRSTI%d",i), rrsti_net); - if (mode!=0) disconnect_unused(&ci, id_RRSTO); - pack_xrf_input_and_output(&ci, ci.name, id_RRSTI1, id_RRSTO, PLACE_FIFO_RRSTI1, lut_only, lut_and_ff, dff_only); - pack_xrf_input_and_output(&ci, ci.name, id_RRSTI2, IdString(), PLACE_FIFO_RRSTI2, lut_only, lut_and_ff, dff_only); + for (int i = 1; i <= rsti; i++) + ci.connectPort(ctx->idf("RRSTI%d", i), rrsti_net); + if (mode != 0) + disconnect_unused(&ci, id_RRSTO); + pack_xrf_input_and_output(&ci, ci.name, id_RRSTI1, id_RRSTO, PLACE_FIFO_RRSTI1, lut_only, lut_and_ff, + dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_RRSTI2, IdString(), PLACE_FIFO_RRSTI2, lut_only, lut_and_ff, + dff_only); if (mode != 0) { - pack_xrf_input_and_output(&ci, ci.name, id_RRSTI3, IdString(), PLACE_FIFO_RRSTI3, lut_only, lut_and_ff, dff_only); - pack_xrf_input_and_output(&ci, ci.name, id_RRSTI4, IdString(), PLACE_FIFO_RRSTI4, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_RRSTI3, IdString(), PLACE_FIFO_RRSTI3, lut_only, lut_and_ff, + dff_only); + pack_xrf_input_and_output(&ci, ci.name, id_RRSTI4, IdString(), PLACE_FIFO_RRSTI4, lut_only, lut_and_ff, + dff_only); } } else { - disconnect_unused(&ci,id_RRSTI); + disconnect_unused(&ci, id_RRSTI); } for (int i = 1; i <= 18; i++) { - connect_gnd_if_unconnected(&ci, ctx->idf("I%d",i)); - pack_xrf_input_and_output(&ci, ci.name, ctx->idf("I%d",i), ctx->idf("O%d",i), ClusterPlacement(PLACE_FIFO_I1 + i-1), lut_only, lut_and_ff, dff_only); + connect_gnd_if_unconnected(&ci, ctx->idf("I%d", i)); + pack_xrf_input_and_output(&ci, ci.name, ctx->idf("I%d", i), ctx->idf("O%d", i), + ClusterPlacement(PLACE_FIFO_I1 + i - 1), lut_only, lut_and_ff, dff_only); } - if (mode==0) { + if (mode == 0) { for (int i = 19; i <= 36; i++) { - disconnect_unused(&ci,ctx->idf("I%d",i)); - disconnect_unused(&ci,ctx->idf("O%d",i)); + disconnect_unused(&ci, ctx->idf("I%d", i)); + disconnect_unused(&ci, ctx->idf("O%d", i)); } } else { for (int i = 19; i <= 36; i++) { - connect_gnd_if_unconnected(&ci, ctx->idf("I%d",i)); - pack_xrf_input_and_output(&ci, ci.name, ctx->idf("I%d",i), ctx->idf("O%d",i), ClusterPlacement(PLACE_FIFO_I1 + i-1), lut_only, lut_and_ff, dff_only); + connect_gnd_if_unconnected(&ci, ctx->idf("I%d", i)); + pack_xrf_input_and_output(&ci, ci.name, ctx->idf("I%d", i), ctx->idf("O%d", i), + ClusterPlacement(PLACE_FIFO_I1 + i - 1), lut_only, lut_and_ff, dff_only); } } for (int i = 1; i <= 6; i++) { - connect_gnd_if_unconnected(&ci, ctx->idf("RAI%d",i)); - pack_xrf_input_and_output(&ci, ci.name, ctx->idf("RAI%d",i), ctx->idf("RAO%d",i), ClusterPlacement(PLACE_FIFO_RAI1 + i-1), lut_only, lut_and_ff, dff_only); + connect_gnd_if_unconnected(&ci, ctx->idf("RAI%d", i)); + pack_xrf_input_and_output(&ci, ci.name, ctx->idf("RAI%d", i), ctx->idf("RAO%d", i), + ClusterPlacement(PLACE_FIFO_RAI1 + i - 1), lut_only, lut_and_ff, dff_only); - connect_gnd_if_unconnected(&ci, ctx->idf("WAI%d",i)); - pack_xrf_input_and_output(&ci, ci.name, ctx->idf("WAI%d",i), ctx->idf("WAO%d",i), ClusterPlacement(PLACE_FIFO_WAI1 + i-1), lut_only, lut_and_ff, dff_only); + connect_gnd_if_unconnected(&ci, ctx->idf("WAI%d", i)); + pack_xrf_input_and_output(&ci, ci.name, ctx->idf("WAI%d", i), ctx->idf("WAO%d", i), + ClusterPlacement(PLACE_FIFO_WAI1 + i - 1), lut_only, lut_and_ff, dff_only); } - if (mode==0) { + if (mode == 0) { disconnect_unused(&ci, id_RAI7); disconnect_unused(&ci, id_WAI7); } else { @@ -1542,20 +1626,26 @@ void NgUltraPacker::pack_fifos(void) disconnect_if_gnd(&ci, id_WEA); pack_xrf_input_and_output(&ci, ci.name, id_WEA, IdString(), PLACE_FIFO_WEA, lut_only, lut_and_ff, dff_only); - if (mode==0) { + if (mode == 0) { // FIFO ci.renamePort(id_WEQ1, id_WEQ); - pack_xrf_input_and_output(&ci, ci.name, IdString(), id_WEQ, PLACE_FIFO_WEQ1, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, IdString(), id_WEQ, PLACE_FIFO_WEQ1, lut_only, lut_and_ff, + dff_only); disconnect_unused(&ci, id_WEQ2); ci.renamePort(id_REQ1, id_REQ); - pack_xrf_input_and_output(&ci, ci.name, IdString(), id_REQ, PLACE_FIFO_REQ1, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, IdString(), id_REQ, PLACE_FIFO_REQ1, lut_only, lut_and_ff, + dff_only); disconnect_unused(&ci, id_REQ2); } else { - pack_xrf_input_and_output(&ci, ci.name, IdString(), id_WEQ1, PLACE_FIFO_WEQ1, lut_only, lut_and_ff, dff_only); - pack_xrf_input_and_output(&ci, ci.name, IdString(), id_WEQ2, PLACE_FIFO_WEQ2, lut_only, lut_and_ff, dff_only); - pack_xrf_input_and_output(&ci, ci.name, IdString(), id_WEQ1, PLACE_FIFO_REQ1, lut_only, lut_and_ff, dff_only); - pack_xrf_input_and_output(&ci, ci.name, IdString(), id_WEQ2, PLACE_FIFO_REQ2, lut_only, lut_and_ff, dff_only); + pack_xrf_input_and_output(&ci, ci.name, IdString(), id_WEQ1, PLACE_FIFO_WEQ1, lut_only, lut_and_ff, + dff_only); + pack_xrf_input_and_output(&ci, ci.name, IdString(), id_WEQ2, PLACE_FIFO_WEQ2, lut_only, lut_and_ff, + dff_only); + pack_xrf_input_and_output(&ci, ci.name, IdString(), id_WEQ1, PLACE_FIFO_REQ1, lut_only, lut_and_ff, + dff_only); + pack_xrf_input_and_output(&ci, ci.name, IdString(), id_WEQ2, PLACE_FIFO_REQ2, lut_only, lut_and_ff, + dff_only); // XFIFO ci.ports[id_WCK1].name = id_WCK1; @@ -1581,7 +1671,6 @@ void NgUltraPacker::pack_fifos(void) ci.connectPort(id_RCK2, net); } } - } if (lut_only) log_info(" %6d FEs used as LUT only\n", lut_only); @@ -1606,10 +1695,11 @@ void NgUltraPacker::insert_ioms() Loc iotp_loc = ni->driver.cell->getLocation(); iotp_loc.z -= 1; BelId bel = ctx->getBelByLocation(iotp_loc); - if (uarch->global_capable_bels.count(bel)==0) + if (uarch->global_capable_bels.count(bel) == 0) continue; for (const auto &usr : ni->users) { - if (uarch->is_fabric_lowskew_sink(usr) || uarch->is_ring_clock_sink(usr) || uarch->is_tube_clock_sink(usr) || uarch->is_ring_over_tile_clock_sink(usr)) { + if (uarch->is_fabric_lowskew_sink(usr) || uarch->is_ring_clock_sink(usr) || + uarch->is_tube_clock_sink(usr) || uarch->is_ring_over_tile_clock_sink(usr)) { pins_needing_iom.emplace_back(ni->name); break; } @@ -1646,9 +1736,9 @@ void NgUltraPacker::insert_ioms() IdString port = usr.port; usr.cell->disconnectPort(port); usr.cell->connectPort(port, iom_to_clk); - } + } iom->connectPort(port, input_pad->getPort(id_O)); - iom->connectPort((port==id_P17RI) ? id_CKO1 : id_CKO2, iom_to_clk); + iom->connectPort((port == id_P17RI) ? id_CKO1 : id_CKO2, iom_to_clk); if (ctx->checkBelAvail(bel)) ctx->bindBel(bel, iom, PlaceStrength::STRENGTH_LOCKED); CellInfo *bfr = net->driver.cell; @@ -1693,50 +1783,65 @@ void NgUltraPacker::insert_wfbs() void NgUltraPacker::mandatory_param(CellInfo *cell, IdString param) { if (!cell->params.count(param)) - log_error("Mandatory parameter '%s' of cell '%s'(%s) is missing.\n", param.c_str(ctx), cell->name.c_str(ctx), cell->type.c_str(ctx)); + log_error("Mandatory parameter '%s' of cell '%s'(%s) is missing.\n", param.c_str(ctx), cell->name.c_str(ctx), + cell->type.c_str(ctx)); } int NgUltraPacker::memory_width(int config, bool ecc) { if (ecc) { - if (config==4) - return 18; + if (config == 4) + return 18; else log_error("ECC mode only support width of 18.\n"); } else { - switch(config) - { - case 0: return 1; // NOECC_48kx1 - case 1: return 2; // NOECC_24kx2 - case 2: return 4; // NOECC_12kx4 - case 3: return 8; // NOECC_6kx8 - case 4: return 12; // NOECC_4kx12 - case 5: return 24; // NOECC_2kx24 - case 6: return 3; // NOECC_16kx3 - case 7: return 6; // NOECC_8kx6 + switch (config) { + case 0: + return 1; // NOECC_48kx1 + case 1: + return 2; // NOECC_24kx2 + case 2: + return 4; // NOECC_12kx4 + case 3: + return 8; // NOECC_6kx8 + case 4: + return 12; // NOECC_4kx12 + case 5: + return 24; // NOECC_2kx24 + case 6: + return 3; // NOECC_16kx3 + case 7: + return 6; // NOECC_8kx6 } log_error("Unknown memory configuration width config '%d'.\n", config); } } -int NgUltraPacker::memory_addr_bits(int config,bool ecc) +int NgUltraPacker::memory_addr_bits(int config, bool ecc) { if (ecc) { - if (config==4) - return 11; + if (config == 4) + return 11; else log_error("ECC mode only support width of 18.\n"); } else { - switch(config) - { - case 0: return 16; // NOECC_48kx1 - case 1: return 15; // NOECC_24kx2 - case 2: return 14; // NOECC_12kx4 - case 3: return 13; // NOECC_6kx8 - case 4: return 12; // NOECC_4kx12 - case 5: return 11; // NOECC_2kx24 - case 6: return 14; // NOECC_16kx3 - case 7: return 13; // NOECC_8kx6 + switch (config) { + case 0: + return 16; // NOECC_48kx1 + case 1: + return 15; // NOECC_24kx2 + case 2: + return 14; // NOECC_12kx4 + case 3: + return 13; // NOECC_6kx8 + case 4: + return 12; // NOECC_4kx12 + case 5: + return 11; // NOECC_2kx24 + case 6: + return 14; // NOECC_16kx3 + case 7: + return 13; // NOECC_8kx6 } log_error("Unknown memory configuration width config '%d'.\n", config); } @@ -1745,20 +1850,24 @@ int NgUltraPacker::memory_addr_bits(int config,bool ecc) void NgUltraPacker::insert_wfb(CellInfo *cell, IdString port) { NetInfo *net = cell->getPort(port); - if (!net) return; + if (!net) + return; CellInfo *wfg = net_only_drives(ctx, net, is_wfg, id_ZI, true); - if (wfg) return; + if (wfg) + return; bool in_fabric = false; bool in_ring = false; for (const auto &usr : net->users) { - if (uarch->is_fabric_lowskew_sink(usr) || uarch->is_tube_clock_sink(usr) || uarch->is_ring_over_tile_clock_sink(usr)) + if (uarch->is_fabric_lowskew_sink(usr) || uarch->is_tube_clock_sink(usr) || + uarch->is_ring_over_tile_clock_sink(usr)) in_fabric = true; else in_ring = true; } // If all in ring and none in fabric no need for WFB - if (in_ring && !in_fabric) return; + if (in_ring && !in_fabric) + return; log_info(" Inserting WFB for cell '%s' port '%s'\n", cell->name.c_str(ctx), port.c_str(ctx)); CellInfo *wfb = create_cell_ptr(id_WFB, ctx->idf("%s$%s", cell->name.c_str(ctx), port.c_str(ctx))); if (in_ring && in_fabric) { @@ -1788,11 +1897,12 @@ void NgUltraPacker::constrain_location(CellInfo *cell) if (!location.empty()) { if (uarch->locations.count(location)) { BelId bel = uarch->locations[location]; - if (ctx->getBelType(bel)!= cell->type) { + if (ctx->getBelType(bel) != cell->type) { log_error("Location '%s' is wrong for bel type '%s'.\n", location.c_str(), cell->type.c_str(ctx)); } if (ctx->checkBelAvail(bel)) { - log_info(" Constraining %s '%s' to '%s'\n", cell->type.c_str(ctx), cell->name.c_str(ctx), location.c_str()); + log_info(" Constraining %s '%s' to '%s'\n", cell->type.c_str(ctx), cell->name.c_str(ctx), + location.c_str()); ctx->bindBel(bel, cell, PlaceStrength::STRENGTH_LOCKED); } else { log_error("Bel at location '%s' is already used by other cell.\n", location.c_str()); @@ -1856,9 +1966,8 @@ void NgUltraPacker::pack_wfgs(void) if (!zi || !zi->driver.cell) log_error("WFG port ZI of '%s' must be driven.\n", ci.name.c_str(ctx)); NetInfo *zo = ci.getPort(id_ZO); - if (!zo || zo->users.entries()==0) + if (!zo || zo->users.entries() == 0) log_error("WFG port ZO of '%s' must be connected.\n", ci.name.c_str(ctx)); - } } @@ -1881,7 +1990,8 @@ void NgUltraPacker::pack_gcks(void) disconnect_unused(&ci, id_SI2); } else if (mode == "MUX") { // all used - } else log_error("Unknown mode '%s' for cell '%s'.\n", mode.c_str(), ci.name.c_str(ctx)); + } else + log_error("Unknown mode '%s' for cell '%s'.\n", mode.c_str(), ci.name.c_str(ctx)); if (net_driven_by(ctx, ci.getPort(id_SI1), is_gck, id_SO) || net_driven_by(ctx, ci.getPort(id_SI2), is_gck, id_SO) || @@ -1909,57 +2019,56 @@ void NgUltraPacker::pack_rams(void) ci.disconnectPort(id_BCKR); mandatory_param(&ci, id_raw_config0); mandatory_param(&ci, id_raw_config1); - Property extr = ci.params[id_raw_config1].extract(0, 16); + Property extr = ci.params[id_raw_config1].extract(0, 16); std::vector bits = extr.as_bits(); - //int ecc_mode = (bits[12] ? 1 : 0) | (bits[13] ? 2 : 0) | (bits[14] ? 4 : 0) | (bits[15] ? 8 : 0); + // int ecc_mode = (bits[12] ? 1 : 0) | (bits[13] ? 2 : 0) | (bits[14] ? 4 : 0) | (bits[15] ? 8 : 0); bool ecc = bits[12]; - //int a_in_width = memory_width((bits[0] ? 1 : 0) | (bits[1] ? 2 : 0) | (bits[2] ? 4 : 0), ecc); - //int b_in_width = memory_width((bits[3] ? 1 : 0) | (bits[4] ? 2 : 0) | (bits[5] ? 4 : 0), ecc); + // int a_in_width = memory_width((bits[0] ? 1 : 0) | (bits[1] ? 2 : 0) | (bits[2] ? 4 : 0), ecc); + // int b_in_width = memory_width((bits[3] ? 1 : 0) | (bits[4] ? 2 : 0) | (bits[5] ? 4 : 0), ecc); int a_out_width = memory_width((bits[6] ? 1 : 0) | (bits[7] ? 2 : 0) | (bits[8] ? 4 : 0), ecc); int b_out_width = memory_width((bits[9] ? 1 : 0) | (bits[10] ? 2 : 0) | (bits[11] ? 4 : 0), ecc); - int a_addr = std::max(memory_addr_bits((bits[0] ? 1 : 0) | (bits[1] ? 2 : 0) | (bits[2] ? 4 : 0), ecc) , - memory_addr_bits((bits[6] ? 1 : 0) | (bits[7] ? 2 : 0) | (bits[8] ? 4 : 0), ecc)); - int b_addr = std::max(memory_addr_bits((bits[3] ? 1 : 0) | (bits[4] ? 2 : 0) | (bits[5] ? 4 : 0), ecc) , - memory_addr_bits((bits[9] ? 1 : 0) | (bits[10] ? 2 : 0) | (bits[11] ? 4 : 0), ecc)); - + int a_addr = std::max(memory_addr_bits((bits[0] ? 1 : 0) | (bits[1] ? 2 : 0) | (bits[2] ? 4 : 0), ecc), + memory_addr_bits((bits[6] ? 1 : 0) | (bits[7] ? 2 : 0) | (bits[8] ? 4 : 0), ecc)); + int b_addr = std::max(memory_addr_bits((bits[3] ? 1 : 0) | (bits[4] ? 2 : 0) | (bits[5] ? 4 : 0), ecc), + memory_addr_bits((bits[9] ? 1 : 0) | (bits[10] ? 2 : 0) | (bits[11] ? 4 : 0), ecc)); NetInfo *a_cs = ci.getPort(id_ACS); if (!a_cs || a_cs->name.in(ctx->id("$PACKER_GND"))) { // If there is no chip-select disconnect all disconnect_unused(&ci, id_ACK); - for(int i=0;i<24;i++) { - disconnect_unused(&ci, ctx->idf("AI%d",i+1)); - disconnect_unused(&ci, ctx->idf("AO%d",i+1)); + for (int i = 0; i < 24; i++) { + disconnect_unused(&ci, ctx->idf("AI%d", i + 1)); + disconnect_unused(&ci, ctx->idf("AO%d", i + 1)); } - for(int i=0;i<16;i++) - disconnect_unused(&ci, ctx->idf("AA%d",i+1)); + for (int i = 0; i < 16; i++) + disconnect_unused(&ci, ctx->idf("AA%d", i + 1)); } else { - for(int i=a_out_width;i<24;i++) - disconnect_unused(&ci, ctx->idf("AO%d",i+1)); - for(int i=a_addr;i<16;i++) - disconnect_unused(&ci, ctx->idf("AA%d",i+1)); + for (int i = a_out_width; i < 24; i++) + disconnect_unused(&ci, ctx->idf("AO%d", i + 1)); + for (int i = a_addr; i < 16; i++) + disconnect_unused(&ci, ctx->idf("AA%d", i + 1)); } NetInfo *b_cs = ci.getPort(id_BCS); if (!b_cs || b_cs->name.in(ctx->id("$PACKER_GND"))) { // If there is no chip-select disconnect all disconnect_unused(&ci, id_BCK); - for(int i=0;i<24;i++) { - disconnect_unused(&ci, ctx->idf("BI%d",i+1)); - disconnect_unused(&ci, ctx->idf("BO%d",i+1)); + for (int i = 0; i < 24; i++) { + disconnect_unused(&ci, ctx->idf("BI%d", i + 1)); + disconnect_unused(&ci, ctx->idf("BO%d", i + 1)); } - for(int i=0;i<16;i++) - disconnect_unused(&ci, ctx->idf("BA%d",i+1)); + for (int i = 0; i < 16; i++) + disconnect_unused(&ci, ctx->idf("BA%d", i + 1)); } else { - for(int i=b_out_width;i<24;i++) - disconnect_unused(&ci, ctx->idf("BO%d",i+1)); - for(int i=b_addr;i<16;i++) - disconnect_unused(&ci, ctx->idf("BA%d",i+1)); + for (int i = b_out_width; i < 24; i++) + disconnect_unused(&ci, ctx->idf("BO%d", i + 1)); + for (int i = b_addr; i < 16; i++) + disconnect_unused(&ci, ctx->idf("BA%d", i + 1)); } for (auto &p : ci.ports) { - if (p.second.type == PortType::PORT_IN) + if (p.second.type == PortType::PORT_IN) disconnect_if_gnd(&ci, p.first); } } @@ -1980,7 +2089,7 @@ void NgUltraPacker::dsp_same_driver(IdString port, CellInfo *cell, CellInfo **ta void NgUltraPacker::dsp_same_sink(IdString port, CellInfo *cell, CellInfo **target) { if (cell->getPort(port)) { - if (cell->getPort(port)->users.entries()!=1) + if (cell->getPort(port)->users.entries() != 1) log_error("Port '%s' of '%s' can only drive one DSP.\n", port.c_str(ctx), cell->name.c_str(ctx)); CellInfo *driver = (*cell->getPort(port)->users.begin()).cell; if (!driver->type.in(id_DSP, id_NX_DSP_U)) @@ -1994,7 +2103,7 @@ void NgUltraPacker::dsp_same_sink(IdString port, CellInfo *cell, CellInfo **targ void NgUltraPacker::pack_dsps(void) { log_info("Packing DSPs..\n"); - dict dsp_output; + dict dsp_output; std::vector root_dsps; for (auto &cell : ctx->cells) { CellInfo &ci = *cell.second; @@ -2008,40 +2117,42 @@ void NgUltraPacker::pack_dsps(void) mandatory_param(&ci, id_raw_config3); for (auto &p : ci.ports) { - if (p.second.type == PortType::PORT_IN) + if (p.second.type == PortType::PORT_IN) disconnect_if_gnd(&ci, p.first); } // CAI1-24, CBI1-18, CZI1..56 and CCI must be from same DSP CellInfo *dsp = nullptr; - for(int i=1;i<=24;i++) - dsp_same_driver(ctx->idf("CAI%d",i), &ci, &dsp); - for(int i=1;i<=18;i++) - dsp_same_driver(ctx->idf("CBI%d",i), &ci, &dsp); - for(int i=1;i<=56;i++) - dsp_same_driver(ctx->idf("CZI%d",i), &ci, &dsp); + for (int i = 1; i <= 24; i++) + dsp_same_driver(ctx->idf("CAI%d", i), &ci, &dsp); + for (int i = 1; i <= 18; i++) + dsp_same_driver(ctx->idf("CBI%d", i), &ci, &dsp); + for (int i = 1; i <= 56; i++) + dsp_same_driver(ctx->idf("CZI%d", i), &ci, &dsp); dsp_same_driver(id_CCI, &ci, &dsp); if (!dsp) root_dsps.push_back(&ci); // CAO1-24, CBO1-18, CZO1..56 and CCO must go to same DSP dsp = nullptr; - for(int i=1;i<=24;i++) - dsp_same_sink(ctx->idf("CAO%d",i), &ci, &dsp); - for(int i=1;i<=18;i++) - dsp_same_sink(ctx->idf("CBO%d",i), &ci, &dsp); - for(int i=1;i<=56;i++) - dsp_same_sink(ctx->idf("CZO%d",i), &ci, &dsp); + for (int i = 1; i <= 24; i++) + dsp_same_sink(ctx->idf("CAO%d", i), &ci, &dsp); + for (int i = 1; i <= 18; i++) + dsp_same_sink(ctx->idf("CBO%d", i), &ci, &dsp); + for (int i = 1; i <= 56; i++) + dsp_same_sink(ctx->idf("CZO%d", i), &ci, &dsp); dsp_same_sink(id_CCO, &ci, &dsp); if (dsp) dsp_output.emplace(ci.name, dsp); } for (auto root : root_dsps) { CellInfo *dsp = root; - if (dsp_output.count(dsp->name)==0) continue; + if (dsp_output.count(dsp->name) == 0) + continue; root->cluster = root->name; while (true) { - if (dsp_output.count(dsp->name)==0) break; + if (dsp_output.count(dsp->name) == 0) + break; dsp = dsp_output[dsp->name]; dsp->cluster = root->name; root->constr_children.push_back(dsp); @@ -2057,7 +2168,7 @@ void NgUltraPacker::remove_not_used() for (auto &p : ci.ports) { if (p.second.type == PortType::PORT_OUT) { NetInfo *net = ci.getPort(p.first); - if (net && net->users.entries()==0) { + if (net && net->users.entries() == 0) { ci.disconnectPort(p.first); } } @@ -2065,7 +2176,6 @@ void NgUltraPacker::remove_not_used() } } - void NgUltraImpl::pack() { const ArchArgs &args = ctx->args; @@ -2119,7 +2229,8 @@ IdString NgUltraPacker::assign_wfg(IdString ckg, IdString ckg2, CellInfo *cell) if (item.second == ckg || item.second == ckg2) { IdString ckg = item.second; uarch->unused_wfg.erase(bel); - log_info(" Using '%s:%s' for cell '%s'.\n", uarch->tile_name(bel.tile).c_str(), ctx->getBelName(bel)[1].c_str(ctx), cell->name.c_str(ctx)); + log_info(" Using '%s:%s' for cell '%s'.\n", uarch->tile_name(bel.tile).c_str(), + ctx->getBelName(bel)[1].c_str(ctx), cell->name.c_str(ctx)); ctx->bindBel(bel, cell, PlaceStrength::STRENGTH_LOCKED); return ckg; } @@ -2127,8 +2238,9 @@ IdString NgUltraPacker::assign_wfg(IdString ckg, IdString ckg2, CellInfo *cell) log_error(" No more available WFGs for cell '%s'.\n", cell->name.c_str(ctx)); } -void NgUltraPacker::extract_lowskew_signals(CellInfo *cell, dict>> &lowskew_signals) -{ +void NgUltraPacker::extract_lowskew_signals(CellInfo *cell, + dict>> &lowskew_signals) +{ IdString loc; if (cell->bel != BelId()) loc = uarch->tile_name_id(cell->bel.tile); @@ -2137,7 +2249,7 @@ void NgUltraPacker::extract_lowskew_signals(CellInfo *cell, dictget_fabric_lowskew_sinks(); if (sinks.count(cell->type)) { - for(auto &port : sinks.at(cell->type)) { + for (auto &port : sinks.at(cell->type)) { NetInfo *clock = cell->getPort(port); if (clock && !global_lowskew.count(clock->name)) { ref.port = port; @@ -2150,7 +2262,7 @@ void NgUltraPacker::extract_lowskew_signals(CellInfo *cell, dictcells) { CellInfo &ci = *cell.second; if (!ci.type.in(id_PLL)) @@ -2168,16 +2280,17 @@ 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; + IdString bank = uarch->tile_name_id(ref->driver.cell->bel.tile); + // bool found = false; for (auto &item : uarch->unused_pll) { BelId bel = item.first; - std::pair& ckgs = uarch->bank_to_ckg[bank]; + std::pair &ckgs = uarch->bank_to_ckg[bank]; if (item.second == ckgs.first || item.second == ckgs.second) { 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)); + 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; } } @@ -2221,8 +2334,10 @@ void NgUltraPacker::pre_place(void) if (zo_net->users.entries() != 1) log_error("WFG can only be chained with one other WFG cell\n"); group.push_back(wfg); - } else break; - } else break; + } else + break; + } else + break; } groups.push_back(group); } @@ -2245,7 +2360,7 @@ void NgUltraPacker::pre_place(void) NetInfo *zi = root->getPort(id_ZI); if (zi->driver.cell->type.in(id_IOM)) { IdString bank = uarch->tile_name_id(zi->driver.cell->bel.tile); - std::pair& ckgs = uarch->bank_to_ckg[bank]; + std::pair &ckgs = uarch->bank_to_ckg[bank]; IdString ckg = assign_wfg(ckgs.first, ckgs.second, root); for (int i = 1; i < int(grp.size()); i++) { assign_wfg(ckg, IdString(), grp.at(i)); @@ -2265,14 +2380,14 @@ void NgUltraPacker::pre_place(void) } } - dict>> lowskew_signals; + dict>> lowskew_signals; for (auto &cell : ctx->cells) extract_lowskew_signals(cell.second.get(), lowskew_signals); log_info("Adding GCK for lowskew signals..\n"); - for(auto &n : lowskew_signals[IdString()]) { + for (auto &n : lowskew_signals[IdString()]) { NetInfo *net = ctx->nets.at(n.first).get(); - if (net->driver.cell->type.in(id_BFR,id_DFR,id_DDFR)) { + if (net->driver.cell->type.in(id_BFR, id_DFR, id_DDFR)) { CellInfo *bfr = net->driver.cell; CellInfo *gck_cell = create_cell_ptr(id_GCK, ctx->idf("%s$csc", bfr->name.c_str(ctx))); gck_cell->params[id_std_mode] = Property("CSC"); @@ -2282,16 +2397,20 @@ void NgUltraPacker::pre_place(void) gck_cell->connectPort(id_SO, old); gck_cell->connectPort(id_CMD, new_out); bfr->connectPort(id_O, new_out); - log_info(" Create GCK '%s' for signal '%s'\n",gck_cell->name.c_str(ctx), n.first.c_str(ctx)); + log_info(" Create GCK '%s' for signal '%s'\n", gck_cell->name.c_str(ctx), n.first.c_str(ctx)); } if (net->driver.cell->type.in(id_BEYOND_FE)) { CellInfo *fe = net->driver.cell; - if (!fe->params.count(id_lut_table)) continue; - if (fe->params.count(id_dff_used)) continue; - if (fe->params[id_lut_table] != Property(0x5555, 16)) continue; - if (!fe->getPort(id_I1)) continue; + if (!fe->params.count(id_lut_table)) + continue; + if (fe->params.count(id_dff_used)) + continue; + if (fe->params[id_lut_table] != Property(0x5555, 16)) + continue; + if (!fe->getPort(id_I1)) + continue; CellInfo *bfr = fe->getPort(id_I1)->driver.cell; - if (bfr->type.in(id_BFR,id_DFR,id_DDFR)) { + if (bfr->type.in(id_BFR, id_DFR, id_DDFR)) { CellInfo *gck_cell = create_cell_ptr(id_GCK, ctx->idf("%s$csc", bfr->name.c_str(ctx))); gck_cell->params[id_std_mode] = Property("CSC"); gck_cell->params[id_inv_out] = Property(true); @@ -2302,7 +2421,7 @@ void NgUltraPacker::pre_place(void) gck_cell->connectPort(id_SO, old_out); gck_cell->connectPort(id_CMD, old_in); packed_cells.insert(fe->name); - log_info(" Create GCK '%s' for signal '%s'\n",gck_cell->name.c_str(ctx), n.first.c_str(ctx)); + log_info(" Create GCK '%s' for signal '%s'\n", gck_cell->name.c_str(ctx), n.first.c_str(ctx)); } } } @@ -2315,7 +2434,7 @@ void NgUltraImpl::disable_beyond_fe_s_output(BelId bel) for (PipId pip : ctx->getPipsDownhill(dwire)) { for (PipId pip2 : ctx->getPipsDownhill(ctx->getPipDstWire(pip))) { IdString dst = ctx->getWireName(ctx->getPipDstWire(pip2))[1]; - if (boost::ends_with(dst.c_str(ctx),".DS")) { + if (boost::ends_with(dst.c_str(ctx), ".DS")) { blocked_pips.emplace(pip2); return; } @@ -2333,7 +2452,8 @@ void NgUltraImpl::postPlace() const auto &extra_data = *bel_extra_data(ci.bel); // Check if CSC mode only if FE is capable if ((extra_data.flags & BEL_EXTRA_FE_CSC)) { - if (str_or_default(ci.params, id_type, "")=="CSC") continue; + if (str_or_default(ci.params, id_type, "") == "CSC") + continue; // Disable routing to S output if CSC is not used disable_beyond_fe_s_output(ci.bel); } @@ -2342,8 +2462,8 @@ void NgUltraImpl::postPlace() // it is considered that signal is comming from RI1 crossbar. // We need to prevent router to use that crossbar output for // any other signal. - for (int i=1;i<=4;i++) { - IdString port = ctx->idf("A%d",i); + for (int i = 1; i <= 4; i++) { + IdString port = ctx->idf("A%d", i); NetInfo *net = ci.getPort(port); if (!net) continue; @@ -2352,7 +2472,7 @@ void NgUltraImpl::postPlace() for (PipId pip : ctx->getPipsUphill(dwire)) { WireId src = ctx->getPipSrcWire(pip); const std::string src_name = ctx->getWireName(src)[1].str(ctx); - if (boost::starts_with(src_name,"RI1")) { + if (boost::starts_with(src_name, "RI1")) { for (PipId pip2 : ctx->getPipsDownhill(src)) { blocked_pips.emplace(pip2); } @@ -2379,82 +2499,89 @@ void NgUltraImpl::postPlace() BelId NgUltraPacker::getCSC(Loc l, int row) { - const int z_loc[] = { 0, 15, 16, 31 }; - for(int j=0;j<3;j++) { - for(int i=0;i<4;i++) { - BelId bel = ctx->getBelByLocation(Loc(l.x+j+1,l.y+j%2+2,z_loc[i])); - if (!ctx->getBoundBelCell(bel) && (row==0 || row==(i+1))) return bel; + const int z_loc[] = {0, 15, 16, 31}; + for (int j = 0; j < 3; j++) { + for (int i = 0; i < 4; i++) { + BelId bel = ctx->getBelByLocation(Loc(l.x + j + 1, l.y + j % 2 + 2, z_loc[i])); + if (!ctx->getBoundBelCell(bel) && (row == 0 || row == (i + 1))) + return bel; } - } + } return BelId(); } void NgUltraPacker::insert_csc() { - dict>> local_system_matrix; + dict>> local_system_matrix; log_info("Inserting CSCs...\n"); int insert_new_csc = 0, change_to_csc = 0; for (auto &cell : ctx->cells) { auto ci = cell.second.get(); if (ci->bel != BelId()) { - if (uarch->tile_type(ci->bel.tile)==TILE_EXTRA_FABRIC) { + if (uarch->tile_type(ci->bel.tile) == TILE_EXTRA_FABRIC) { extract_lowskew_signals(ci, local_system_matrix); } } } - for(auto &lsm : local_system_matrix) { + for (auto &lsm : local_system_matrix) { std::string name = lsm.first.c_str(ctx); Loc loc = uarch->tile_locations[name]; std::vector> fanout; - for(auto &n : lsm.second) { - fanout.push_back(std::make_pair(n.second.size(),n.first)); + for (auto &n : lsm.second) { + fanout.push_back(std::make_pair(n.second.size(), n.first)); } std::sort(fanout.begin(), fanout.end(), std::greater>()); int available_csc = 12; - for (std::size_t i = 0; i < std::min(fanout.size(),available_csc ); i++) { + for (std::size_t i = 0; i < std::min(fanout.size(), available_csc); i++) { auto &n = fanout.at(i); NetInfo *net = ctx->nets.at(n.second).get(); CellInfo *cell = net->driver.cell; - if (uarch->tile_name(cell->bel.tile) == lsm.first.c_str(ctx) && !cell->params.count(id_dff_used) && cell->cluster == ClusterId()) { - BelId newbel = getCSC(loc,0); - if (newbel==BelId()) break; + if (uarch->tile_name(cell->bel.tile) == lsm.first.c_str(ctx) && !cell->params.count(id_dff_used) && + cell->cluster == ClusterId()) { + BelId newbel = getCSC(loc, 0); + if (newbel == BelId()) + break; ctx->unbindBel(cell->bel); cell->disconnectPort(id_LO); NetInfo *new_out = ctx->createNet(ctx->idf("%s$o", cell->name.c_str(ctx))); cell->params[id_CSC] = Property(Property::State::S1); cell->params[id_type] = Property("CSC"); - cell->params[id_dff_used] = Property(1,1); - cell->connectPort(id_LO,new_out); - cell->connectPort(id_DI,new_out); - - cell->connectPort(id_DO,net); + cell->params[id_dff_used] = Property(1, 1); + cell->connectPort(id_LO, new_out); + cell->connectPort(id_DI, new_out); + + cell->connectPort(id_DO, net); ctx->bindBel(newbel, cell, PlaceStrength::STRENGTH_LOCKED); change_to_csc++; continue; } Loc cell_loc = ctx->getBelLocation(cell->bel); - BelId newbel = getCSC(loc,(cell_loc.y & 3)+1); // Take CSC from pefered row - if (newbel==BelId()) newbel = getCSC(loc,0); // Try getting any other CSC - if (newbel==BelId()) break; - if (lsm.second[n.second].size() < 4) break; + BelId newbel = getCSC(loc, (cell_loc.y & 3) + 1); // Take CSC from pefered row + if (newbel == BelId()) + newbel = getCSC(loc, 0); // Try getting any other CSC + if (newbel == BelId()) + break; + if (lsm.second[n.second].size() < 4) + break; - CellInfo *fe = create_cell_ptr(id_BEYOND_FE, ctx->idf("%s$%s$csc", net->name.c_str(ctx), lsm.first.c_str(ctx))); + CellInfo *fe = + create_cell_ptr(id_BEYOND_FE, ctx->idf("%s$%s$csc", net->name.c_str(ctx), lsm.first.c_str(ctx))); NetInfo *new_out = ctx->createNet(ctx->idf("%s$o", fe->name.c_str(ctx))); fe->params[id_lut_table] = Property(0xaaaa, 16); - fe->params[id_lut_used] = Property(1,1); + fe->params[id_lut_used] = Property(1, 1); fe->params[id_CSC] = Property(Property::State::S1); fe->params[id_type] = Property("CSC"); - fe->params[id_dff_used] = Property(1,1); + fe->params[id_dff_used] = Property(1, 1); fe->connectPort(id_I1, net); - fe->connectPort(id_DO,new_out); + fe->connectPort(id_DO, new_out); insert_new_csc++; - for(auto &conn : lsm.second[n.second]) + for (auto &conn : lsm.second[n.second]) conn.cell->disconnectPort(conn.port); - for(auto &conn : lsm.second[n.second]) - conn.cell->connectPort(conn.port,new_out); + for (auto &conn : lsm.second[n.second]) + conn.cell->connectPort(conn.port, new_out); ctx->bindBel(newbel, fe, PlaceStrength::STRENGTH_LOCKED); } @@ -2463,23 +2590,29 @@ void NgUltraPacker::insert_csc() log_info(" %6d FEs inserted as CSC\n", insert_new_csc); if (change_to_csc) log_info(" %6d FEs converted to CSC\n", change_to_csc); - } BelId NgUltraPacker::get_available_gck(int lobe, NetInfo *si1, NetInfo *si2) { auto &gcks = uarch->gck_per_lobe[lobe]; - for(int i=0;i<20;i++) { + for (int i = 0; i < 20; i++) { auto &g = gcks.at(i); - if (g.used) continue; - if (si1 && g.si1!=IdString() && g.si1!=si1->name) continue; - if (si2 && g.si2!=IdString() && g.si2!=si2->name) continue; - if (si1) g.si1 = si1->name; - if (si2) g.si2 = si2->name; + if (g.used) + continue; + if (si1 && g.si1 != IdString() && g.si1 != si1->name) + continue; + if (si2 && g.si2 != IdString() && g.si2 != si2->name) + continue; + if (si1) + g.si1 = si1->name; + if (si2) + g.si2 = si2->name; g.used = true; - if (i%2==0) { + if (i % 2 == 0) { // next GCK share inputs in reverse order - if (si2) gcks.at(i+1).si1 = si2->name; - if (si1) gcks.at(i+1).si2 = si1->name; + if (si2) + gcks.at(i + 1).si1 = si2->name; + if (si1) + gcks.at(i + 1).si2 = si1->name; } return g.bel; } @@ -2510,8 +2643,8 @@ void NgUltraPacker::duplicate_gck() dict> connections; for (const auto &usr : glb_net->users) { if (uarch->is_fabric_lowskew_sink(usr) || uarch->is_ring_over_tile_clock_sink(usr)) { - if (usr.cell->bel==BelId()) { - log_error("Cell '%s' not placed\n",usr.cell->name.c_str(ctx)); + if (usr.cell->bel == BelId()) { + log_error("Cell '%s' not placed\n", usr.cell->name.c_str(ctx)); } int lobe = uarch->tile_lobe(usr.cell->bel.tile); if (lobe > 0) { @@ -2524,21 +2657,24 @@ void NgUltraPacker::duplicate_gck() CellInfo *driver = glb_net->driver.cell; NetInfo *si1 = driver->getPort(id_SI1); NetInfo *si2 = driver->getPort(id_SI2); - NetInfo *cmd = driver->getPort(id_CMD); + NetInfo *cmd = driver->getPort(id_CMD); for (auto &conn : connections) { BelId bel = get_available_gck(conn.first, si1, si2); CellInfo *gck_cell = nullptr; - if (cnt==0) { + if (cnt == 0) { gck_cell = driver; - log_info(" Assign GCK '%s' to lobe %d\n",gck_cell->name.c_str(ctx), conn.first); + log_info(" Assign GCK '%s' to lobe %d\n", gck_cell->name.c_str(ctx), conn.first); } else { gck_cell = create_cell_ptr(id_GCK, ctx->idf("%s$gck_%d", driver->name.c_str(ctx), conn.first)); - log_info(" Create GCK '%s' for lobe %d\n",gck_cell->name.c_str(ctx), conn.first); + log_info(" Create GCK '%s' for lobe %d\n", gck_cell->name.c_str(ctx), conn.first); for (auto ¶ms : driver->params) gck_cell->params[params.first] = params.second; - if (si1) gck_cell->connectPort(id_SI1, si1); - if (si2) gck_cell->connectPort(id_SI2, si2); - if (cmd) gck_cell->connectPort(id_CMD, cmd); + if (si1) + gck_cell->connectPort(id_SI1, si1); + if (si2) + gck_cell->connectPort(id_SI2, si2); + if (cmd) + gck_cell->connectPort(id_CMD, cmd); } gck_cell->disconnectPort(id_SO); NetInfo *new_clk = ctx->createNet(ctx->id(gck_cell->name.str(ctx))); @@ -2546,14 +2682,13 @@ void NgUltraPacker::duplicate_gck() for (const auto &usr : conn.second) { CellInfo *cell = usr.cell; IdString port = usr.port; - cell->connectPort(port, new_clk); + cell->connectPort(port, new_clk); } global_lowskew.emplace(new_clk->name); ctx->bindBel(bel, gck_cell, PlaceStrength::STRENGTH_LOCKED); cnt++; } } - } void NgUltraPacker::insert_bypass_gck() @@ -2571,8 +2706,8 @@ void NgUltraPacker::insert_bypass_gck() dict> connections; for (const auto &usr : glb_net->users) { if (uarch->is_fabric_lowskew_sink(usr) || uarch->is_ring_over_tile_clock_sink(usr)) { - if (usr.cell->bel==BelId()) { - log_error("Cell '%s' not placed\n",usr.cell->name.c_str(ctx)); + if (usr.cell->bel == BelId()) { + log_error("Cell '%s' not placed\n", usr.cell->name.c_str(ctx)); } int lobe = uarch->tile_lobe(usr.cell->bel.tile); if (lobe > 0) { @@ -2584,7 +2719,7 @@ void NgUltraPacker::insert_bypass_gck() for (auto &conn : connections) { BelId bel = get_available_gck(conn.first, glb_net, nullptr); - log_info(" Create GCK for lobe %d\n",conn.first); + log_info(" Create GCK for lobe %d\n", conn.first); CellInfo *gck_cell = create_cell_ptr(id_GCK, ctx->idf("%s$gck_%d", glb_net->name.c_str(ctx), conn.first)); gck_cell->params[id_std_mode] = Property("BYPASS"); gck_cell->connectPort(id_SI1, glb_net); @@ -2593,7 +2728,7 @@ void NgUltraPacker::insert_bypass_gck() for (const auto &usr : conn.second) { CellInfo *cell = usr.cell; IdString port = usr.port; - cell->connectPort(port, new_clk); + cell->connectPort(port, new_clk); } global_lowskew.emplace(new_clk->name); ctx->bindBel(bel, gck_cell, PlaceStrength::STRENGTH_LOCKED); diff --git a/himbaechel/uarch/ng-ultra/pack.h b/himbaechel/uarch/ng-ultra/pack.h index 11a22d7e..07253688 100644 --- a/himbaechel/uarch/ng-ultra/pack.h +++ b/himbaechel/uarch/ng-ultra/pack.h @@ -83,9 +83,11 @@ TESTABLE_PRIVATE: void ddfr_rewrite(CellInfo *cell); 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_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, ClusterPlacement placement, 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, + ClusterPlacement placement, int &lut_only, int &lut_and_ff, int &dff_only); void connect_gnd_if_unconnected(CellInfo *cell, IdString input, bool warn); void disconnect_if_gnd(CellInfo *cell, IdString input); @@ -107,10 +109,10 @@ TESTABLE_PRIVATE: int make_init_with_const_input(int init, int input, bool value); int memory_width(int config, bool ecc); - int memory_addr_bits(int config,bool ecc); + int memory_addr_bits(int config, bool ecc); void constrain_location(CellInfo *cell); - void extract_lowskew_signals(CellInfo *cell, dict>> &lowskew_signals); + void extract_lowskew_signals(CellInfo *cell, dict>> &lowskew_signals); // Cell creating CellInfo *create_cell_ptr(IdString type, IdString name); diff --git a/himbaechel/uarch/ng-ultra/tests/lut_dff.cc b/himbaechel/uarch/ng-ultra/tests/lut_dff.cc index 223c53cb..87cce6ff 100644 --- a/himbaechel/uarch/ng-ultra/tests/lut_dff.cc +++ b/himbaechel/uarch/ng-ultra/tests/lut_dff.cc @@ -18,9 +18,9 @@ */ #include +#include "command.h" #include "gtest/gtest.h" #include "nextpnr.h" -#include "command.h" #include "uarch/ng-ultra/ng_ultra.h" #include "uarch/ng-ultra/pack.h" #define HIMBAECHEL_CONSTIDS "uarch/ng-ultra/constids.inc" @@ -38,13 +38,13 @@ class NGUltraLutDffTest : public ::testing::Test ctx = new Context(chipArgs); ctx->uarch->init(ctx); ctx->late_init(); - impl = (NgUltraImpl*)(ctx->uarch.get()); + impl = (NgUltraImpl *)(ctx->uarch.get()); } virtual void TearDown() { delete ctx; } int const_autoidx = 0; - NetInfo* add_constant_driver(const char *name, char constval) + NetInfo *add_constant_driver(const char *name, char constval) { IdString cell_name = ctx->idf("%s%s%d", name, (constval == '1' ? "$VCC$" : "$GND$"), const_autoidx++); CellInfo *cc = ctx->createCell(cell_name, ctx->id(constval == '1' ? "VCC" : "GND")); @@ -67,7 +67,7 @@ class NGUltraLutDffTest : public ::testing::Test int S1 = I4 ? (lut_table >> 8) & 0xff : lut_table & 0xff; int S2 = I3 ? (S1 >> 4 & 0xf) : S1 & 0xf; int S3 = I2 ? (S2 >> 2 & 0x3) : S2 & 0x3; - int O = I1 ? (S3 >> 1 & 0x1) : S3 & 0x1; + int O = I1 ? (S3 >> 1 & 0x1) : S3 & 0x1; return O; } @@ -99,19 +99,19 @@ TEST_F(NGUltraLutDffTest, remove_unused_gnd) add_port(cell, "I2", PORT_IN); add_port(cell, "I3", PORT_IN); add_port(cell, "I4", PORT_IN); - cell->connectPort(id_I1, add_constant_driver("TEST",'1')); - cell->connectPort(id_I2, add_constant_driver("TEST",'1')); - cell->connectPort(id_I3, add_constant_driver("TEST",'1')); + cell->connectPort(id_I1, add_constant_driver("TEST", '1')); + cell->connectPort(id_I2, add_constant_driver("TEST", '1')); + cell->connectPort(id_I3, add_constant_driver("TEST", '1')); ASSERT_EQ(ctx->cells.size(), 4LU); packer.pack_constants(); ASSERT_EQ(ctx->cells.size(), 3LU); impl->remove_constants(); ASSERT_EQ(ctx->cells.size(), 2LU); - ASSERT_EQ(ctx->cells.find(ctx->id("$PACKER_GND_DRV")),ctx->cells.end()); - ASSERT_NE(ctx->cells.find(ctx->id("$PACKER_VCC_DRV")),ctx->cells.end()); - ASSERT_EQ(ctx->nets.find(ctx->id("$PACKER_GND")),ctx->nets.end()); - ASSERT_NE(ctx->nets.find(ctx->id("$PACKER_VCC")),ctx->nets.end()); + ASSERT_EQ(ctx->cells.find(ctx->id("$PACKER_GND_DRV")), ctx->cells.end()); + ASSERT_NE(ctx->cells.find(ctx->id("$PACKER_VCC_DRV")), ctx->cells.end()); + ASSERT_EQ(ctx->nets.find(ctx->id("$PACKER_GND")), ctx->nets.end()); + ASSERT_NE(ctx->nets.find(ctx->id("$PACKER_VCC")), ctx->nets.end()); } TEST_F(NGUltraLutDffTest, remove_unused_vcc) @@ -122,26 +122,26 @@ TEST_F(NGUltraLutDffTest, remove_unused_vcc) add_port(cell, "I2", PORT_IN); add_port(cell, "I3", PORT_IN); add_port(cell, "I4", PORT_IN); - cell->connectPort(id_I1, add_constant_driver("TEST",'0')); - cell->connectPort(id_I2, add_constant_driver("TEST",'0')); - cell->connectPort(id_I3, add_constant_driver("TEST",'0')); + cell->connectPort(id_I1, add_constant_driver("TEST", '0')); + cell->connectPort(id_I2, add_constant_driver("TEST", '0')); + cell->connectPort(id_I3, add_constant_driver("TEST", '0')); ASSERT_EQ(ctx->cells.size(), 4LU); packer.pack_constants(); ASSERT_EQ(ctx->cells.size(), 3LU); impl->remove_constants(); ASSERT_EQ(ctx->cells.size(), 2LU); - ASSERT_NE(ctx->cells.find(ctx->id("$PACKER_GND_DRV")),ctx->cells.end()); - ASSERT_EQ(ctx->cells.find(ctx->id("$PACKER_VCC_DRV")),ctx->cells.end()); - ASSERT_NE(ctx->nets.find(ctx->id("$PACKER_GND")),ctx->nets.end()); - ASSERT_EQ(ctx->nets.find(ctx->id("$PACKER_VCC")),ctx->nets.end()); + ASSERT_NE(ctx->cells.find(ctx->id("$PACKER_GND_DRV")), ctx->cells.end()); + ASSERT_EQ(ctx->cells.find(ctx->id("$PACKER_VCC_DRV")), ctx->cells.end()); + ASSERT_NE(ctx->nets.find(ctx->id("$PACKER_GND")), ctx->nets.end()); + ASSERT_EQ(ctx->nets.find(ctx->id("$PACKER_VCC")), ctx->nets.end()); } TEST_F(NGUltraLutDffTest, make_init_with_const_input) { NgUltraPacker packer(ctx, impl); - for (int lut_table=0;lut_table<0x10000;lut_table++) { - for(int lut=0;lut<16;lut++) { + for (int lut_table = 0; lut_table < 0x10000; lut_table++) { + for (int lut = 0; lut < 16; lut++) { int I4 = (lut & 8) ? 1 : 0; int I3 = (lut & 4) ? 1 : 0; int I2 = (lut & 2) ? 1 : 0; @@ -152,10 +152,10 @@ TEST_F(NGUltraLutDffTest, make_init_with_const_input) int tab3 = packer.make_init_with_const_input(tab2, 2, I3); int tab4 = packer.make_init_with_const_input(tab3, 3, I4); - ASSERT_EQ(evaluate_lut(I1,I2,I3,I4,lut_table),evaluate_lut(I1,I2,I3,I4,tab1)); - ASSERT_EQ(evaluate_lut(I1,I2,I3,I4,lut_table),evaluate_lut(I1,I2,I3,I4,tab2)); - ASSERT_EQ(evaluate_lut(I1,I2,I3,I4,lut_table),evaluate_lut(I1,I2,I3,I4,tab3)); - ASSERT_EQ(evaluate_lut(I1,I2,I3,I4,lut_table),evaluate_lut(I1,I2,I3,I4,tab4)); + ASSERT_EQ(evaluate_lut(I1, I2, I3, I4, lut_table), evaluate_lut(I1, I2, I3, I4, tab1)); + ASSERT_EQ(evaluate_lut(I1, I2, I3, I4, lut_table), evaluate_lut(I1, I2, I3, I4, tab2)); + ASSERT_EQ(evaluate_lut(I1, I2, I3, I4, lut_table), evaluate_lut(I1, I2, I3, I4, tab3)); + ASSERT_EQ(evaluate_lut(I1, I2, I3, I4, lut_table), evaluate_lut(I1, I2, I3, I4, tab4)); } } } diff --git a/himbaechel/uarch/ng-ultra/tests/main.cc b/himbaechel/uarch/ng-ultra/tests/main.cc index 5084fd76..92e027f2 100644 --- a/himbaechel/uarch/ng-ultra/tests/main.cc +++ b/himbaechel/uarch/ng-ultra/tests/main.cc @@ -18,8 +18,8 @@ */ #include -#include "log.h" #include "gtest/gtest.h" +#include "log.h" USING_NEXTPNR_NAMESPACE