diff options
author | Eddie Hung <eddie.hung+gitlab@gmail.com> | 2018-07-18 04:49:50 +0000 |
---|---|---|
committer | Eddie Hung <eddie.hung+gitlab@gmail.com> | 2018-07-18 04:49:50 +0000 |
commit | 7e6332735d12f2e5ab9128648ed444bc123df512 (patch) | |
tree | fc4f7a05be8691340c0003e10be400dc67defea0 | |
parent | dabc057da94207c1dfbb8d9679c639ff697bea14 (diff) | |
parent | edf7bd09cf2a27fa1ada1a1e34cbe47c4bf0d48a (diff) | |
download | nextpnr-7e6332735d12f2e5ab9128648ed444bc123df512.tar.gz nextpnr-7e6332735d12f2e5ab9128648ed444bc123df512.tar.bz2 nextpnr-7e6332735d12f2e5ab9128648ed444bc123df512.zip |
Merge branch 'master' into 'master'
Master
See merge request eddiehung/nextpnr!3
-rw-r--r-- | common/nextpnr.h | 4 | ||||
-rw-r--r-- | ecp5/archdefs.h | 3 | ||||
-rw-r--r-- | ecp5/bitstream.cc | 12 | ||||
-rw-r--r-- | ecp5/cells.cc | 10 | ||||
-rw-r--r-- | ecp5/pack.cc | 41 | ||||
-rw-r--r-- | ecp5/synth/blinky_nopack.ys | 2 | ||||
-rw-r--r-- | generic/archdefs.h | 3 | ||||
-rw-r--r-- | gui/yosystab.cc | 5 | ||||
-rw-r--r-- | ice40/archdefs.h | 4 |
9 files changed, 68 insertions, 16 deletions
diff --git a/common/nextpnr.h b/common/nextpnr.h index 50465869..3d0cc955 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -200,7 +200,7 @@ struct PipMap PlaceStrength strength = STRENGTH_NONE; }; -struct NetInfo +struct NetInfo : ArchNetInfo { IdString name; PortRef driver; @@ -225,7 +225,7 @@ struct PortInfo PortType type; }; -struct CellInfo +struct CellInfo : ArchCellInfo { IdString name, type; std::unordered_map<IdString, PortInfo> ports; diff --git a/ecp5/archdefs.h b/ecp5/archdefs.h index 84a431fd..df1add44 100644 --- a/ecp5/archdefs.h +++ b/ecp5/archdefs.h @@ -129,6 +129,9 @@ struct DecalId } }; +struct ArchNetInfo { }; +struct ArchCellInfo { }; + NEXTPNR_NAMESPACE_END namespace std { diff --git a/ecp5/bitstream.cc b/ecp5/bitstream.cc index e70d6bb2..19ddb9f9 100644 --- a/ecp5/bitstream.cc +++ b/ecp5/bitstream.cc @@ -214,6 +214,18 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex cc.tiles[tname].add_enum(slice + ".REG1.REGSET", str_or_default(ci->params, ctx->id("REG1_REGSET"), "RESET")); cc.tiles[tname].add_enum(slice + ".CEMUX", str_or_default(ci->params, ctx->id("CEMUX"), "1")); + IdString lsrnet; + if (ci->ports.find(ctx->id("LSR")) != ci->ports.end() && ci->ports.at(ctx->id("LSR")).net != nullptr) + lsrnet = ci->ports.at(ctx->id("LSR")).net->name; + if (ctx->getBoundWireNet(ctx->getWireByName( + ctx->id(fmt_str("X" << bel.location.x << "/Y" << bel.location.y << "/LSR0")))) == lsrnet) { + cc.tiles[tname].add_enum("LSR0.SRMODE", str_or_default(ci->params, ctx->id("SRMODE"), "LSR_OVER_CE")); + cc.tiles[tname].add_enum("LSR0.LSRMUX", str_or_default(ci->params, ctx->id("LSRMUX"), "LSR")); + } else if (ctx->getBoundWireNet(ctx->getWireByName(ctx->id( + fmt_str("X" << bel.location.x << "/Y" << bel.location.y << "/LSR1")))) == lsrnet) { + cc.tiles[tname].add_enum("LSR1.SRMODE", str_or_default(ci->params, ctx->id("SRMODE"), "LSR_OVER_CE")); + cc.tiles[tname].add_enum("LSR1.LSRMUX", str_or_default(ci->params, ctx->id("LSRMUX"), "LSR")); + } // TODO: CLKMUX, CEMUX, carry } else if (ci->type == ctx->id("TRELLIS_IO")) { std::string pio = ctx->locInfo(bel)->bel_data[bel.index].name.get(); diff --git a/ecp5/cells.cc b/ecp5/cells.cc index 4a20ce80..59504735 100644 --- a/ecp5/cells.cc +++ b/ecp5/cells.cc @@ -41,7 +41,7 @@ std::unique_ptr<CellInfo> create_ecp5_cell(Context *ctx, IdString type, std::str new_cell->name = ctx->id(name); } new_cell->type = type; - if (type == ctx->id("TRELLIS_LC")) { + if (type == ctx->id("TRELLIS_SLICE")) { new_cell->params[ctx->id("MODE")] = "LOGIC"; new_cell->params[ctx->id("GSR")] = "DISABLED"; new_cell->params[ctx->id("SRMODE")] = "LSR_OVER_CE"; @@ -131,7 +131,7 @@ static void set_param_safe(bool has_ff, CellInfo *lc, IdString name, const std:: static void replace_port_safe(bool has_ff, CellInfo *ff, IdString ff_port, CellInfo *lc, IdString lc_port) { if (has_ff) { - assert(lc->ports.at(lc_port).net == ff->ports.at(ff_port).net); + NPNR_ASSERT(lc->ports.at(lc_port).net == ff->ports.at(ff_port).net); NetInfo *ffnet = ff->ports.at(ff_port).net; if (ffnet != nullptr) ffnet->users.erase( @@ -154,8 +154,10 @@ void ff_to_slice(Context *ctx, CellInfo *ff, CellInfo *lc, int index, bool drive lc->params[ctx->id(reg + "_SD")] = driven_by_lut ? "1" : "0"; lc->params[ctx->id(reg + "_REGSET")] = str_or_default(ff->params, ctx->id("REGSET"), "RESET"); replace_port_safe(has_ff, ff, ctx->id("CLK"), lc, ctx->id("CLK")); - replace_port_safe(has_ff, ff, ctx->id("LSR"), lc, ctx->id("LSR")); - replace_port_safe(has_ff, ff, ctx->id("CE"), lc, ctx->id("CE")); + if (ff->ports.find(ctx->id("LSR")) != ff->ports.end()) + replace_port_safe(has_ff, ff, ctx->id("LSR"), lc, ctx->id("LSR")); + if (ff->ports.find(ctx->id("CE")) != ff->ports.end()) + replace_port_safe(has_ff, ff, ctx->id("CE"), lc, ctx->id("CE")); replace_port(ff, ctx->id("Q"), lc, ctx->id("Q" + std::to_string(index))); if (driven_by_lut) { diff --git a/ecp5/pack.cc b/ecp5/pack.cc index 4f864b89..c0427d46 100644 --- a/ecp5/pack.cc +++ b/ecp5/pack.cc @@ -119,7 +119,8 @@ class Ecp5Packer NetInfo *znet = ci->ports.at(ctx->id("Z")).net; if (znet != nullptr) { for (auto user : znet->users) { - if (is_lut(ctx, user.cell) && procdLuts.find(user.cell->name) == procdLuts.end()) { + if (is_lut(ctx, user.cell) && user.cell != ci && + procdLuts.find(user.cell->name) == procdLuts.end()) { if (can_pack_lutff(ci->name, user.cell->name)) { procdLuts.insert(ci->name); procdLuts.insert(user.cell->name); @@ -137,7 +138,8 @@ class Ecp5Packer NetInfo *qnet = ctx->cells.at(lutffPairs[ci->name])->ports.at(ctx->id("Q")).net; if (qnet != nullptr) { for (auto user : qnet->users) { - if (is_lut(ctx, user.cell) && procdLuts.find(user.cell->name) == procdLuts.end()) { + if (is_lut(ctx, user.cell) && user.cell != ci && + procdLuts.find(user.cell->name) == procdLuts.end()) { if (can_pack_lutff(ci->name, user.cell->name)) { procdLuts.insert(ci->name); procdLuts.insert(user.cell->name); @@ -152,11 +154,11 @@ class Ecp5Packer } } } - for (char inp : "ABCD") { - NetInfo *innet = ci->ports.at(ctx->id(std::string("") + inp)).net; + for (const char *inp : {"A", "B", "C", "D"}) { + NetInfo *innet = ci->ports.at(ctx->id(inp)).net; if (innet != nullptr && innet->driver.cell != nullptr) { CellInfo *drv = innet->driver.cell; - if (is_lut(ctx, drv) && innet->driver.port == ctx->id("Z")) { + if (is_lut(ctx, drv) && drv != ci && innet->driver.port == ctx->id("Z")) { if (procdLuts.find(drv->name) == procdLuts.end()) { if (can_pack_lutff(ci->name, drv->name)) { procdLuts.insert(ci->name); @@ -167,7 +169,8 @@ class Ecp5Packer } } else if (is_ff(ctx, drv) && innet->driver.port == ctx->id("Q")) { auto fflut = fflutPairs.find(drv->name); - if (fflut != fflutPairs.end() && procdLuts.find(fflut->second) == procdLuts.end()) { + if (fflut != fflutPairs.end() && fflut->second != ci->name && + procdLuts.find(fflut->second) == procdLuts.end()) { if (can_pack_lutff(ci->name, fflut->second)) { procdLuts.insert(ci->name); procdLuts.insert(fflut->second); @@ -356,6 +359,32 @@ class Ecp5Packer flush_cells(); } + void set_lut_input_constant(CellInfo *cell, IdString input, bool value) + { + int index = std::string("ABCD").find(input.str(ctx)); + int init = int_or_default(cell->params, ctx->id("INIT")); + int new_init = 0; + for (int i = 0; i < 16; i++) { + if (((i >> index) & 0x1) != value) { + int other_i = (i & (~(1 << index))) | (value << index); + if ((init >> other_i) & 0x1) + new_init |= (1 << i); + } else { + if ((init >> i) & 0x1) + new_init |= (1 << i); + } + } + cell->params[ctx->id("INIT")] = std::to_string(init); + NetInfo *innet = cell->ports.at(input).net; + if (innet != nullptr) { + innet->users.erase( + std::remove_if(innet->users.begin(), innet->users.end(), + [cell, input](PortRef port) { return port.cell == cell && port.port == input; }), + innet->users.end()); + } + cell->ports.at(input).net = nullptr; + } + public: void pack() { diff --git a/ecp5/synth/blinky_nopack.ys b/ecp5/synth/blinky_nopack.ys new file mode 100644 index 00000000..fb359380 --- /dev/null +++ b/ecp5/synth/blinky_nopack.ys @@ -0,0 +1,2 @@ +read_verilog blinky.v +synth_ecp5 -noccu2 -nomux -nodram -json blinky.json diff --git a/generic/archdefs.h b/generic/archdefs.h index 9969014b..f5999776 100644 --- a/generic/archdefs.h +++ b/generic/archdefs.h @@ -52,4 +52,7 @@ typedef IdString PipId; typedef IdString GroupId; typedef IdString DecalId; +struct ArchNetInfo { }; +struct ArchCellInfo { }; + NEXTPNR_NAMESPACE_END diff --git a/gui/yosystab.cc b/gui/yosystab.cc index d83b969e..9bbd9c12 100644 --- a/gui/yosystab.cc +++ b/gui/yosystab.cc @@ -61,9 +61,9 @@ YosysTab::YosysTab(QString folder, QWidget *parent) : QWidget(parent) connect(process, SIGNAL(readyReadStandardError()), this, SLOT(onReadyReadStandardError()));
connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(onReadyReadStandardOutput()));
connect(process, &QProcess::started, this, [this] { lineEdit->setEnabled(true); });
-/*
+
#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0)
- connect(process, &QProcess::error, this, [this](QProcess::ProcessError error) {
+ connect(process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error), this, [this](QProcess::ProcessError error) {
#else
connect(process, &QProcess::errorOccurred, this, [this](QProcess::ProcessError error) {
#endif
@@ -74,7 +74,6 @@ YosysTab::YosysTab(QString folder, QWidget *parent) : QWidget(parent) Q_EMIT deleteLater();
}
});
-*/
process->setWorkingDirectory(folder);
process->start("yosys");
}
diff --git a/ice40/archdefs.h b/ice40/archdefs.h index 75df678a..ce7d3f52 100644 --- a/ice40/archdefs.h +++ b/ice40/archdefs.h @@ -150,6 +150,9 @@ struct DecalId bool operator!=(const DecalId &other) const { return (type != other.type) || (index != other.index); } }; +struct ArchNetInfo { }; +struct ArchCellInfo { }; + NEXTPNR_NAMESPACE_END namespace std { @@ -201,5 +204,4 @@ template <> struct hash<NEXTPNR_NAMESPACE_PREFIX DecalId> return seed; } }; - } // namespace std |