diff options
Diffstat (limited to 'ice40/bitstream.cc')
-rw-r--r-- | ice40/bitstream.cc | 65 |
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"); } |