From 5d1b87b0a4e138726d751590728cdcc2f12f6192 Mon Sep 17 00:00:00 2001 From: David Shah Date: Wed, 20 Jun 2018 11:19:25 +0200 Subject: place_sa: Set placement strengths Signed-off-by: David Shah --- common/place_sa.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/common/place_sa.cc b/common/place_sa.cc index 0fead5d8..442559b0 100644 --- a/common/place_sa.cc +++ b/common/place_sa.cc @@ -100,6 +100,7 @@ class SAPlacer } cell->bel = bel; + cell->belStrength = STRENGTH_USER; ctx->bindBel(bel, cell->name); locked_bels.insert(bel); placed_cells++; @@ -214,9 +215,9 @@ class SAPlacer } // Final post-pacement validitiy check for (auto bel : ctx->getBels()) { + IdString cell = ctx->getBelCell(bel, false); if (!checker->isBelLocationValid(bel)) { std::string cell_text = "no cell"; - IdString cell = ctx->getBelCell(bel, false); if (cell != IdString()) cell_text = std::string("cell '") + cell.str(ctx) + "'"; log_error("post-placement validity check failed for Bel '%s' " @@ -276,6 +277,7 @@ class SAPlacer all_placed = true; } cell->bel = best_bel; + cell->belStrength = STRENGTH_WEAK; ctx->bindBel(cell->bel, cell->name); // Back annotate location -- cgit v1.2.3 From 1436ae21a2d9a214f7585deb2f038ff87ce4862c Mon Sep 17 00:00:00 2001 From: David Shah Date: Wed, 20 Jun 2018 11:44:28 +0200 Subject: Adding stubs for delay annotation and cell timing lookup Signed-off-by: David Shah --- common/nextpnr.h | 10 +++++----- common/timing.cc | 29 +++++++++++++++++++++++++++++ common/timing.h | 28 ++++++++++++++++++++++++++++ dummy/arch.cc | 18 ++++++++++++++++++ dummy/arch.h | 7 +++++++ frontend/json/jsonparse.cc | 2 +- ice40/arch.cc | 21 +++++++++++++++++++++ ice40/arch.h | 10 ++++++++++ 8 files changed, 119 insertions(+), 6 deletions(-) create mode 100644 common/timing.cc create mode 100644 common/timing.h 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/timing.cc b/common/timing.cc new file mode 100644 index 00000000..352ca94a --- /dev/null +++ b/common/timing.cc @@ -0,0 +1,29 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 David Shah + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "timing.h" +#include "log.h" +#include +#include +#include + +void assign_budget(Context *ctx, float default_clock = 12e6) +{ + +} diff --git a/common/timing.h b/common/timing.h new file mode 100644 index 00000000..da0cdd9c --- /dev/null +++ b/common/timing.h @@ -0,0 +1,28 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 David Shah + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#ifndef TIMING_H +#define TIMING_H + +#include "nextpnr.h" + +// Assign "budget" values for all user ports in the design +void assign_budget(Context *ctx, float default_clock = 12e6); + +#endif TIMING_H diff --git a/dummy/arch.cc b/dummy/arch.cc index fb54c74f..64841374 100644 --- a/dummy/arch.cc +++ b/dummy/arch.cc @@ -176,4 +176,22 @@ std::vector Arch::getPipGraphics(PipId pip) const return ret; } +// --------------------------------------------------------------- + +delay_t Arch::getCellDelay(const CellInfo *cell, IdString fromPort, + IdString toPort) const +{ + return 0; +} + +IdString Arch::getPortClock(const CellInfo *cell, IdString port) const +{ + return IdString(); +} + +bool Arch::isClockPort(const CellInfo *cell, IdString port) const +{ + return false; +} + NEXTPNR_NAMESPACE_END diff --git a/dummy/arch.h b/dummy/arch.h index 02bec23a..61a09e00 100644 --- a/dummy/arch.h +++ b/dummy/arch.h @@ -32,7 +32,9 @@ struct DelayInfo delay_t delay = 0; delay_t raiseDelay() const { return delay; } + delay_t fallDelay() const { return delay; } + delay_t avgDelay() const { return delay; } DelayInfo operator+(const DelayInfo &other) const @@ -131,6 +133,11 @@ struct Arch : BaseCtx std::unordered_set belGraphicsReload; std::unordered_set wireGraphicsReload; std::unordered_set pipGraphicsReload; + + delay_t getCellDelay(const CellInfo *cell, IdString fromPort, + IdString toPort) const; + IdString getPortClock(const CellInfo *cell, IdString port) const; + bool isClockPort(const CellInfo *cell, IdString port) const; }; NEXTPNR_NAMESPACE_END diff --git a/frontend/json/jsonparse.cc b/frontend/json/jsonparse.cc index afd126fd..8f0ecc35 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 diff --git a/ice40/arch.cc b/ice40/arch.cc index ba372410..380f3386 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -416,4 +416,25 @@ std::vector Arch::getPipGraphics(PipId pip) const return ret; } +// ----------------------------------------------------------------------- + +delay_t Arch::getCellDelay(const CellInfo *cell, IdString fromPort, + IdString toPort) const +{ + // TODO + return 0; +} + +IdString Arch::getPortClock(const CellInfo *cell, IdString port) const +{ + // TODO + return IdString(); +} + +bool Arch::isClockPort(const CellInfo *cell, IdString port) const +{ + // TODO + return false; +} + NEXTPNR_NAMESPACE_END diff --git a/ice40/arch.h b/ice40/arch.h index c1256a41..172541c0 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -755,6 +755,16 @@ struct Arch : BaseCtx std::unordered_set belGraphicsReload; std::unordered_set wireGraphicsReload; std::unordered_set pipGraphicsReload; + + // ------------------------------------------------- + + // Get the delay through a cell from one port to another + delay_t getCellDelay(const CellInfo *cell, IdString fromPort, + IdString toPort) const; + // Get the associated clock to a port, or empty if the port is combinational + IdString getPortClock(const CellInfo *cell, IdString port) const; + // Return true if a port is a clock + bool isClockPort(const CellInfo *cell, IdString port) const; }; NEXTPNR_NAMESPACE_END -- cgit v1.2.3 From 2a41211ce1955a44ca363ba6000c38feb3883e32 Mon Sep 17 00:00:00 2001 From: David Shah Date: Wed, 20 Jun 2018 11:53:49 +0200 Subject: Another stub delay calculation function Signed-off-by: David Shah --- common/timing.cc | 21 ++++++++++++++++++--- common/timing.h | 6 +++++- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/common/timing.cc b/common/timing.cc index 352ca94a..225afb5f 100644 --- a/common/timing.cc +++ b/common/timing.cc @@ -18,12 +18,27 @@ */ #include "timing.h" -#include "log.h" +#include #include #include -#include +#include "log.h" -void assign_budget(Context *ctx, float default_clock = 12e6) +NEXTPNR_NAMESPACE_BEGIN + +// Follow a path, returning budget to annotate +static delay_t follow_path(Context *ctx, const PortRef &begin, int path_length, + delay_t slack) { + if (ctx->getPortClock(begin.cell, begin.port) != IdString()) { + return slack / path_length; + } else { + // ... + } +} +void assign_budget(Context *ctx, float default_clock) +{ + // TODO } + +NEXTPNR_NAMESPACE_END diff --git a/common/timing.h b/common/timing.h index da0cdd9c..03ae048d 100644 --- a/common/timing.h +++ b/common/timing.h @@ -22,7 +22,11 @@ #include "nextpnr.h" +NEXTPNR_NAMESPACE_BEGIN + // Assign "budget" values for all user ports in the design void assign_budget(Context *ctx, float default_clock = 12e6); -#endif TIMING_H +NEXTPNR_NAMESPACE_END + +#endif -- cgit v1.2.3 From 5ca4663294aff1f4af45e9abfffa20c1e44ea017 Mon Sep 17 00:00:00 2001 From: David Shah Date: Wed, 20 Jun 2018 12:21:56 +0200 Subject: Working on the timing budget annnotator Signed-off-by: David Shah --- common/timing.cc | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++------ dummy/arch.cc | 6 +++--- dummy/arch.h | 4 ++-- ice40/arch.cc | 6 +++--- ice40/arch.h | 7 ++++--- 5 files changed, 70 insertions(+), 17 deletions(-) diff --git a/common/timing.cc b/common/timing.cc index 225afb5f..47c82a03 100644 --- a/common/timing.cc +++ b/common/timing.cc @@ -25,20 +25,72 @@ NEXTPNR_NAMESPACE_BEGIN +static delay_t follow_net(Context *ctx, NetInfo *net, int path_length, + delay_t slack); + // Follow a path, returning budget to annotate -static delay_t follow_path(Context *ctx, const PortRef &begin, int path_length, - delay_t slack) +static delay_t follow_user_port(Context *ctx, PortRef &user, int path_length, + delay_t slack) { - if (ctx->getPortClock(begin.cell, begin.port) != IdString()) { - return slack / path_length; + delay_t value; + if (ctx->getPortClock(user.cell, user.port) != IdString()) { + // At the end of a timing path (arguably, should check setup time + // here too) + value = slack / path_length; } else { - // ... + // Default to the path ending here, if no further paths found + value = slack / path_length; + // Follow outputs of the user + for (auto port : user.cell->ports) { + if (port.second.type == PORT_OUT) { + delay_t comb_delay; + // Look up delay through this path + bool is_path = ctx->getCellDelay(user.cell, user.port, + port.first, comb_delay); + if (is_path) { + NetInfo *net = port.second.net; + if (net) { + delay_t path_budget = follow_net(ctx, net, path_length, + slack - comb_delay); + value = std::min(value, path_budget); + } + } + } + } + } + + if (value < user.budget) { + user.budget = value; + } +} + +static delay_t follow_net(Context *ctx, NetInfo *net, int path_length, + delay_t slack) +{ + delay_t net_budget = slack / path_length; + for (auto &usr : net->users) { + net_budget = std::min( + net_budget, follow_user_port(ctx, usr, path_length + 1, slack)); } + return net_budget; } void assign_budget(Context *ctx, float default_clock) { - // TODO + for (auto cell : ctx->cells) { + for (auto port : cell.second->ports) { + if (port.second.type == PORT_OUT) { + IdString clock_domain = + ctx->getPortClock(cell.second, port.first); + if (clock_domain != IdString()) { + delay_t slack = delay_t( + 1.0e12 / default_clock); // TODO: clock constraints + if (port.second.net) + follow_net(ctx, port.second.net, 0, slack); + } + } + } + } } NEXTPNR_NAMESPACE_END diff --git a/dummy/arch.cc b/dummy/arch.cc index 64841374..fa0d8bd3 100644 --- a/dummy/arch.cc +++ b/dummy/arch.cc @@ -178,10 +178,10 @@ std::vector Arch::getPipGraphics(PipId pip) const // --------------------------------------------------------------- -delay_t Arch::getCellDelay(const CellInfo *cell, IdString fromPort, - IdString toPort) const +bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, + IdString toPort, delay_t &delay) const { - return 0; + return false; } IdString Arch::getPortClock(const CellInfo *cell, IdString port) const diff --git a/dummy/arch.h b/dummy/arch.h index 61a09e00..39c48232 100644 --- a/dummy/arch.h +++ b/dummy/arch.h @@ -134,8 +134,8 @@ struct Arch : BaseCtx std::unordered_set wireGraphicsReload; std::unordered_set pipGraphicsReload; - delay_t getCellDelay(const CellInfo *cell, IdString fromPort, - IdString toPort) const; + bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, + delay_t &delay) const; IdString getPortClock(const CellInfo *cell, IdString port) const; bool isClockPort(const CellInfo *cell, IdString port) const; }; diff --git a/ice40/arch.cc b/ice40/arch.cc index 380f3386..7baaef8d 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -418,11 +418,11 @@ std::vector Arch::getPipGraphics(PipId pip) const // ----------------------------------------------------------------------- -delay_t Arch::getCellDelay(const CellInfo *cell, IdString fromPort, - IdString toPort) const +bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, + IdString toPort, delay_t &delay) const { // TODO - return 0; + return false; } IdString Arch::getPortClock(const CellInfo *cell, IdString port) const diff --git a/ice40/arch.h b/ice40/arch.h index 172541c0..356f88da 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -758,9 +758,10 @@ struct Arch : BaseCtx // ------------------------------------------------- - // Get the delay through a cell from one port to another - delay_t getCellDelay(const CellInfo *cell, IdString fromPort, - IdString toPort) const; + // Get the delay through a cell from one port to another, returning false + // if no path exists + bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, + delay_t &delay) const; // Get the associated clock to a port, or empty if the port is combinational IdString getPortClock(const CellInfo *cell, IdString port) const; // Return true if a port is a clock -- cgit v1.2.3 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