From 6d2f058f678761e90fc451af48f4e0ed0f504603 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 20 Jun 2018 12:34:06 +0200 Subject: Added context menus for python and info tab --- gui/infotab.cc | 17 +++++++++++++++++ gui/infotab.h | 5 +++++ gui/pythontab.cc | 17 +++++++++++++++++ gui/pythontab.h | 4 ++++ 4 files changed, 43 insertions(+) diff --git a/gui/infotab.cc b/gui/infotab.cc index a5659569..7690b83c 100644 --- a/gui/infotab.cc +++ b/gui/infotab.cc @@ -9,6 +9,16 @@ InfoTab::InfoTab(QWidget *parent) : QWidget(parent) f.setStyleHint(QFont::Monospace); plainTextEdit->setFont(f); + plainTextEdit->setContextMenuPolicy(Qt::CustomContextMenu); + QAction *clearAction = new QAction("Clear &buffer", this); + clearAction->setStatusTip("Clears display buffer"); + connect(clearAction, SIGNAL(triggered()), this, SLOT(clearBuffer())); + contextMenu = plainTextEdit->createStandardContextMenu(); + contextMenu->addSeparator(); + contextMenu->addAction(clearAction); + connect(plainTextEdit, SIGNAL(customContextMenuRequested(const QPoint)), + this, SLOT(showContextMenu(const QPoint))); + QGridLayout *mainLayout = new QGridLayout(); mainLayout->addWidget(plainTextEdit); setLayout(mainLayout); @@ -20,3 +30,10 @@ void InfoTab::info(std::string str) plainTextEdit->insertPlainText(str.c_str()); plainTextEdit->moveCursor(QTextCursor::End); } + +void InfoTab::showContextMenu(const QPoint &pt) +{ + contextMenu->exec(mapToGlobal(pt)); +} + +void InfoTab::clearBuffer() { plainTextEdit->clear(); } diff --git a/gui/infotab.h b/gui/infotab.h index e3c58ba5..d7f1408c 100644 --- a/gui/infotab.h +++ b/gui/infotab.h @@ -1,6 +1,7 @@ #ifndef INFOTAB_H #define INFOTAB_H +#include #include #include "nextpnr.h" @@ -14,9 +15,13 @@ class InfoTab : public QWidget public: explicit InfoTab(QWidget *parent = 0); void info(std::string str); + private Q_SLOTS: + void showContextMenu(const QPoint &pt); + void clearBuffer(); private: QPlainTextEdit *plainTextEdit; + QMenu *contextMenu; }; #endif // INFOTAB_H diff --git a/gui/pythontab.cc b/gui/pythontab.cc index 04db056d..96a6c4b9 100644 --- a/gui/pythontab.cc +++ b/gui/pythontab.cc @@ -15,6 +15,16 @@ PythonTab::PythonTab(QWidget *parent) : QWidget(parent) f.setStyleHint(QFont::Monospace); plainTextEdit->setFont(f); + plainTextEdit->setContextMenuPolicy(Qt::CustomContextMenu); + QAction *clearAction = new QAction("Clear &buffer", this); + clearAction->setStatusTip("Clears display buffer"); + connect(clearAction, SIGNAL(triggered()), this, SLOT(clearBuffer())); + contextMenu = plainTextEdit->createStandardContextMenu(); + contextMenu->addSeparator(); + contextMenu->addAction(clearAction); + connect(plainTextEdit, SIGNAL(customContextMenuRequested(const QPoint)), + this, SLOT(showContextMenu(const QPoint))); + lineEdit = new LineEditor(); lineEdit->setMinimumHeight(30); lineEdit->setMaximumHeight(30); @@ -98,3 +108,10 @@ void PythonTab::editLineReturnPressed(QString text) print(std::string(">>> " + input + "\n")); int error = executePython(input); } + +void PythonTab::showContextMenu(const QPoint &pt) +{ + contextMenu->exec(mapToGlobal(pt)); +} + +void PythonTab::clearBuffer() { plainTextEdit->clear(); } \ No newline at end of file diff --git a/gui/pythontab.h b/gui/pythontab.h index 3876b3df..5aed8b0b 100644 --- a/gui/pythontab.h +++ b/gui/pythontab.h @@ -2,6 +2,7 @@ #define PYTHONTAB_H #include +#include #include #include "emb.h" #include "line_editor.h" @@ -22,10 +23,13 @@ class PythonTab : public QWidget int executePython(std::string &command); private Q_SLOTS: void editLineReturnPressed(QString text); + void showContextMenu(const QPoint &pt); + void clearBuffer(); private: QPlainTextEdit *plainTextEdit; LineEditor *lineEdit; + QMenu *contextMenu; emb::stdout_write_type write; }; -- cgit v1.2.3 From c3837027b22b67a5079d84419bae20c4d545430b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 20 Jun 2018 12:50:38 +0200 Subject: Add better iCE40 delay estimates Signed-off-by: Clifford Wolf --- common/nextpnr.h | 10 ++--- common/route.cc | 16 ++++---- dummy/arch.h | 2 + ice40/arch.h | 17 +++++++- ice40/chipdb.py | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 145 insertions(+), 18 deletions(-) diff --git a/common/nextpnr.h b/common/nextpnr.h index c59b401e..5ccbf057 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -17,13 +17,13 @@ * */ +#include #include #include #include #include #include #include -#include #ifndef NEXTPNR_H #define NEXTPNR_H @@ -196,12 +196,12 @@ struct CellInfo; enum PlaceStrength { - STRENGTH_NONE = 0, - STRENGTH_WEAK = 1, + STRENGTH_NONE = 0, + STRENGTH_WEAK = 1, STRENGTH_STRONG = 2, - STRENGTH_FIXED = 3, + STRENGTH_FIXED = 3, STRENGTH_LOCKED = 4, - STRENGTH_USER = 5 + STRENGTH_USER = 5 }; struct PortRef diff --git a/common/route.cc b/common/route.cc index b031237c..42a705a1 100644 --- a/common/route.cc +++ b/common/route.cc @@ -206,15 +206,16 @@ struct Router assert(next_delay >= 0); if (visited.count(next_wire)) { - if (visited.at(next_wire).delay <= next_delay + 1e-3) + if (visited.at(next_wire).delay <= + next_delay + ctx->getDelayEpsilon()) continue; #if 0 // FIXME if (ctx->verbose) log("Found better route to %s. Old vs new delay " - "estimate: %.2f %.2f\n", + "estimate: %.3f %.3f\n", ctx->getWireName(next_wire).c_str(), - float(visited.at(next_wire).delay), - float(next_delay)); + ctx->getDelayNS(visited.at(next_wire).delay), + ctx->getDelayNS(next_delay)); #endif revisitCnt++; } @@ -246,8 +247,8 @@ struct Router } if (ctx->verbose) - log(" Final path delay: %.2f\n", - float(visited[dst_wire].delay)); + log(" Final path delay: %.3f\n", + ctx->getDelayNS(visited[dst_wire].delay)); maxDelay = fmaxf(maxDelay, visited[dst_wire].delay); if (ctx->verbose) @@ -257,7 +258,8 @@ struct Router while (1) { if (ctx->verbose) - log(" %8.2f %s\n", float(visited[cursor].delay), + log(" %8.3f %s\n", + ctx->getDelayNS(visited[cursor].delay), ctx->getWireName(cursor).c_str(ctx)); if (src_wires.count(cursor)) diff --git a/dummy/arch.h b/dummy/arch.h index 02bec23a..7ceda3b3 100644 --- a/dummy/arch.h +++ b/dummy/arch.h @@ -120,6 +120,8 @@ struct Arch : BaseCtx bool estimatePosition(BelId bel, int &x, int &y) const; delay_t estimateDelay(WireId src, WireId dst) const; + delay_t getDelayEpsilon() const { return 0.01; } + float getDelayNS(delay_t v) const { return v; } std::vector getFrameGraphics() const; std::vector getBelGraphics(BelId bel) const; diff --git a/ice40/arch.h b/ice40/arch.h index c1256a41..4a2f6e50 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -63,6 +63,17 @@ enum PortPin : int32_t PIN_MAXIDX }; +enum WireType : int8_t +{ + WIRE_TYPE_NONE = 0, + WIRE_TYPE_LOCAL = 1, + WIRE_TYPE_GLOBAL = 2, + WIRE_TYPE_SP4_VERT = 3, + WIRE_TYPE_SP4_HORZ = 4, + WIRE_TYPE_SP12_HORZ = 5, + WIRE_TYPE_SP12_VERT = 6 +}; + // ----------------------------------------------------------------------- /**** Everything in this section must be kept in sync with chipdb.py ****/ @@ -130,7 +141,9 @@ struct WireInfoPOD BelPortPOD bel_uphill; RelPtr bels_downhill; - int16_t x, y; + int8_t x, y; + WireType type; + int8_t padding_0; } __attribute__((packed)); struct PackagePinPOD @@ -742,6 +755,8 @@ struct Arch : BaseCtx bool estimatePosition(BelId bel, int &x, int &y) const; delay_t estimateDelay(WireId src, WireId dst) const; + delay_t getDelayEpsilon() const { return 10; } + float getDelayNS(delay_t v) const { return v * 0.001; } // ------------------------------------------------- diff --git a/ice40/chipdb.py b/ice40/chipdb.py index 129c71ed..67d24713 100644 --- a/ice40/chipdb.py +++ b/ice40/chipdb.py @@ -45,6 +45,7 @@ cbit_re = re.compile(r'B(\d+)\[(\d+)\]') portpins = dict() beltypes = dict() tiletypes = dict() +wiretypes = dict() with open("ice40/portpins.inc") as f: for line in f: @@ -69,9 +70,30 @@ tiletypes["IO"] = 2 tiletypes["RAMB"] = 3 tiletypes["RAMT"] = 4 +wiretypes["LOCAL"] = 1 +wiretypes["GLOBAL"] = 2 +wiretypes["SP4_VERT"] = 5 +wiretypes["SP4_HORZ"] = 6 +wiretypes["SP12_HORZ"] = 7 +wiretypes["SP12_VERT"] = 8 + def maj_wire_name(name): - if re.match(r"lutff_\d/(in|out)", name[2]): + if name[2].startswith("lutff_"): + return True + if name[2].startswith("io_"): + return True + if name[2].startswith("ram/"): return True + if name[2].startswith("sp4_h_r_"): + return name[2] in ("sp4_h_r_0", "sp4_h_r_1", "sp4_h_r_2", "sp4_h_r_3", "sp4_h_r_4", "sp4_h_r_5", + "sp4_h_r_6", "sp4_h_r_7", "sp4_h_r_8", "sp4_h_r_9", "sp4_h_r_10", "sp4_h_r_11") + if name[2].startswith("sp4_v_b_"): + return name[2] in ("sp4_v_b_0", "sp4_v_b_1", "sp4_v_b_2", "sp4_v_b_3", "sp4_v_b_4", "sp4_v_b_5", + "sp4_v_b_6", "sp4_v_b_7", "sp4_v_b_8", "sp4_v_b_9", "sp4_v_b_10", "sp4_v_b_11") + if name[2].startswith("sp12_h_r_"): + return name[2] in ("sp12_h_r_0", "sp12_h_r_1") + if name[2].startswith("sp12_v_b_"): + return name[2] in ("sp12_v_b_0", "sp12_v_b_1") return False def cmp_wire_names(newname, oldname): @@ -79,8 +101,92 @@ def cmp_wire_names(newname, oldname): return True if maj_wire_name(oldname): return False + + if newname[2].startswith("sp") and oldname[2].startswith("sp"): + m1 = re.match(r".*_(\d+)$", newname[2]) + m2 = re.match(r".*_(\d+)$", oldname[2]) + if m1 and m2: + idx1 = int(m1.group(1)) + idx2 = int(m2.group(1)) + if idx1 != idx2: + return idx1 < idx2 + return newname < oldname +def wire_type(name): + longname = name + name = name.split('/')[-1] + wt = None + + if name.startswith("glb_netwk_"): + wt = "GLOBAL" + elif name.startswith("D_IN_") or name.startswith("D_OUT_"): + wt = "LOCAL" + elif name in ("OUT_ENB", "cen", "inclk", "latch", "outclk", "clk", "s_r", "carry_in", "carry_in_mux"): + wt = "LOCAL" + elif name in ("in_0", "in_1", "in_2", "in_3", "cout", "lout", "out", "fabout"): + wt = "LOCAL" + elif name.startswith("local_g") or name.startswith("glb2local_"): + wt = "LOCAL" + elif name.startswith("span4_horz_") or name.startswith("sp4_h_"): + wt = "SP4_HORZ" + elif name.startswith("span4_vert_") or name.startswith("sp4_v_") or name.startswith("sp4_r_v_"): + wt = "SP4_VERT" + elif name.startswith("span12_horz_") or name.startswith("sp12_h_"): + wt = "SP12_HORZ" + elif name.startswith("span12_vert_") or name.startswith("sp12_v_"): + wt = "SP12_VERT" + elif name.startswith("MASK_") or name.startswith("RADDR_") or name.startswith("WADDR_"): + wt = "LOCAL" + elif name.startswith("RDATA_") or name.startswith("WDATA_") or name.startswith("neigh_op_"): + wt = "LOCAL" + elif name in ("WCLK", "WCLKE", "WE", "RCLK", "RCLKE", "RE"): + wt = "LOCAL" + + if wt is None: + print("No type for wire: %s (%s)" % (longname, name), file=sys.stderr) + assert 0 + return wt + +def pipdelay(src, dst): + src = wire_names_r[src] + dst = wire_names_r[dst] + src_type = wire_type(src[2]) + dst_type = wire_type(dst[2]) + + if src_type == "LOCAL" and dst_type == "LOCAL": + return 250 + + if src_type == "GLOBAL" and dst_type == "LOCAL": + return 400 + + # Local -> Span + + if src_type == "LOCAL" and dst_type in ("SP4_HORZ", "SP4_VERT"): + return 350 + + if src_type == "LOCAL" and dst_type in ("SP12_HORZ", "SP12_VERT"): + return 500 + + # Span -> Local + + if src_type in ("SP4_HORZ", "SP4_VERT", "SP12_HORZ", "SP12_VERT") and dst_type == "LOCAL": + return 300 + + # Span -> Span + + if src_type in ("SP12_HORZ", "SP12_VERT") and dst_type in ("SP12_HORZ", "SP12_VERT"): + return 450 + + if src_type in ("SP4_HORZ", "SP4_VERT") and dst_type in ("SP4_HORZ", "SP4_VERT"): + return 300 + + if src_type in ("SP12_HORZ", "SP12_VERT") and dst_type in ("SP4_HORZ", "SP4_VERT"): + return 380 + + # print(src, dst, src_type, dst_type, file=sys.stderr) + assert 0 + with open(sys.argv[1], "r") as f: mode = None @@ -663,7 +769,7 @@ for wire in range(num_wires): pi = dict() pi["src"] = src pi["dst"] = wire - pi["delay"] = 1 + pi["delay"] = pipdelay(src, wire) pi["x"] = pip_xy[(src, wire)][0] pi["y"] = pip_xy[(src, wire)][1] pi["switch_mask"] = pip_xy[(src, wire)][2] @@ -687,7 +793,7 @@ for wire in range(num_wires): pi = dict() pi["src"] = wire pi["dst"] = dst - pi["delay"] = 1 + pi["delay"] = pipdelay(wire, dst) pi["x"] = pip_xy[(wire, dst)][0] pi["y"] = pip_xy[(wire, dst)][1] pi["switch_mask"] = pip_xy[(wire, dst)][2] @@ -809,8 +915,10 @@ for info in wireinfo: bba.u32(info["uphill_bel"], "bel_uphill.bel_index") bba.u32(info["uphill_pin"], "bel_uphill.port") bba.r(info["list_bels_downhill"], "bels_downhill") - bba.u16(info["x"], "x") - bba.u16(info["y"], "y") + bba.u8(info["x"], "x") + bba.u8(info["y"], "y") + bba.u8(wiretypes[wire_type(info["name"])], "type") + bba.u8(0, "padding") bba.l("pip_data_%s" % dev_name, "PipInfoPOD") for info in pipinfo: -- cgit v1.2.3 From cb9c6c6ef271a6f5297d74c81807bca01a0d8319 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 20 Jun 2018 12:57:38 +0200 Subject: Changes to estimatePosition API Signed-off-by: Clifford Wolf --- common/place_sa.cc | 19 ++++++++++--------- dummy/arch.cc | 8 ++++---- dummy/arch.h | 2 +- ice40/arch.cc | 5 ++--- ice40/arch.h | 2 +- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/common/place_sa.cc b/common/place_sa.cc index 0fead5d8..3162d88c 100644 --- a/common/place_sa.cc +++ b/common/place_sa.cc @@ -51,7 +51,8 @@ class SAPlacer int num_bel_types = 0; for (auto bel : ctx->getBels()) { int x, y; - ctx->estimatePosition(bel, x, y); + bool gb; + ctx->estimatePosition(bel, x, y, gb); BelType type = ctx->getBelType(bel); int type_idx; if (bel_types.find(type) == bel_types.end()) { @@ -288,18 +289,17 @@ class SAPlacer float get_wirelength(NetInfo *net) { float wirelength = 0; - int driver_x = 0, driver_y = 0; - bool consider_driver = false; + int driver_x, driver_y; + bool driver_gb; CellInfo *driver_cell = net->driver.cell; if (!driver_cell) return 0; if (driver_cell->bel == BelId()) return 0; - consider_driver = - ctx->estimatePosition(driver_cell->bel, driver_x, driver_y); + ctx->estimatePosition(driver_cell->bel, driver_x, driver_y, driver_gb); WireId drv_wire = ctx->getWireBelPin( driver_cell->bel, ctx->portPinFromId(net->driver.port)); - if (!consider_driver) + if (driver_gb) return 0; for (auto load : net->users) { if (load.cell == nullptr) @@ -307,7 +307,7 @@ class SAPlacer CellInfo *load_cell = load.cell; if (load_cell->bel == BelId()) continue; - // ctx->estimatePosition(load_cell->bel, load_x, load_y); + // ctx->estimatePosition(load_cell->bel, load_x, load_y, load_gb); WireId user_wire = ctx->getWireBelPin( load_cell->bel, ctx->portPinFromId(load.port)); // wirelength += std::abs(load_x - driver_x) + std::abs(load_y - @@ -405,8 +405,9 @@ class SAPlacer BelId random_bel_for_cell(CellInfo *cell) { BelType targetType = ctx->belTypeFromId(cell->type); - int x = 0, y = 0; - ctx->estimatePosition(cell->bel, x, y); + int x, y; + bool gb; + ctx->estimatePosition(cell->bel, x, y, gb); while (true) { int nx = ctx->rng(2 * diameter + 1) + std::max(x - diameter, 0); int ny = ctx->rng(2 * diameter + 1) + std::max(y - diameter, 0); diff --git a/dummy/arch.cc b/dummy/arch.cc index fb54c74f..58298c4e 100644 --- a/dummy/arch.cc +++ b/dummy/arch.cc @@ -141,11 +141,11 @@ const std::vector &Arch::getWireAliases(WireId wire) const // --------------------------------------------------------------- -bool Arch::estimatePosition(BelId bel, int &x, int &y) const +void Arch::estimatePosition(BelId bel, int &x, int &y, bool &gb) const { - x = 0.0; - y = 0.0; - return false; + x = 0; + y = 0; + gb = false; } delay_t Arch::estimateDelay(WireId src, WireId dst) const { return 0.0; } diff --git a/dummy/arch.h b/dummy/arch.h index 7ceda3b3..925c231f 100644 --- a/dummy/arch.h +++ b/dummy/arch.h @@ -118,7 +118,7 @@ struct Arch : BaseCtx const std::vector &getPipsUphill(WireId wire) const; const std::vector &getWireAliases(WireId wire) const; - bool estimatePosition(BelId bel, int &x, int &y) const; + void estimatePosition(BelId bel, int &x, int &y, bool &gb) const; delay_t estimateDelay(WireId src, WireId dst) const; delay_t getDelayEpsilon() const { return 0.01; } float getDelayNS(delay_t v) const { return v; } diff --git a/ice40/arch.cc b/ice40/arch.cc index ba372410..3dcd9cb0 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -295,13 +295,12 @@ std::string Arch::getBelPackagePin(BelId bel) const } // ----------------------------------------------------------------------- -bool Arch::estimatePosition(BelId bel, int &x, int &y) const +void Arch::estimatePosition(BelId bel, int &x, int &y, bool &gb) const { assert(bel != BelId()); x = chip_info->bel_data[bel.index].x; y = chip_info->bel_data[bel.index].y; - - return chip_info->bel_data[bel.index].type != TYPE_SB_GB; + gb = chip_info->bel_data[bel.index].type == TYPE_SB_GB; } delay_t Arch::estimateDelay(WireId src, WireId dst) const diff --git a/ice40/arch.h b/ice40/arch.h index 4a2f6e50..d9631c11 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -753,7 +753,7 @@ struct Arch : BaseCtx // ------------------------------------------------- - bool estimatePosition(BelId bel, int &x, int &y) const; + void estimatePosition(BelId bel, int &x, int &y, bool &gb) const; delay_t estimateDelay(WireId src, WireId dst) const; delay_t getDelayEpsilon() const { return 10; } float getDelayNS(delay_t v) const { return v * 0.001; } -- cgit v1.2.3 From 7c3593ea5acef05546be8835e25cf5e4b18549ee Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 20 Jun 2018 12:57:59 +0200 Subject: Updates from clangformat Signed-off-by: Clifford Wolf --- common/place_sa.cc | 5 +++-- frontend/json/jsonparse.cc | 13 ++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/common/place_sa.cc b/common/place_sa.cc index 3162d88c..55ec9b9a 100644 --- a/common/place_sa.cc +++ b/common/place_sa.cc @@ -374,8 +374,9 @@ class SAPlacer delta = new_wirelength - curr_wirelength; n_move++; // SA acceptance criterea - if (delta < 0 || (temp > 1e-6 && (ctx->rng() / float(0x3fffffff)) <= - std::exp(-delta / temp))) { + if (delta < 0 || + (temp > 1e-6 && + (ctx->rng() / float(0x3fffffff)) <= std::exp(-delta / temp))) { n_accept++; if (delta < 0) improved = true; diff --git a/frontend/json/jsonparse.cc b/frontend/json/jsonparse.cc index afd126fd..9add256e 100644 --- a/frontend/json/jsonparse.cc +++ b/frontend/json/jsonparse.cc @@ -26,8 +26,8 @@ #include #include #include -#include #include +#include #include "nextpnr.h" NEXTPNR_NAMESPACE_BEGIN @@ -749,12 +749,11 @@ void json_import(Context *ctx, string modname, JsonNode *node) int netid = bits->data_array.at(i)->data_number; if (netid >= netnames.size()) netnames.resize(netid + 1); - netnames.at(netid) = - ctx->id(basename + - (num_bits == 1 ? "" - : std::string("[") + - std::to_string(i) + - std::string("]"))); + netnames.at(netid) = ctx->id( + basename + + (num_bits == 1 ? "" : std::string("[") + + std::to_string(i) + + std::string("]"))); } } } -- cgit v1.2.3