aboutsummaryrefslogtreecommitdiffstats
path: root/ice40/bitstream.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ice40/bitstream.cc')
-rw-r--r--ice40/bitstream.cc65
1 files changed, 59 insertions, 6 deletions
diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc
index 87d77b9d..9b85dff5 100644
--- a/ice40/bitstream.cc
+++ b/ice40/bitstream.cc
@@ -156,7 +156,9 @@ void configure_extra_cell(chipconfig_t &config, const Context *ctx, CellInfo *ce
// Lattice's weird string style params, not sure if
// prefixes other than 0b should be supported, only 0b features in docs
std::string raw = get_param_str_or_def(cell, ctx->id(p.first), "0b0");
- assert(raw.substr(0, 2) == "0b");
+ if (raw.substr(0, 2) != "0b")
+ log_error("expected configuration string starting with '0b' for parameter '%s' on cell '%s'\n",
+ p.first.c_str(), cell->name.c_str(ctx));
raw = raw.substr(2);
value.resize(raw.length());
for (int i = 0; i < (int)raw.length(); i++) {
@@ -168,7 +170,13 @@ void configure_extra_cell(chipconfig_t &config, const Context *ctx, CellInfo *ce
}
}
} else {
- int ival = get_param_or_def(cell, ctx->id(p.first), 0);
+ int ival;
+ try {
+ ival = get_param_or_def(cell, ctx->id(p.first), 0);
+ } catch (std::invalid_argument &e) {
+ log_error("expected numeric value for parameter '%s' on cell '%s'\n", p.first.c_str(),
+ cell->name.c_str(ctx));
+ }
for (int i = 0; i < p.second; i++)
value.push_back((ival >> i) & 0x1);
@@ -289,6 +297,9 @@ void write_asc(const Context *ctx, std::ostream &out)
case ArchArgs::UP5K:
out << ".device 5k" << std::endl;
break;
+ case ArchArgs::U4K:
+ out << ".device u4k" << std::endl;
+ break;
default:
NPNR_ASSERT_FALSE("unsupported device type\n");
}
@@ -519,10 +530,23 @@ void write_asc(const Context *ctx, std::ostream &out)
}
if (ctx->args.type == ArchArgs::UP5K) {
+ std::string pullup_resistor = "100K";
+ if (cell.second->attrs.count(ctx->id("PULLUP_RESISTOR")))
+ pullup_resistor = cell.second->attrs.at(ctx->id("PULLUP_RESISTOR"));
+ NPNR_ASSERT(pullup_resistor == "100K" || pullup_resistor == "10K" || pullup_resistor == "6P8K" ||
+ pullup_resistor == "3P3K");
if (iez == 0) {
- set_config(ti, config.at(iey).at(iex), "IoCtrl.cf_bit_39", !pullup);
+ set_config(ti, config.at(iey).at(iex), "IoCtrl.cf_bit_39",
+ (!pullup) || (pullup_resistor != "100K"));
+ set_config(ti, config.at(iey).at(iex), "IoCtrl.cf_bit_36", pullup && pullup_resistor == "3P3K");
+ set_config(ti, config.at(iey).at(iex), "IoCtrl.cf_bit_37", pullup && pullup_resistor == "6P8K");
+ set_config(ti, config.at(iey).at(iex), "IoCtrl.cf_bit_38", pullup && pullup_resistor == "10K");
} else if (iez == 1) {
- set_config(ti, config.at(iey).at(iex), "IoCtrl.cf_bit_35", !pullup);
+ set_config(ti, config.at(iey).at(iex), "IoCtrl.cf_bit_35",
+ (!pullup) || (pullup_resistor != "100K"));
+ set_config(ti, config.at(iey).at(iex), "IoCtrl.cf_bit_32", pullup && pullup_resistor == "3P3K");
+ set_config(ti, config.at(iey).at(iex), "IoCtrl.cf_bit_33", pullup && pullup_resistor == "6P8K");
+ set_config(ti, config.at(iey).at(iex), "IoCtrl.cf_bit_34", pullup && pullup_resistor == "10K");
}
}
} else {
@@ -592,8 +616,30 @@ void write_asc(const Context *ctx, std::ostream &out)
configure_extra_cell(config, ctx, cell.second.get(), rgba_params, true, std::string("IpConfig."));
set_ec_cbit(config, ctx, get_ec_config(ctx->chip_info, cell.second->bel), "RGBA_DRV_EN", true, "IpConfig.");
} else if (cell.second->type == ctx->id("SB_WARMBOOT") || cell.second->type == ctx->id("ICESTORM_LFOSC") ||
- cell.second->type == ctx->id("SB_LEDDA_IP") ) {
+ cell.second->type == ctx->id("SB_LEDDA_IP")) {
// No config needed
+ } else if (cell.second->type == ctx->id("SB_I2C")) {
+ bool sda_in_dly = !cell.second->attrs.count(ctx->id("SDA_INPUT_DELAYED")) ||
+ std::stoi(cell.second->attrs[ctx->id("SDA_INPUT_DELAYED")]);
+ bool sda_out_dly = !cell.second->attrs.count(ctx->id("SDA_OUTPUT_DELAYED")) ||
+ std::stoi(cell.second->attrs[ctx->id("SDA_OUTPUT_DELAYED")]);
+ set_ec_cbit(config, ctx, get_ec_config(ctx->chip_info, cell.second->bel), "SDA_INPUT_DELAYED", sda_in_dly,
+ "IpConfig.");
+ set_ec_cbit(config, ctx, get_ec_config(ctx->chip_info, cell.second->bel), "SDA_OUTPUT_DELAYED", sda_out_dly,
+ "IpConfig.");
+ set_ec_cbit(config, ctx, get_ec_config(ctx->chip_info, cell.second->bel), "I2C_ENABLE_0", true,
+ "IpConfig.");
+ set_ec_cbit(config, ctx, get_ec_config(ctx->chip_info, cell.second->bel), "I2C_ENABLE_1", true,
+ "IpConfig.");
+ } else if (cell.second->type == ctx->id("SB_SPI")) {
+ set_ec_cbit(config, ctx, get_ec_config(ctx->chip_info, cell.second->bel), "SPI_ENABLE_0", true,
+ "IpConfig.");
+ set_ec_cbit(config, ctx, get_ec_config(ctx->chip_info, cell.second->bel), "SPI_ENABLE_1", true,
+ "IpConfig.");
+ set_ec_cbit(config, ctx, get_ec_config(ctx->chip_info, cell.second->bel), "SPI_ENABLE_2", true,
+ "IpConfig.");
+ set_ec_cbit(config, ctx, get_ec_config(ctx->chip_info, cell.second->bel), "SPI_ENABLE_3", true,
+ "IpConfig.");
} else if (cell.second->type == ctx->id("ICESTORM_SPRAM")) {
const BelInfoPOD &beli = ci.bel_data[bel.index];
int x = beli.x, y = beli.y, z = beli.z;
@@ -639,7 +685,9 @@ void write_asc(const Context *ctx, std::ostream &out)
{"B_SIGNED", 1}};
configure_extra_cell(config, ctx, cell.second.get(), mac16_params, false, std::string("IpConfig."));
} else if (cell.second->type == ctx->id("ICESTORM_HFOSC")) {
- const std::vector<std::pair<std::string, int>> hfosc_params = {{"CLKHF_DIV", 2}, {"TRIM_EN", 1}};
+ std::vector<std::pair<std::string, int>> hfosc_params = {{"CLKHF_DIV", 2}};
+ if (ctx->args.type != ArchArgs::U4K)
+ hfosc_params.push_back(std::pair<std::string, int>("TRIM_EN", 1));
configure_extra_cell(config, ctx, cell.second.get(), hfosc_params, true, std::string("IpConfig."));
} else if (cell.second->type == ctx->id("ICESTORM_PLL")) {
@@ -732,6 +780,8 @@ void write_asc(const Context *ctx, std::ostream &out)
setColBufCtrl = (y == 8 || y == 9 || y == 24 || y == 25);
} else if (ctx->args.type == ArchArgs::UP5K) {
setColBufCtrl = (y == 4 || y == 5 || y == 14 || y == 15 || y == 26 || y == 27);
+ } else if (ctx->args.type == ArchArgs::U4K) {
+ setColBufCtrl = (y == 4 || y == 5 || y == 16 || y == 17);
} else if (ctx->args.type == ArchArgs::LP384) {
setColBufCtrl = false;
}
@@ -863,6 +913,9 @@ void read_config(Context *ctx, std::istream &in, chipconfig_t &config)
case ArchArgs::UP5K:
expected = "5k";
break;
+ case ArchArgs::U4K:
+ expected = "u4k";
+ break;
default:
log_error("unsupported device type\n");
}