diff options
-rw-r--r-- | ecp5/baseconfigs.cc | 1 | ||||
-rw-r--r-- | ecp5/bitstream.cc | 33 | ||||
-rw-r--r-- | ecp5/config.cc | 6 | ||||
-rw-r--r-- | ecp5/config.h | 1 | ||||
-rw-r--r-- | ecp5/lpf.cc | 21 |
5 files changed, 58 insertions, 4 deletions
diff --git a/ecp5/baseconfigs.cc b/ecp5/baseconfigs.cc index 3dc07b22..f76e6c93 100644 --- a/ecp5/baseconfigs.cc +++ b/ecp5/baseconfigs.cc @@ -514,7 +514,6 @@ void config_empty_lfe5u_45f(ChipConfig &cc) cc.tiles["MIB_R10C41:CMUX_UR_0"].add_arc("G_DCS0CLK1", "G_VPFN0000"); cc.tiles["MIB_R58C40:CMUX_LL_0"].add_arc("G_DCS1CLK0", "G_VPFN0000"); cc.tiles["MIB_R58C41:CMUX_LR_0"].add_arc("G_DCS1CLK1", "G_VPFN0000"); - cc.tiles["MIB_R71C3:BANKREF8"].add_unknown(18, 0); cc.tiles["MIB_R71C4:EFB0_PICB0"].add_unknown(54, 1); cc.tiles["MIB_R71C4:EFB0_PICB0"].add_unknown(56, 1); cc.tiles["MIB_R71C4:EFB0_PICB0"].add_unknown(82, 1); diff --git a/ecp5/bitstream.cc b/ecp5/bitstream.cc index d6b1c701..bef149a4 100644 --- a/ecp5/bitstream.cc +++ b/ecp5/bitstream.cc @@ -701,9 +701,13 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex auto tiles = ctx->getTilesAtLocation(y, x); for (auto tile : tiles) { std::string type = tile.second; - if (type.find("BANKREF") != std::string::npos && type != "BANKREF8") { + if (type.find("BANKREF") != std::string::npos) { int bank = std::stoi(type.substr(7)); - if (bankVcc.find(bank) != bankVcc.end()) { + if (bank == 8 && ctx->settings.count(ctx->id("arch.sysconfig.CONFIG_IOVOLTAGE"))) { + std::string vcc = str_or_default(ctx->settings, ctx->id("arch.sysconfig.CONFIG_IOVOLTAGE")); + vcc.at(1) = 'V'; + cc.tiles[tile.first].add_enum("BANK.VCCIO", vcc); + } else if (bankVcc.find(bank) != bankVcc.end()) { if (bankVcc[bank] == IOVoltage::VCC_1V35) cc.tiles[tile.first].add_enum("BANK.VCCIO", "1V2"); else @@ -1404,6 +1408,8 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex cc.tiles[ctx->getTileByType("EFB1_PICB1")].add_enum("OSC.MODE", "OSCG"); cc.tiles[ctx->getTileByType("EFB1_PICB1")].add_enum("CCLK.MODE", "_NONE_"); } else if (ci->type == id_USRMCLK) { + if (str_or_default(ctx->settings, ctx->id("arch.sysconfig.MASTER_SPI_PORT"), "") == "ENABLE") + log_warning("USRMCLK will not function correctly when MASTER_SPI_PORT is set to ENABLE.\n"); cc.tiles[ctx->getTileByType("EFB3_PICB1")].add_enum("CCLK.MODE", "USRMCLK"); } else if (ci->type == id_GSR) { cc.tiles[ctx->getTileByType("EFB0_PICB0")].add_enum( @@ -1485,6 +1491,29 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex } } + // Add some SYSCONFIG settings + const std::string prefix = "arch.sysconfig."; + for (auto &setting : ctx->settings) { + std::string key = setting.first.str(ctx); + if (key.substr(0, prefix.length()) != prefix) + continue; + key = key.substr(prefix.length()); + std::string value = setting.second.as_string(); + if (key == "SLAVE_SPI_PORT" || key == "DONE_EX") { + cc.tiles[ctx->getTileByType("EFB0_PICB0")].add_enum("SYSCONFIG." + key, value); + cc.tiles[ctx->getTileByType("EFB2_PICB0")].add_enum("SYSCONFIG." + key, value); + } else if (key == "SLAVE_PARALLEL_PORT" || key == "BACKGROUND_RECONFIG" || key == "WAKE_UP") { + cc.tiles[ctx->getTileByType("EFB0_PICB0")].add_enum("SYSCONFIG." + key, value); + } else if (key == "MASTER_SPI_PORT") { + cc.tiles[ctx->getTileByType("EFB1_PICB1")].add_enum("SYSCONFIG." + key, value); + } else if (key == "TRANSFR") { + cc.tiles[ctx->getTileByType("EFB0_PICB0")].add_enum("SYSCONFIG." + key, value); + cc.tiles[ctx->getTileByType("EFB1_PICB1")].add_enum("SYSCONFIG." + key, value); + } else { + cc.sysconfig[key] = value; + } + } + // Fixup tile names fix_tile_names(ctx, cc); // Configure chip diff --git a/ecp5/config.cc b/ecp5/config.cc index c8f94857..84085e8f 100644 --- a/ecp5/config.cc +++ b/ecp5/config.cc @@ -267,6 +267,8 @@ std::ostream &operator<<(std::ostream &out, const ChipConfig &cc) out << ".device " << cc.chip_name << std::endl << std::endl; for (const auto &meta : cc.metadata) out << ".comment " << meta << std::endl; + for (const auto &sc : cc.sysconfig) + out << ".sysconfig " << sc.first << " " << sc.second << std::endl; out << std::endl; for (const auto &tile : cc.tiles) { if (!tile.second.empty()) { @@ -311,6 +313,10 @@ std::istream &operator>>(std::istream &in, ChipConfig &cc) std::string line; getline(in, line); cc.metadata.push_back(line); + } else if (verb == ".sysconfig") { + std::string key, value; + in >> key >> value; + cc.sysconfig[key] = value; } else if (verb == ".tile") { std::string tilename; in >> tilename; diff --git a/ecp5/config.h b/ecp5/config.h index 8b38de5d..d4a21577 100644 --- a/ecp5/config.h +++ b/ecp5/config.h @@ -114,6 +114,7 @@ class ChipConfig std::vector<std::string> metadata; std::map<std::string, TileConfig> tiles; std::vector<TileGroup> tilegroups; + std::map<std::string, std::string> sysconfig; std::map<uint16_t, std::vector<uint16_t>> bram_data; }; diff --git a/ecp5/lpf.cc b/ecp5/lpf.cc index e740b737..18c81237 100644 --- a/ecp5/lpf.cc +++ b/ecp5/lpf.cc @@ -23,6 +23,14 @@ NEXTPNR_NAMESPACE_BEGIN +static const std::unordered_set<std::string> sysconfig_keys = { + "SLAVE_SPI_PORT", "MASTER_SPI_PORT", "SLAVE_PARALLEL_PORT", + "BACKGROUND_RECONFIG", "DONE_EX", "DONE_OD", + "DONE_PULL", "MCCLK_FREQ", "TRANSFR", + "CONFIG_IOVOLTAGE", "CONFIG_SECURE", "WAKE_UP", + "COMPRESS_CONFIG", "CONFIG_MODE", "INBUF", +}; + bool Arch::applyLPF(std::string filename, std::istream &in) { auto isempty = [](const std::string &str) { @@ -66,10 +74,21 @@ bool Arch::applyLPF(std::string filename, std::istream &in) words.push_back(tmp); if (words.size() >= 0) { std::string verb = words.at(0); - if (verb == "BLOCK" || verb == "SYSCONFIG") { + if (verb == "BLOCK") { if (words.size() != 2 || (words.at(1) != "ASYNCPATHS" && words.at(1) != "RESETPATHS")) log_warning(" ignoring unsupported LPF command '%s' (on line %d)\n", command.c_str(), lineno); + } else if (verb == "SYSCONFIG") { + for (size_t i = 1; i < words.size(); i++) { + std::string setting = words.at(i); + size_t eqpos = setting.find('='); + if (eqpos == std::string::npos) + log_error("expected syntax 'SYSCONFIG <attr>=<value>...' (on line %d)\n", lineno); + std::string key = setting.substr(0, eqpos), value = setting.substr(eqpos + 1); + if (!sysconfig_keys.count(key)) + log_error("unexpected SYSCONFIG key '%s' (on line %d)\n", key.c_str(), lineno); + settings[id("arch.sysconfig." + key)] = value; + } } else if (verb == "FREQUENCY") { if (words.size() < 2) log_error("expected object type after FREQUENCY (on line %d)\n", lineno); |