diff --git a/xc7/cells.cc b/xc7/cells.cc index 817fbab6..68da9907 100644 --- a/xc7/cells.cc +++ b/xc7/cells.cc @@ -48,8 +48,6 @@ std::unique_ptr create_xc7_cell(Context *ctx, IdString type, std::stri new_cell->params[ctx->id("NEG_CLK")] = "0"; new_cell->params[ctx->id("CARRY_ENABLE")] = "0"; new_cell->params[ctx->id("DFF_ENABLE")] = "0"; - new_cell->params[ctx->id("SET_NORESET")] = "0"; - new_cell->params[ctx->id("ASYNC_SR")] = "0"; new_cell->params[ctx->id("CIN_CONST")] = "0"; new_cell->params[ctx->id("CIN_SET")] = "0"; @@ -290,34 +288,56 @@ void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_l replace_port(dff, ctx->id("C"), lc, ctx->id("CLK")); if (citer != config.end()) { - if (*citer == 'C' || *citer == 'P') - lc->params[ctx->id("ASYNC_SR")] = "1"; - else - lc->params[ctx->id("ASYNC_SR")] = "0"; + auto gnd_net = ctx->nets.at(ctx->id("$PACKER_GND_NET")).get(); if (*citer == 'S') { citer++; - replace_port(dff, ctx->id("S"), lc, ctx->id("SR")); - lc->params[ctx->id("SET_NORESET")] = "1"; + if (get_net_or_empty(dff, ctx->id("S")) != gnd_net) { + lc->params[ctx->id("SR")] = "SRHIGH"; + lc->params[ctx->id("SYNC_ATTR")] = "SYNC"; + replace_port(dff, ctx->id("S"), lc, ctx->id("SR")); + } + else + disconnect_port(ctx, dff, ctx->id("S")); } else if (*citer == 'R') { citer++; - replace_port(dff, ctx->id("R"), lc, ctx->id("SR")); - lc->params[ctx->id("SET_NORESET")] = "0"; + if (get_net_or_empty(dff, ctx->id("R")) != gnd_net) { + lc->params[ctx->id("SR")] = "SRLOW"; + lc->params[ctx->id("SYNC_ATTR")] = "SYNC"; + replace_port(dff, ctx->id("R"), lc, ctx->id("SR")); + } + else + disconnect_port(ctx, dff, ctx->id("R")); } else if (*citer == 'C') { citer++; - replace_port(dff, ctx->id("CLR"), lc, ctx->id("SR")); - lc->params[ctx->id("SET_NORESET")] = "0"; + if (get_net_or_empty(dff, ctx->id("CLR")) != gnd_net) { + lc->params[ctx->id("SR")] = "SRLOW"; + lc->params[ctx->id("SYNC_ATTR")] = "ASYNC"; + replace_port(dff, ctx->id("CLR"), lc, ctx->id("SR")); + } + else + disconnect_port(ctx, dff, ctx->id("CLR")); } else { NPNR_ASSERT(*citer == 'P'); citer++; - replace_port(dff, ctx->id("PRE"), lc, ctx->id("SR")); - lc->params[ctx->id("SET_NORESET")] = "1"; + if (get_net_or_empty(dff, ctx->id("PRE")) != gnd_net) { + lc->params[ctx->id("SR")] = "SRHIGH"; + lc->params[ctx->id("SYNC_ATTR")] = "ASYNC"; + replace_port(dff, ctx->id("PRE"), lc, ctx->id("SR")); + } + else + disconnect_port(ctx, dff, ctx->id("PRE")); } } if (citer != config.end() && *citer == 'E') { - replace_port(dff, ctx->id("CE"), lc, ctx->id("CE")); + auto vcc_net = ctx->nets.at(ctx->id("$PACKER_VCC_NET")).get(); + ++citer; + if (get_net_or_empty(dff, ctx->id("CE")) != vcc_net) + replace_port(dff, ctx->id("CE"), lc, ctx->id("CE")); + else + disconnect_port(ctx, dff, ctx->id("CE")); } NPNR_ASSERT(citer == config.end()); @@ -331,7 +351,7 @@ void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_l auto it = dff->params.find(ctx->id("INIT")); if (it != dff->params.end()) - lc->params[ctx->id("DFF_INIT")] = it->second; + lc->params[ctx->id("FFINIT")] = it->second == "1" ? "INIT1" : "INIT0"; } void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio) diff --git a/xc7/xdl.cc b/xc7/xdl.cc index 81b11c00..fabffbfc 100644 --- a/xc7/xdl.cc +++ b/xc7/xdl.cc @@ -111,7 +111,7 @@ DesignSharedPtr create_torc_design(const Context *ctx) // Assume from Yosys that INIT masks of less than 32 bits are output as uint32_t if (lut_inputs.size() < 6) { auto init_as_uint = boost::lexical_cast(init); - NPNR_ASSERT(init_as_uint <= (1ull << (1u << lut_inputs.size()))); + NPNR_ASSERT(init_as_uint <= ((1ull << (1u << lut_inputs.size())) - 1)); if (lut_inputs.empty()) value += init; else { @@ -173,16 +173,19 @@ DesignSharedPtr create_torc_design(const Context *ctx) boost::replace_all(name, ":", "\\:"); instPtr->setConfig(setting, name, "#FF"); instPtr->setConfig(setting + "MUX", "", "O6"); - instPtr->setConfig(setting + "INIT", "", "INIT" + cell.second->params.at(ctx->id("DFF_INIT"))); - assert(cell.second->params.at(ctx->id("SET_NORESET")) == "0"); // TODO - instPtr->setConfig(setting + "SR", "", "SRLOW"); + instPtr->setConfig(setting + "INIT", "", cell.second->params.at(ctx->id("FFINIT"))); - NPNR_ASSERT(!cell.second->lcInfo.negClk); // TODO - instPtr->setConfig("CLKINV", "", "CLK"); + if (cell.second->lcInfo.negClk) + instPtr->setConfig("CLKINV", "", "CLK_B"); + + if (get_net_or_empty(cell.second.get(), ctx->id("SR"))) { + instPtr->setConfig(setting + "SR", "", cell.second->params.at(ctx->id("SR"))); + instPtr->setConfig("SYNC_ATTR", "", cell.second->params.at(ctx->id("SYNC_ATTR"))); + instPtr->setConfig("SRUSEDMUX", "", "IN"); + } + if (get_net_or_empty(cell.second.get(), ctx->id("CE"))) + instPtr->setConfig("CEUSEDMUX", "", "IN"); - instPtr->setConfig("SRUSEDMUX", "", "IN"); - instPtr->setConfig("CEUSEDMUX", "", "IN"); - instPtr->setConfig("SYNC_ATTR", "", "ASYNC"); } } else if (cell.second->type == id_IOB33) { if (get_net_or_empty(cell.second.get(), id_I)) { @@ -195,9 +198,6 @@ DesignSharedPtr create_torc_design(const Context *ctx) instPtr->setConfig("DRIVE", "", "12"); instPtr->setConfig("SLEW", "", "SLOW"); } - } else if (cell.second->type == id_BUFGCTRL || cell.second->type == id_PS7 || cell.second->type == id_MMCME2_ADV) { - for (const auto& i : cell.second->params) - instPtr->setConfig(i.first.str(ctx), "", i.second); } else if (cell.second->type == id_IOB18) { if (get_net_or_empty(cell.second.get(), id_I)) { instPtr->setConfig("IUSED", "", "0"); @@ -209,6 +209,9 @@ DesignSharedPtr create_torc_design(const Context *ctx) instPtr->setConfig("DRIVE", "", "12"); instPtr->setConfig("SLEW", "", "SLOW"); } + } else if (cell.second->type == id_BUFGCTRL || cell.second->type == id_PS7 || cell.second->type == id_MMCME2_ADV) { + for (const auto& i : cell.second->params) + instPtr->setConfig(i.first.str(ctx), "", i.second); } else log_error("Unsupported cell type '%s'.\n", cell.second->type.c_str(ctx)); }