diff options
author | David Shah <dave@ds0.me> | 2020-10-15 16:32:55 +0100 |
---|---|---|
committer | David Shah <dave@ds0.me> | 2020-11-30 08:45:27 +0000 |
commit | c80144b7f08736ce769fd69b3f5a98c86b430d5b (patch) | |
tree | 2748da9371cf531cf335c57a08b8bfeeed88418c /nexus | |
parent | 901bf2bb1eeb97386fc22f6453240f61c0aa676b (diff) | |
download | nextpnr-c80144b7f08736ce769fd69b3f5a98c86b430d5b.tar.gz nextpnr-c80144b7f08736ce769fd69b3f5a98c86b430d5b.tar.bz2 nextpnr-c80144b7f08736ce769fd69b3f5a98c86b430d5b.zip |
nexus: Generate FASM files that can be used standalone
Signed-off-by: David Shah <dave@ds0.me>
Diffstat (limited to 'nexus')
-rw-r--r-- | nexus/arch.cc | 8 | ||||
-rw-r--r-- | nexus/arch.h | 2 | ||||
-rw-r--r-- | nexus/constids.inc | 8 | ||||
-rw-r--r-- | nexus/fasm.cc | 102 |
4 files changed, 113 insertions, 7 deletions
diff --git a/nexus/arch.cc b/nexus/arch.cc index 40efa62d..8005a130 100644 --- a/nexus/arch.cc +++ b/nexus/arch.cc @@ -77,6 +77,14 @@ Arch::Arch(ArchArgs args) : args(args) log_error("Unknown device string '%s' (expected device name like 'LIFCL-40-8SG72C')\n", args.device.c_str()); package = args.device.substr(last_sep + 2, (package_end - (last_sep + 2)) + 1); rating = args.device.substr(package_end + 1); + + // Check for 'ES' part + if (rating.size() > 1 && rating.substr(1) == "ES") { + variant = "ES"; + } else { + variant = ""; + } + // Load database std::string chipdb = stringf("nexus/chipdb-%s.bin", family.c_str()); auto db_ptr = reinterpret_cast<const RelPtr<DatabasePOD> *>(get_chipdb(chipdb)); diff --git a/nexus/arch.h b/nexus/arch.h index 71114f62..126d0a91 100644 --- a/nexus/arch.h +++ b/nexus/arch.h @@ -826,7 +826,7 @@ struct ArchArgs struct Arch : BaseCtx { ArchArgs args; - std::string family, device, package, speed, rating; + std::string family, device, package, speed, rating, variant; Arch(ArchArgs args); // ------------------------------------------------- diff --git a/nexus/constids.inc b/nexus/constids.inc index b4aa5077..3fc44207 100644 --- a/nexus/constids.inc +++ b/nexus/constids.inc @@ -155,3 +155,11 @@ X(IOPAD) X(PADDO) X(PADDI) X(PADDT) + +X(PREADD9_CORE) +X(MULT9_CORE) +X(MULT18_CORE) +X(REG18_CORE) +X(MULT18X36_CORE) +X(MULT36_CORE) +X(ACC54_CORE) diff --git a/nexus/fasm.cc b/nexus/fasm.cc index 3029f4dc..66747461 100644 --- a/nexus/fasm.cc +++ b/nexus/fasm.cc @@ -67,6 +67,13 @@ struct NexusFasmWriter out << name << std::endl; } } + // Write a FASM attribute + void write_attribute(const std::string &key, const std::string &value, bool str = true) + { + std::string qu = str ? "\"" : ""; + out << "{ " << key << "=" << qu << value << qu << " }" << std::endl; + last_was_blank = false; + } // Write a FASM comment void write_comment(const std::string &cmt) { out << "# " << cmt << std::endl; } // Write a FASM bitvector; optionally inverting the values in the process @@ -161,6 +168,12 @@ struct NexusFasmWriter std::string s = stringf("R%dC%d_%s", r, c, ctx->nameOf(ctx->bel_data(bel).name)); push(s); } + // Push a bel's group and name + void push_bel(BelId bel) + { + push_belgroup(bel); + fasm_ctx.back() += stringf(".%s", ctx->nameOf(ctx->bel_data(bel).name)); + } // Write out a pip in tile.dst.src format void write_pip(PipId pip) { @@ -284,12 +297,15 @@ struct NexusFasmWriter write_cell_muxes(cell); pop(2); } + + std::unordered_set<BelId> used_io; + // Write config for an SEIO33_CORE cell void write_io33(const CellInfo *cell) { BelId bel = cell->bel; - push_belgroup(bel); - push_belname(bel); + used_io.insert(bel); + push_bel(bel); const NetInfo *t = get_net_or_empty(cell, id_T); auto tmux = ctx->get_cell_pinmux(cell, id_T); bool is_input = false, is_output = false; @@ -302,14 +318,14 @@ struct NexusFasmWriter write_bit(stringf("BASE_TYPE.%s_%s", iodir, str_or_default(cell->attrs, id_IO_TYPE, "LVCMOS33").c_str())); write_ioattr(cell, "PULLMODE", "NONE"); write_cell_muxes(cell); - pop(2); + pop(); } // Write config for an SEIO18_CORE cell void write_io18(const CellInfo *cell) { BelId bel = cell->bel; - push_belgroup(bel); - push_belname(bel); + used_io.insert(bel); + push_bel(bel); push("SEIO18"); const NetInfo *t = get_net_or_empty(cell, id_T); auto tmux = ctx->get_cell_pinmux(cell, id_T); @@ -323,7 +339,7 @@ struct NexusFasmWriter write_bit(stringf("BASE_TYPE.%s_%s", iodir, str_or_default(cell->attrs, id_IO_TYPE, "LVCMOS18H").c_str())); write_ioattr(cell, "PULLMODE", "NONE"); write_cell_muxes(cell); - pop(3); + pop(2); } // Write config for an OSC_CORE cell void write_osc(const CellInfo *cell) @@ -341,9 +357,79 @@ struct NexusFasmWriter write_cell_muxes(cell); pop(2); } + // Write out FASM for unused bels where needed + void write_unused() + { + write_comment("# Unused bels"); + + // DSP primitives are configured to a default mode; even if unused + static const std::unordered_map<IdString, std::vector<std::string>> dsp_defconf = { + {id_MULT9_CORE, + { + "GSR.ENABLED", + "MODE.NONE", + "RSTAMUX.RSTA", + "RSTPMUX.RSTP", + }}, + {id_PREADD9_CORE, + { + "GSR.ENABLED", + "MODE.NONE", + "RSTBMUX.RSTB", + "RSTCLMUX.RSTCL", + }}, + {id_REG18_CORE, + { + "GSR.ENABLED", + "MODE.NONE", + "RSTPMUX.RSTP", + }}, + {id_ACC54_CORE, + { + "ACCUBYPS.BYPASS", + "MODE.NONE", + }}, + }; + + for (BelId bel : ctx->getBels()) { + IdString type = ctx->getBelType(bel); + if (type == id_SEIO33_CORE && !used_io.count(bel)) { + push_bel(bel); + write_bit("BASE_TYPE.NONE"); + pop(); + blank(); + } else if (type == id_SEIO18_CORE && !used_io.count(bel)) { + push_bel(bel); + push("SEIO18"); + write_bit("BASE_TYPE.NONE"); + pop(2); + blank(); + } else if (dsp_defconf.count(type) && ctx->getBoundBelCell(bel) == nullptr) { + push_bel(bel); + for (const auto &cbit : dsp_defconf.at(type)) + write_bit(cbit); + pop(); + blank(); + } + } + } + // Write out placeholder bankref config + void write_bankcfg() + { + for (int i = 0; i < 8; i++) { + if (i >= 3 && i <= 5) + continue; // 1.8V banks, skip for now + write_bit(stringf("GLOBAL.BANK%d.VCC.3V3", i)); + } + blank(); + } // Write out FASM for the whole design void operator()() { + // Write device config + write_attribute("oxide.device", ctx->device); + write_attribute("oxide.device_variant", ctx->variant); + blank(); // Write routing for (auto n : sorted(ctx->nets)) { write_net(n.second); @@ -364,6 +450,10 @@ struct NexusFasmWriter write_osc(ci); blank(); } + // Write config for unused bels + write_unused(); + // Write bank config + write_bankcfg(); } }; } // namespace |