aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ecp5/baseconfigs.cc1
-rw-r--r--ecp5/bitstream.cc33
-rw-r--r--ecp5/config.cc6
-rw-r--r--ecp5/config.h1
-rw-r--r--ecp5/lpf.cc21
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);