Merge branch 'master' into gw1nr-9

This commit is contained in:
YRabbit 2023-02-02 07:35:38 +10:00
commit 2edc77836d
4 changed files with 52 additions and 24 deletions

View File

@ -131,9 +131,16 @@ bool Arch::apply_lpf(std::string filename, std::istream &in)
std::string cell = strip_quotes(words.at(2)); std::string cell = strip_quotes(words.at(2));
if (words.at(3) != "SITE") if (words.at(3) != "SITE")
log_error("expected 'SITE' after 'LOCATE COMP %s' (on line %d)\n", cell.c_str(), lineno); 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) if (words.size() > 5)
log_error("unexpected input following LOCATE clause (on line %d)\n", lineno); log_error("unexpected input following LOCATE clause (on line %d)\n", lineno);
auto fnd_cell = cells.find(id(cell));
// 1-bit wires are treated as scalar by nextpnr.
// In HDL they might have been a singleton vector.
if (fnd_cell == cells.end() && cell.size() >= 3 && cell.substr(cell.size() - 3) == "[0]") {
cell = cell.substr(0, cell.size() - 3);
fnd_cell = cells.find(id(cell));
}
if (fnd_cell != cells.end()) { if (fnd_cell != cells.end()) {
fnd_cell->second->attrs[id_LOC] = strip_quotes(words.at(4)); fnd_cell->second->attrs[id_LOC] = strip_quotes(words.at(4));
} }

View File

@ -153,7 +153,11 @@ static void set_ec_cbit(chipconfig_t &config, const Context *ctx, const BelConfi
return; return;
} }
} }
if (value)
NPNR_ASSERT_FALSE_STR("failed to config extra cell config bit " + name); NPNR_ASSERT_FALSE_STR("failed to config extra cell config bit " + name);
else
log_warning("failed to config extra cell config bit %s to zero (ignored, maybe update icestorm ?)\n",
name.c_str());
} }
void configure_extra_cell(chipconfig_t &config, const Context *ctx, CellInfo *cell, void configure_extra_cell(chipconfig_t &config, const Context *ctx, CellInfo *cell,
@ -423,6 +427,18 @@ void write_asc(const Context *ctx, std::ostream &out)
// If this is a PAD PLL, and this is the 'PLLOUT_A' port, then the same SB_IO is also PAD // If this is a PAD PLL, and this is the 'PLLOUT_A' port, then the same SB_IO is also PAD
if (port == id_PLLOUT_A && is_sb_pll40_pad(ctx, cell.second.get())) if (port == id_PLLOUT_A && is_sb_pll40_pad(ctx, cell.second.get()))
sb_io_used_by_pll_pad.insert(io_bel_loc); sb_io_used_by_pll_pad.insert(io_bel_loc);
// Configure the SB_IO that the clock outputs are going through.
// note: PINTYPE[1:0] must be set property to passes the PLL through to the fabric.
// "01" if ICEGATE is disabed for that port and "11" if it's enabled
const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_IO];
bool icegate_ena = get_param_or_def(
ctx, cell.second.get(), (port == id_PLLOUT_A) ? id_ENABLE_ICEGATE_PORTA : id_ENABLE_ICEGATE_PORTB);
set_config(ti, config.at(io_bel_loc.y).at(io_bel_loc.x),
"IOB_" + std::to_string(io_bel_loc.z) + ".PINTYPE_1", icegate_ena);
set_config(ti, config.at(io_bel_loc.y).at(io_bel_loc.x),
"IOB_" + std::to_string(io_bel_loc.z) + ".PINTYPE_0", true);
} }
} }
@ -724,6 +740,8 @@ void write_asc(const Context *ctx, std::ostream &out)
{"DIVF", 7}, {"DIVF", 7},
{"DIVQ", 3}, {"DIVQ", 3},
{"DIVR", 4}, {"DIVR", 4},
{"ENABLE_ICEGATE_PORTA", 1},
{"ENABLE_ICEGATE_PORTB", 1},
{"FDA_FEEDBACK", 4}, {"FDA_FEEDBACK", 4},
{"FDA_RELATIVE", 4}, {"FDA_RELATIVE", 4},
{"FEEDBACK_PATH", 3}, {"FEEDBACK_PATH", 3},
@ -734,19 +752,6 @@ void write_asc(const Context *ctx, std::ostream &out)
{"SHIFTREG_DIV_MODE", 2}, {"SHIFTREG_DIV_MODE", 2},
{"TEST_MODE", 1}}; {"TEST_MODE", 1}};
configure_extra_cell(config, ctx, cell.second.get(), pll_params, false, std::string("PLL.")); configure_extra_cell(config, ctx, cell.second.get(), pll_params, false, std::string("PLL."));
// Configure the SB_IOs that the clock outputs are going through.
for (auto &io_bel_loc : sb_io_used_by_pll_out) {
// Write config.
const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_IO];
// PINTYPE[1:0] == "01" passes the PLL through to the fabric.
set_config(ti, config.at(io_bel_loc.y).at(io_bel_loc.x),
"IOB_" + std::to_string(io_bel_loc.z) + ".PINTYPE_1", false);
set_config(ti, config.at(io_bel_loc.y).at(io_bel_loc.x),
"IOB_" + std::to_string(io_bel_loc.z) + ".PINTYPE_0", true);
}
} else { } else {
NPNR_ASSERT(false); NPNR_ASSERT(false);
} }

View File

@ -216,6 +216,9 @@ std::unique_ptr<CellInfo> create_ice_cell(Context *ctx, IdString type, std::stri
new_cell->params[id_PLLOUT_SELECT_A] = Property(0, 2); new_cell->params[id_PLLOUT_SELECT_A] = Property(0, 2);
new_cell->params[id_PLLOUT_SELECT_B] = Property(0, 2); new_cell->params[id_PLLOUT_SELECT_B] = Property(0, 2);
new_cell->params[id_ENABLE_ICEGATE_PORTA] = Property::State::S0;
new_cell->params[id_ENABLE_ICEGATE_PORTB] = Property::State::S0;
new_cell->params[id_PLLTYPE] = Property(0, 3); new_cell->params[id_PLLTYPE] = Property(0, 3);
new_cell->params[id_SHIFTREG_DIVMODE] = Property::State::S0; new_cell->params[id_SHIFTREG_DIVMODE] = Property::State::S0;
new_cell->params[id_TEST_MODE] = Property::State::S0; new_cell->params[id_TEST_MODE] = Property::State::S0;
@ -404,25 +407,28 @@ void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_l
void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio, pool<IdString> &todelete_cells) void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio, pool<IdString> &todelete_cells)
{ {
bool pull_up_attr = false;
if (nxio->type == ctx->id("$nextpnr_ibuf")) { if (nxio->type == ctx->id("$nextpnr_ibuf")) {
sbio->params[id_PIN_TYPE] = 1; sbio->params[id_PIN_TYPE] = 1;
auto pu_attr = nxio->attrs.find(id_PULLUP);
if (pu_attr != nxio->attrs.end())
sbio->params[id_PULLUP] = pu_attr->second;
nxio->movePortTo(id_O, sbio, id_D_IN_0); nxio->movePortTo(id_O, sbio, id_D_IN_0);
pull_up_attr = true;
} else if (nxio->type == ctx->id("$nextpnr_obuf")) { } else if (nxio->type == ctx->id("$nextpnr_obuf")) {
NetInfo *i = nxio->getPort(id_I);
if (i == nullptr || i->driver.cell == nullptr) {
sbio->params[id_PIN_TYPE] = 1;
pull_up_attr = true;
} else
sbio->params[id_PIN_TYPE] = 25; sbio->params[id_PIN_TYPE] = 25;
nxio->movePortTo(id_I, sbio, id_D_OUT_0); nxio->movePortTo(id_I, sbio, id_D_OUT_0);
} else if (nxio->type == ctx->id("$nextpnr_iobuf")) { } else if (nxio->type == ctx->id("$nextpnr_iobuf")) {
// N.B. tristate will be dealt with below // N.B. tristate will be dealt with below
NetInfo *i = nxio->getPort(id_I); NetInfo *i = nxio->getPort(id_I);
if (i == nullptr || i->driver.cell == nullptr) if (i == nullptr || i->driver.cell == nullptr) {
sbio->params[id_PIN_TYPE] = 1; sbio->params[id_PIN_TYPE] = 1;
else pull_up_attr = true;
} else
sbio->params[id_PIN_TYPE] = 25; sbio->params[id_PIN_TYPE] = 25;
auto pu_attr = nxio->attrs.find(id_PULLUP);
if (pu_attr != nxio->attrs.end())
sbio->params[id_PULLUP] = pu_attr->second;
nxio->movePortTo(id_I, sbio, id_D_OUT_0); nxio->movePortTo(id_I, sbio, id_D_OUT_0);
nxio->movePortTo(id_O, sbio, id_D_IN_0); nxio->movePortTo(id_O, sbio, id_D_IN_0);
} else { } else {
@ -465,6 +471,7 @@ void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio, pool<IdString> &to
sbio->params[id_PIN_TYPE] = 41; sbio->params[id_PIN_TYPE] = 41;
tbuf->movePortTo(id_A, sbio, id_D_OUT_0); tbuf->movePortTo(id_A, sbio, id_D_OUT_0);
tbuf->movePortTo(id_E, sbio, id_OUTPUT_ENABLE); tbuf->movePortTo(id_E, sbio, id_OUTPUT_ENABLE);
pull_up_attr = true;
if (donet->users.entries() > 1) { if (donet->users.entries() > 1) {
for (auto user : donet->users) for (auto user : donet->users)
@ -476,6 +483,13 @@ void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio, pool<IdString> &to
ctx->nets.erase(donet->name); ctx->nets.erase(donet->name);
todelete_cells.insert(tbuf->name); todelete_cells.insert(tbuf->name);
} }
// Copy pull-up attribute if there's any chance output driver isn't active
if (pull_up_attr) {
auto pu_attr = nxio->attrs.find(id_PULLUP);
if (pu_attr != nxio->attrs.end())
sbio->params[id_PULLUP] = pu_attr->second;
}
} }
uint8_t sb_pll40_type(const BaseCtx *ctx, const CellInfo *cell) uint8_t sb_pll40_type(const BaseCtx *ctx, const CellInfo *cell)

View File

@ -480,6 +480,8 @@ X(DIVQ)
X(DIVR) X(DIVR)
X(D_REG) X(D_REG)
X(E) X(E)
X(ENABLE_ICEGATE_PORTA)
X(ENABLE_ICEGATE_PORTB)
X(FDA_FEEDBACK) X(FDA_FEEDBACK)
X(FDA_RELATIVE) X(FDA_RELATIVE)
X(FEEDBACK_PATH) X(FEEDBACK_PATH)