diff options
Diffstat (limited to 'ecp5')
-rw-r--r-- | ecp5/arch.cc | 9 | ||||
-rw-r--r-- | ecp5/arch.h | 1 | ||||
-rw-r--r-- | ecp5/bitstream.cc | 24 | ||||
-rw-r--r-- | ecp5/docs/primitives.md | 2 | ||||
-rw-r--r-- | ecp5/lpf.cc | 2 | ||||
-rw-r--r-- | ecp5/main.cc | 6 | ||||
-rw-r--r-- | ecp5/pack.cc | 10 |
7 files changed, 44 insertions, 10 deletions
diff --git a/ecp5/arch.cc b/ecp5/arch.cc index 39d2ba17..ab24842e 100644 --- a/ecp5/arch.cc +++ b/ecp5/arch.cc @@ -106,7 +106,8 @@ Arch::Arch(ArchArgs args) : args(args) log_error("Unsupported ECP5 chip type.\n"); } #else - if (args.type == ArchArgs::LFE5U_25F || args.type == ArchArgs::LFE5UM_25F || args.type == ArchArgs::LFE5UM5G_25F) { + if (args.type == ArchArgs::LFE5U_12F || args.type == ArchArgs::LFE5U_25F || args.type == ArchArgs::LFE5UM_25F || + args.type == ArchArgs::LFE5UM5G_25F) { chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_25k)); } else if (args.type == ArchArgs::LFE5U_45F || args.type == ArchArgs::LFE5UM_45F || args.type == ArchArgs::LFE5UM5G_45F) { @@ -139,7 +140,9 @@ Arch::Arch(ArchArgs args) : args(args) std::string Arch::getChipName() const { - if (args.type == ArchArgs::LFE5U_25F) { + if (args.type == ArchArgs::LFE5U_12F) { + return "LFE5U-12F"; + } else if (args.type == ArchArgs::LFE5U_25F) { return "LFE5U-25F"; } else if (args.type == ArchArgs::LFE5U_45F) { return "LFE5U-45F"; @@ -186,6 +189,8 @@ std::string Arch::getFullChipName() const IdString Arch::archArgsToId(ArchArgs args) const { + if (args.type == ArchArgs::LFE5U_12F) + return id("lfe5u_12f"); if (args.type == ArchArgs::LFE5U_25F) return id("lfe5u_25f"); if (args.type == ArchArgs::LFE5U_45F) diff --git a/ecp5/arch.h b/ecp5/arch.h index 55494b1f..d57b5bc0 100644 --- a/ecp5/arch.h +++ b/ecp5/arch.h @@ -431,6 +431,7 @@ struct ArchArgs enum ArchArgsTypes { NONE, + LFE5U_12F, LFE5U_25F, LFE5U_45F, LFE5U_85F, diff --git a/ecp5/bitstream.cc b/ecp5/bitstream.cc index 1bdb4188..54d0c0a4 100644 --- a/ecp5/bitstream.cc +++ b/ecp5/bitstream.cc @@ -438,8 +438,8 @@ std::vector<std::string> get_pll_tiles(Context *ctx, BelId bel) void fix_tile_names(Context *ctx, ChipConfig &cc) { // Remove the V prefix/suffix on certain tiles if device is a SERDES variant - if (ctx->args.type == ArchArgs::LFE5U_25F || ctx->args.type == ArchArgs::LFE5U_45F || - ctx->args.type == ArchArgs::LFE5U_85F) { + if (ctx->args.type == ArchArgs::LFE5U_12F || ctx->args.type == ArchArgs::LFE5U_25F || + ctx->args.type == ArchArgs::LFE5U_45F || ctx->args.type == ArchArgs::LFE5U_85F) { std::map<std::string, std::string> tiletype_xform; for (const auto &tile : cc.tiles) { std::string newname = tile.first; @@ -580,6 +580,10 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex config_file >> cc; } else { switch (ctx->args.type) { + case ArchArgs::LFE5U_12F: + BaseConfigs::config_empty_lfe5u_25f(cc); + cc.chip_name = "LFE5U-12F"; + break; case ArchArgs::LFE5U_25F: BaseConfigs::config_empty_lfe5u_25f(cc); break; @@ -927,6 +931,9 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex iovoltage_to_str(vccio).c_str(), ci->name.c_str(ctx)); } } + if (ci->attrs.count(ctx->id("OPENDRAIN"))) + cc.tiles[pio_tile].add_enum(pio + ".OPENDRAIN", + str_or_default(ci->attrs, ctx->id("OPENDRAIN"), "OFF")); std::string datamux_oddr = str_or_default(ci->params, ctx->id("DATAMUX_ODDR"), "PADDO"); if (datamux_oddr != "PADDO") cc.tiles[pic_tile].add_enum(pio + ".DATAMUX_ODDR", datamux_oddr); @@ -1249,9 +1256,14 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex tg.config.add_enum("FEEDBK_PATH", str_or_default(ci->params, ctx->id("FEEDBK_PATH"), "CLKOP")); tg.config.add_enum("CLKOP_TRIM_POL", str_or_default(ci->params, ctx->id("CLKOP_TRIM_POL"), "RISING")); - tg.config.add_enum("CLKOP_TRIM_DELAY", str_or_default(ci->params, ctx->id("CLKOP_TRIM_DELAY"), "0")); + + tg.config.add_enum("CLKOP_TRIM_DELAY", + intstr_or_default(ci->params, ctx->id("CLKOP_TRIM_DELAY"), "0")); + tg.config.add_enum("CLKOS_TRIM_POL", str_or_default(ci->params, ctx->id("CLKOS_TRIM_POL"), "RISING")); - tg.config.add_enum("CLKOS_TRIM_DELAY", str_or_default(ci->params, ctx->id("CLKOS_TRIM_DELAY"), "0")); + + tg.config.add_enum("CLKOS_TRIM_DELAY", + intstr_or_default(ci->params, ctx->id("CLKOS_TRIM_DELAY"), "0")); tg.config.add_enum("OUTDIVIDER_MUXA", str_or_default(ci->params, ctx->id("OUTDIVIDER_MUXA"), get_net_or_empty(ci, id_CLKOP) ? "DIVA" : "REFCLK")); @@ -1429,8 +1441,8 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex Loc loc = ctx->getBelLocation(ci->bel); bool u = loc.y<15, r = loc.x> 15; std::string tiletype = fmt_str("DDRDLL_" << (u ? 'U' : 'L') << (r ? 'R' : 'L')); - if ((ctx->args.type == ArchArgs::LFE5U_25F || ctx->args.type == ArchArgs::LFE5UM_25F || - ctx->args.type == ArchArgs::LFE5UM5G_25F) && + if ((ctx->args.type == ArchArgs::LFE5U_12F || ctx->args.type == ArchArgs::LFE5U_25F || + ctx->args.type == ArchArgs::LFE5UM_25F || ctx->args.type == ArchArgs::LFE5UM5G_25F) && u) tiletype += "A"; std::string tile = ctx->getTileByType(tiletype); diff --git a/ecp5/docs/primitives.md b/ecp5/docs/primitives.md index aa37f3e5..f7f97d16 100644 --- a/ecp5/docs/primitives.md +++ b/ecp5/docs/primitives.md @@ -43,5 +43,5 @@ nextpnr-ecp5 currently supports the following primitives: - **TRELLIS_SLICE** - **TSHX2DQA** - **TSHX2DQSA** - - **USRMCLK** (untested) + - **USRMCLK** diff --git a/ecp5/lpf.cc b/ecp5/lpf.cc index ceb1d7ae..e626cc54 100644 --- a/ecp5/lpf.cc +++ b/ecp5/lpf.cc @@ -101,6 +101,8 @@ bool Arch::applyLPF(std::string filename, std::istream &in) if (words.at(3) != "SITE") log_error("expected 'SITE' after 'LOCATE COMP %s' (on line %d)\n", cell.c_str(), lineno); auto fnd_cell = cells.find(id(cell)); + if (words.size() > 5) + log_error("unexpected input following LOCATE clause (on line %d)\n", lineno); if (fnd_cell != cells.end()) { fnd_cell->second->attrs[id("LOC")] = strip_quotes(words.at(4)); } diff --git a/ecp5/main.cc b/ecp5/main.cc index 24a98df4..a24011db 100644 --- a/ecp5/main.cc +++ b/ecp5/main.cc @@ -49,6 +49,7 @@ ECP5CommandHandler::ECP5CommandHandler(int argc, char **argv) : CommandHandler(a po::options_description ECP5CommandHandler::getArchOptions() { po::options_description specific("Architecture specific options"); + specific.add_options()("12k", "set device type to LFE5U-12F"); specific.add_options()("25k", "set device type to LFE5U-25F"); specific.add_options()("45k", "set device type to LFE5U-45F"); specific.add_options()("85k", "set device type to LFE5U-85F"); @@ -125,7 +126,8 @@ std::unique_ptr<Context> ECP5CommandHandler::createContext(std::unordered_map<st { ArchArgs chipArgs; chipArgs.type = ArchArgs::NONE; - + if (vm.count("12k")) + chipArgs.type = ArchArgs::LFE5U_12F; if (vm.count("25k")) chipArgs.type = ArchArgs::LFE5U_25F; if (vm.count("45k")) @@ -179,6 +181,8 @@ std::unique_ptr<Context> ECP5CommandHandler::createContext(std::unordered_map<st if (chipArgs.type != ArchArgs::NONE) log_error("Overriding architecture is unsuported.\n"); + if (arch_type == "lfe5u_12f") + chipArgs.type = ArchArgs::LFE5U_12F; if (arch_type == "lfe5u_25f") chipArgs.type = ArchArgs::LFE5U_25F; if (arch_type == "lfe5u_45f") diff --git a/ecp5/pack.cc b/ecp5/pack.cc index dac889ce..0872ae58 100644 --- a/ecp5/pack.cc +++ b/ecp5/pack.cc @@ -2038,10 +2038,20 @@ class Ecp5Packer disconnect_port(ctx, prim, port); }; + bool warned_oddrx_iddrx = false; + auto set_iologic_mode = [&](CellInfo *iol, std::string mode) { auto &curr_mode = iol->params[ctx->id("MODE")].str; if (curr_mode != "NONE" && mode == "IREG_OREG") return; + if ((curr_mode == "IDDRXN" && mode == "ODDRXN") || (curr_mode == "ODDRXN" && mode == "IDDRXN")) { + if (!warned_oddrx_iddrx) { + warned_oddrx_iddrx = true; + log_warning("Use of IDDRXN and ODDRXN primitives on the same pin is unofficial and unsupported!\n"); + } + curr_mode = "ODDRXN"; + return; + } if (curr_mode != "NONE" && curr_mode != "IREG_OREG" && curr_mode != mode) log_error("IOLOGIC '%s' has conflicting modes '%s' and '%s'\n", iol->name.c_str(ctx), curr_mode.c_str(), mode.c_str()); |