aboutsummaryrefslogtreecommitdiffstats
path: root/gui
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2018-06-23 16:14:39 +0200
committerClifford Wolf <clifford@clifford.at>2018-06-23 16:14:39 +0200
commit0ccd9febebdb7f2de700d116a8498f23de093e88 (patch)
tree094f717951a81fd91d01e3d776695629f354d089 /gui
parenta40d9dc514b680538d0ffa99873974a15bff9e97 (diff)
parent1e8840b0f9400a1dc17ba6c7496314f82f0db2e1 (diff)
downloadnextpnr-0ccd9febebdb7f2de700d116a8498f23de093e88.tar.gz
nextpnr-0ccd9febebdb7f2de700d116a8498f23de093e88.tar.bz2
nextpnr-0ccd9febebdb7f2de700d116a8498f23de093e88.zip
Merge branch 'master' of gitlab.com:SymbioticEDA/nextpnr
Diffstat (limited to 'gui')
-rw-r--r--gui/basewindow.cc6
-rw-r--r--gui/designwidget.cc58
-rw-r--r--gui/dummy/mainwindow.cc3
-rw-r--r--gui/fpgaviewwidget.cc49
-rw-r--r--gui/fpgaviewwidget.h28
-rw-r--r--gui/ice40/mainwindow.cc61
-rw-r--r--gui/ice40/mainwindow.h12
-rw-r--r--gui/ice40/nextpnr.qrc1
-rw-r--r--gui/ice40/resources/time_add.pngbin0 -> 827 bytes
-rw-r--r--gui/ice40/worker.cc31
-rw-r--r--gui/ice40/worker.h8
-rw-r--r--gui/infotab.cc8
-rw-r--r--gui/line_editor.cc8
-rw-r--r--gui/pythontab.cc20
14 files changed, 142 insertions, 151 deletions
diff --git a/gui/basewindow.cc b/gui/basewindow.cc
index 9d99152c..8e90a8ea 100644
--- a/gui/basewindow.cc
+++ b/gui/basewindow.cc
@@ -36,8 +36,7 @@ static void initBasenameResource() { Q_INIT_RESOURCE(base); }
NEXTPNR_NAMESPACE_BEGIN
-BaseMainWindow::BaseMainWindow(Context *_ctx, QWidget *parent)
- : QMainWindow(parent), ctx(_ctx)
+BaseMainWindow::BaseMainWindow(Context *_ctx, QWidget *parent) : QMainWindow(parent), ctx(_ctx)
{
initBasenameResource();
qRegisterMetaType<std::string>();
@@ -69,8 +68,7 @@ BaseMainWindow::BaseMainWindow(Context *_ctx, QWidget *parent)
designview->setMaximumWidth(300);
splitter_h->addWidget(designview);
- connect(designview, SIGNAL(info(std::string)), this,
- SLOT(writeInfo(std::string)));
+ connect(designview, SIGNAL(info(std::string)), this, SLOT(writeInfo(std::string)));
tabWidget = new QTabWidget();
#ifndef NO_PYTHON
diff --git a/gui/designwidget.cc b/gui/designwidget.cc
index 6752b780..c2bc158d 100644
--- a/gui/designwidget.cc
+++ b/gui/designwidget.cc
@@ -37,10 +37,7 @@ enum class ElementType
class ElementTreeItem : public QTreeWidgetItem
{
public:
- ElementTreeItem(ElementType t, QString str)
- : QTreeWidgetItem((QTreeWidget *)nullptr, QStringList(str)), type(t)
- {
- }
+ ElementTreeItem(ElementType t, QString str) : QTreeWidgetItem((QTreeWidget *)nullptr, QStringList(str)), type(t) {}
virtual ~ElementTreeItem(){};
ElementType getType() { return type; };
@@ -52,11 +49,7 @@ class ElementTreeItem : public QTreeWidgetItem
class BelTreeItem : public ElementTreeItem
{
public:
- BelTreeItem(IdString d, ElementType type, QString str)
- : ElementTreeItem(type, str)
- {
- this->data = d;
- }
+ BelTreeItem(IdString d, ElementType type, QString str) : ElementTreeItem(type, str) { this->data = d; }
virtual ~BelTreeItem(){};
IdString getData() { return this->data; };
@@ -68,11 +61,7 @@ class BelTreeItem : public ElementTreeItem
class WireTreeItem : public ElementTreeItem
{
public:
- WireTreeItem(IdString d, ElementType type, QString str)
- : ElementTreeItem(type, str)
- {
- this->data = d;
- }
+ WireTreeItem(IdString d, ElementType type, QString str) : ElementTreeItem(type, str) { this->data = d; }
virtual ~WireTreeItem(){};
IdString getData() { return this->data; };
@@ -84,11 +73,7 @@ class WireTreeItem : public ElementTreeItem
class PipTreeItem : public ElementTreeItem
{
public:
- PipTreeItem(IdString d, ElementType type, QString str)
- : ElementTreeItem(type, str)
- {
- this->data = d;
- }
+ PipTreeItem(IdString d, ElementType type, QString str) : ElementTreeItem(type, str) { this->data = d; }
virtual ~PipTreeItem(){};
IdString getData() { return this->data; };
@@ -97,8 +82,7 @@ class PipTreeItem : public ElementTreeItem
IdString data;
};
-DesignWidget::DesignWidget(Context *_ctx, QWidget *parent)
- : QWidget(parent), ctx(_ctx)
+DesignWidget::DesignWidget(Context *_ctx, QWidget *parent) : QWidget(parent), ctx(_ctx)
{
treeWidget = new QTreeWidget();
@@ -115,8 +99,7 @@ DesignWidget::DesignWidget(Context *_ctx, QWidget *parent)
QList<QTreeWidgetItem *> bel_items;
for (auto bel : ctx->getBels()) {
auto name = ctx->getBelName(bel);
- bel_items.append(new BelTreeItem(name, ElementType::BEL,
- QString(name.c_str(ctx))));
+ bel_items.append(new BelTreeItem(name, ElementType::BEL, QString(name.c_str(ctx))));
}
bel_root->addChildren(bel_items);
@@ -127,8 +110,7 @@ DesignWidget::DesignWidget(Context *_ctx, QWidget *parent)
treeWidget->insertTopLevelItem(0, wire_root);
for (auto wire : ctx->getWires()) {
auto name = ctx->getWireName(wire);
- wire_items.append(new WireTreeItem(name, ElementType::WIRE,
- QString(name.c_str(ctx))));
+ wire_items.append(new WireTreeItem(name, ElementType::WIRE, QString(name.c_str(ctx))));
}
wire_root->addChildren(wire_items);
@@ -139,8 +121,7 @@ DesignWidget::DesignWidget(Context *_ctx, QWidget *parent)
treeWidget->insertTopLevelItem(0, pip_root);
for (auto pip : ctx->getPips()) {
auto name = ctx->getPipName(pip);
- pip_items.append(new PipTreeItem(name, ElementType::PIP,
- QString(name.c_str(ctx))));
+ pip_items.append(new PipTreeItem(name, ElementType::PIP, QString(name.c_str(ctx))));
}
pip_root->addChildren(pip_items);
@@ -165,11 +146,9 @@ DesignWidget::DesignWidget(Context *_ctx, QWidget *parent)
setLayout(mainLayout);
// Connection
- connect(treeWidget, &QTreeWidget::customContextMenuRequested, this,
- &DesignWidget::prepareMenu);
+ connect(treeWidget, &QTreeWidget::customContextMenuRequested, this, &DesignWidget::prepareMenu);
- connect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)),
- SLOT(onItemClicked(QTreeWidgetItem *, int)));
+ connect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), SLOT(onItemClicked(QTreeWidgetItem *, int)));
}
DesignWidget::~DesignWidget()
@@ -188,8 +167,7 @@ void DesignWidget::addProperty(QtVariantProperty *property, const QString &id)
void DesignWidget::clearProperties()
{
- QMap<QtProperty *, QString>::ConstIterator itProp =
- propertyToId.constBegin();
+ QMap<QtProperty *, QString>::ConstIterator itProp = propertyToId.constBegin();
while (itProp != propertyToId.constEnd()) {
delete itProp.key();
itProp++;
@@ -210,23 +188,20 @@ void DesignWidget::onItemClicked(QTreeWidgetItem *item, int pos)
if (type == ElementType::BEL) {
IdString c = static_cast<BelTreeItem *>(item)->getData();
- QtVariantProperty *topItem =
- variantManager->addProperty(QVariant::String, QString("Name"));
+ QtVariantProperty *topItem = variantManager->addProperty(QVariant::String, QString("Name"));
topItem->setValue(QString(c.c_str(ctx)));
addProperty(topItem, QString("Name"));
} else if (type == ElementType::WIRE) {
IdString c = static_cast<WireTreeItem *>(item)->getData();
- QtVariantProperty *topItem =
- variantManager->addProperty(QVariant::String, QString("Name"));
+ QtVariantProperty *topItem = variantManager->addProperty(QVariant::String, QString("Name"));
topItem->setValue(QString(c.c_str(ctx)));
addProperty(topItem, QString("Name"));
} else if (type == ElementType::PIP) {
IdString c = static_cast<PipTreeItem *>(item)->getData();
- QtVariantProperty *topItem =
- variantManager->addProperty(QVariant::String, QString("Name"));
+ QtVariantProperty *topItem = variantManager->addProperty(QVariant::String, QString("Name"));
topItem->setValue(QString(c.c_str(ctx)));
addProperty(topItem, QString("Name"));
}
@@ -250,9 +225,6 @@ void DesignWidget::prepareMenu(const QPoint &pos)
menu.exec(tree->mapToGlobal(pos));
}
-void DesignWidget::selectObject()
-{
- Q_EMIT info("selected " + itemContextMenu->text(0).toStdString() + "\n");
-}
+void DesignWidget::selectObject() { Q_EMIT info("selected " + itemContextMenu->text(0).toStdString() + "\n"); }
NEXTPNR_NAMESPACE_END
diff --git a/gui/dummy/mainwindow.cc b/gui/dummy/mainwindow.cc
index 354b86ed..e72d4f96 100644
--- a/gui/dummy/mainwindow.cc
+++ b/gui/dummy/mainwindow.cc
@@ -23,8 +23,7 @@ static void initMainResource() { Q_INIT_RESOURCE(nextpnr); }
NEXTPNR_NAMESPACE_BEGIN
-MainWindow::MainWindow(Context *_ctx, QWidget *parent)
- : BaseMainWindow(_ctx, parent)
+MainWindow::MainWindow(Context *_ctx, QWidget *parent) : BaseMainWindow(_ctx, parent)
{
initMainResource();
diff --git a/gui/fpgaviewwidget.cc b/gui/fpgaviewwidget.cc
index 71e74e19..34e1a761 100644
--- a/gui/fpgaviewwidget.cc
+++ b/gui/fpgaviewwidget.cc
@@ -31,8 +31,8 @@
NEXTPNR_NAMESPACE_BEGIN
-void PolyLine::buildPoint(LineShaderData *building, const QVector2D *prev,
- const QVector2D *cur, const QVector2D *next) const
+void PolyLine::buildPoint(LineShaderData *building, const QVector2D *prev, const QVector2D *cur,
+ const QVector2D *next) const
{
// buildPoint emits two vertices per line point, along with normals to move
// them the right directio when rendering and miter to compensate for
@@ -164,13 +164,10 @@ void PolyLine::build(LineShaderData &target) const
bool LineShader::compile(void)
{
program_ = new QOpenGLShaderProgram(parent_);
- program_->addShaderFromSourceCode(QOpenGLShader::Vertex,
- vertexShaderSource_);
- program_->addShaderFromSourceCode(QOpenGLShader::Fragment,
- fragmentShaderSource_);
+ program_->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource_);
+ program_->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource_);
if (!program_->link()) {
- printf("could not link program: %s\n",
- program_->log().toStdString().c_str());
+ printf("could not link program: %s\n", program_->log().toStdString().c_str());
return false;
}
@@ -205,44 +202,35 @@ void LineShader::draw(const LineShaderData &line, const QMatrix4x4 &projection)
program_->bind();
buffers_.position.bind();
- buffers_.position.allocate(&line.vertices[0],
- sizeof(Vertex2DPOD) * line.vertices.size());
+ buffers_.position.allocate(&line.vertices[0], sizeof(Vertex2DPOD) * line.vertices.size());
buffers_.normal.bind();
- buffers_.normal.allocate(&line.normals[0],
- sizeof(Vertex2DPOD) * line.normals.size());
+ buffers_.normal.allocate(&line.normals[0], sizeof(Vertex2DPOD) * line.normals.size());
buffers_.miter.bind();
- buffers_.miter.allocate(&line.miters[0],
- sizeof(GLfloat) * line.miters.size());
+ buffers_.miter.allocate(&line.miters[0], sizeof(GLfloat) * line.miters.size());
buffers_.index.bind();
- buffers_.index.allocate(&line.indices[0],
- sizeof(GLuint) * line.indices.size());
+ buffers_.index.allocate(&line.indices[0], sizeof(GLuint) * line.indices.size());
program_->setUniformValue(uniforms_.projection, projection);
program_->setUniformValue(uniforms_.thickness, line.thickness);
- program_->setUniformValue(uniforms_.color, line.color.r, line.color.g,
- line.color.b, line.color.a);
+ program_->setUniformValue(uniforms_.color, line.color.r, line.color.g, line.color.b, line.color.a);
buffers_.position.bind();
program_->enableAttributeArray("position");
- gl->glVertexAttribPointer(attributes_.position, 2, GL_FLOAT, GL_FALSE, 0,
- (void *)0);
+ gl->glVertexAttribPointer(attributes_.position, 2, GL_FLOAT, GL_FALSE, 0, (void *)0);
buffers_.normal.bind();
program_->enableAttributeArray("normal");
- gl->glVertexAttribPointer(attributes_.normal, 2, GL_FLOAT, GL_FALSE, 0,
- (void *)0);
+ gl->glVertexAttribPointer(attributes_.normal, 2, GL_FLOAT, GL_FALSE, 0, (void *)0);
buffers_.miter.bind();
program_->enableAttributeArray("miter");
- gl->glVertexAttribPointer(attributes_.miter, 1, GL_FLOAT, GL_FALSE, 0,
- (void *)0);
+ gl->glVertexAttribPointer(attributes_.miter, 1, GL_FLOAT, GL_FALSE, 0, (void *)0);
buffers_.index.bind();
- gl->glDrawElements(GL_TRIANGLES, line.indices.size(), GL_UNSIGNED_INT,
- (void *)0);
+ gl->glDrawElements(GL_TRIANGLES, line.indices.size(), GL_UNSIGNED_INT, (void *)0);
program_->disableAttributeArray("miter");
program_->disableAttributeArray("normal");
@@ -253,8 +241,7 @@ void LineShader::draw(const LineShaderData &line, const QMatrix4x4 &projection)
}
FPGAViewWidget::FPGAViewWidget(QWidget *parent)
- : QOpenGLWidget(parent), moveX_(0), moveY_(0), zoom_(10.0f),
- lineShader_(this)
+ : QOpenGLWidget(parent), moveX_(0), moveY_(0), zoom_(10.0f), lineShader_(this)
{
ctx_ = qobject_cast<BaseMainWindow *>(getMainWindow())->getContext();
auto fmt = format();
@@ -263,8 +250,7 @@ FPGAViewWidget::FPGAViewWidget(QWidget *parent)
setFormat(fmt);
fmt = format();
- printf("FPGAViewWidget running on OpenGL %d.%d\n", fmt.majorVersion(),
- fmt.minorVersion());
+ printf("FPGAViewWidget running on OpenGL %d.%d\n", fmt.majorVersion(), fmt.minorVersion());
if (fmt.majorVersion() < 3) {
printf("Could not get OpenGL 3.0 context. Aborting.\n");
log_abort();
@@ -344,8 +330,7 @@ void FPGAViewWidget::drawElement(LineShaderData &out, const GraphicElement &el)
}
if (el.type == GraphicElement::G_LINE) {
- PolyLine(offset + scale * el.x1, offset + scale * el.y1,
- offset + scale * el.x2, offset + scale * el.y2)
+ PolyLine(offset + scale * el.x1, offset + scale * el.y1, offset + scale * el.x2, offset + scale * el.y2)
.build(out);
}
}
diff --git a/gui/fpgaviewwidget.h b/gui/fpgaviewwidget.h
index 9f9dc024..980571fd 100644
--- a/gui/fpgaviewwidget.h
+++ b/gui/fpgaviewwidget.h
@@ -51,15 +51,8 @@ struct ColorPOD
GLfloat b;
GLfloat a;
- ColorPOD(GLfloat R, GLfloat G, GLfloat B, GLfloat A)
- : r(R), g(G), b(B), a(A)
- {
- }
- ColorPOD(const QColor &color)
- : r(color.redF()), g(color.greenF()), b(color.blueF()),
- a(color.alphaF())
- {
- }
+ ColorPOD(GLfloat R, GLfloat G, GLfloat B, GLfloat A) : r(R), g(G), b(B), a(A) {}
+ ColorPOD(const QColor &color) : r(color.redF()), g(color.greenF()), b(color.blueF()), a(color.alphaF()) {}
} __attribute__((packed));
// LineShaderData is a built set of vertices that can be rendered by the
@@ -75,10 +68,7 @@ struct LineShaderData
GLfloat thickness;
ColorPOD color;
- LineShaderData(GLfloat Thickness, QColor Color)
- : thickness(Thickness), color(Color)
- {
- }
+ LineShaderData(GLfloat Thickness, QColor Color) : thickness(Thickness), color(Color) {}
};
// PolyLine is a set of segments defined by points, that can be built to a
@@ -89,8 +79,7 @@ class PolyLine
std::vector<QVector2D> points_;
bool closed_;
- void buildPoint(LineShaderData *building, const QVector2D *prev,
- const QVector2D *cur, const QVector2D *next) const;
+ void buildPoint(LineShaderData *building, const QVector2D *prev, const QVector2D *cur, const QVector2D *next) const;
public:
// Create an empty PolyLine.
@@ -212,11 +201,10 @@ class LineShader
" gl_Position = projection * vec4(p, 0.0, 1.0);\n"
"}\n";
- static constexpr const char *fragmentShaderSource_ =
- "uniform lowp vec4 color;\n"
- "void main() {\n"
- " gl_FragColor = color;\n"
- "}\n";
+ static constexpr const char *fragmentShaderSource_ = "uniform lowp vec4 color;\n"
+ "void main() {\n"
+ " gl_FragColor = color;\n"
+ "}\n";
// Must be called on initialization.
bool compile(void);
diff --git a/gui/ice40/mainwindow.cc b/gui/ice40/mainwindow.cc
index a0739f92..c8df0677 100644
--- a/gui/ice40/mainwindow.cc
+++ b/gui/ice40/mainwindow.cc
@@ -21,6 +21,8 @@
#include <QAction>
#include <QFileDialog>
#include <QIcon>
+#include <QInputDialog>
+#include <QLineEdit>
#include "bitstream.h"
#include "design_utils.h"
#include "jsonparse.h"
@@ -34,8 +36,7 @@ static void initMainResource() { Q_INIT_RESOURCE(nextpnr); }
NEXTPNR_NAMESPACE_BEGIN
-MainWindow::MainWindow(Context *_ctx, QWidget *parent)
- : BaseMainWindow(_ctx, parent)
+MainWindow::MainWindow(Context *_ctx, QWidget *parent) : BaseMainWindow(_ctx, parent), timing_driven(false)
{
initMainResource();
@@ -45,18 +46,19 @@ MainWindow::MainWindow(Context *_ctx, QWidget *parent)
task = new TaskManager(_ctx);
connect(task, SIGNAL(log(std::string)), this, SLOT(writeInfo(std::string)));
- connect(task, SIGNAL(loadfile_finished(bool)), this,
- SLOT(loadfile_finished(bool)));
+ connect(task, SIGNAL(loadfile_finished(bool)), this, SLOT(loadfile_finished(bool)));
connect(task, SIGNAL(pack_finished(bool)), this, SLOT(pack_finished(bool)));
- connect(task, SIGNAL(place_finished(bool)), this,
- SLOT(place_finished(bool)));
- connect(task, SIGNAL(route_finished(bool)), this,
- SLOT(route_finished(bool)));
+ connect(task, SIGNAL(budget_finish(bool)), this, SLOT(budget_finish(bool)));
+ connect(task, SIGNAL(place_finished(bool)), this, SLOT(place_finished(bool)));
+ connect(task, SIGNAL(route_finished(bool)), this, SLOT(route_finished(bool)));
connect(task, SIGNAL(taskCanceled()), this, SLOT(taskCanceled()));
connect(task, SIGNAL(taskStarted()), this, SLOT(taskStarted()));
connect(task, SIGNAL(taskPaused()), this, SLOT(taskPaused()));
+ connect(this, SIGNAL(budget(double)), task, SIGNAL(budget(double)));
+ connect(this, SIGNAL(place(bool)), task, SIGNAL(place(bool)));
+
createMenu();
}
@@ -75,12 +77,20 @@ void MainWindow::createMenu()
connect(actionPack, SIGNAL(triggered()), task, SIGNAL(pack()));
actionPack->setEnabled(false);
+ actionAssignBudget = new QAction("Assign Budget", this);
+ QIcon iconAssignBudget;
+ iconAssignBudget.addFile(QStringLiteral(":/icons/resources/time_add.png"));
+ actionAssignBudget->setIcon(iconAssignBudget);
+ actionAssignBudget->setStatusTip("Assign time budget for current design");
+ connect(actionAssignBudget, SIGNAL(triggered()), this, SLOT(budget()));
+ actionAssignBudget->setEnabled(false);
+
actionPlace = new QAction("Place", this);
QIcon iconPlace;
iconPlace.addFile(QStringLiteral(":/icons/resources/place.png"));
actionPlace->setIcon(iconPlace);
actionPlace->setStatusTip("Place current design");
- connect(actionPlace, SIGNAL(triggered()), task, SIGNAL(place()));
+ connect(actionPlace, SIGNAL(triggered()), this, SLOT(place()));
actionPlace->setEnabled(false);
actionRoute = new QAction("Route", this);
@@ -95,10 +105,12 @@ void MainWindow::createMenu()
addToolBar(Qt::TopToolBarArea, taskFPGABar);
taskFPGABar->addAction(actionPack);
+ taskFPGABar->addAction(actionAssignBudget);
taskFPGABar->addAction(actionPlace);
taskFPGABar->addAction(actionRoute);
menu_Design->addAction(actionPack);
+ menu_Design->addAction(actionAssignBudget);
menu_Design->addAction(actionPlace);
menu_Design->addAction(actionRoute);
@@ -136,13 +148,13 @@ void MainWindow::createMenu()
void MainWindow::open()
{
- QString fileName = QFileDialog::getOpenFileName(this, QString(), QString(),
- QString("*.json"));
+ QString fileName = QFileDialog::getOpenFileName(this, QString(), QString(), QString("*.json"));
if (!fileName.isEmpty()) {
tabWidget->setCurrentWidget(info);
std::string fn = fileName.toStdString();
disableActions();
+ timing_driven = false;
Q_EMIT task->loadfile(fn);
}
}
@@ -152,6 +164,7 @@ bool MainWindow::save() { return false; }
void MainWindow::disableActions()
{
actionPack->setEnabled(false);
+ actionAssignBudget->setEnabled(false);
actionPlace->setEnabled(false);
actionRoute->setEnabled(false);
@@ -176,10 +189,23 @@ void MainWindow::pack_finished(bool status)
if (status) {
log("Packing design successful.\n");
actionPlace->setEnabled(true);
+ actionAssignBudget->setEnabled(true);
} else {
log("Packing design failed.\n");
}
}
+
+void MainWindow::budget_finish(bool status)
+{
+ disableActions();
+ if (status) {
+ log("Assigning timing budget successful.\n");
+ actionPlace->setEnabled(true);
+ } else {
+ log("Assigning timing budget failed.\n");
+ }
+}
+
void MainWindow::place_finished(bool status)
{
disableActions();
@@ -219,4 +245,17 @@ void MainWindow::taskPaused()
actionStop->setEnabled(true);
}
+void MainWindow::budget()
+{
+ bool ok;
+ double freq = QInputDialog::getDouble(this, "Assign timing budget", "Frequency [MHz]:", 50, 0, 250, 2, &ok);
+ if (ok) {
+ freq *= 1e6;
+ timing_driven = true;
+ Q_EMIT budget(freq);
+ }
+}
+
+void MainWindow::place() { Q_EMIT place(timing_driven); }
+
NEXTPNR_NAMESPACE_END \ No newline at end of file
diff --git a/gui/ice40/mainwindow.h b/gui/ice40/mainwindow.h
index c0c4bef8..9857adf8 100644
--- a/gui/ice40/mainwindow.h
+++ b/gui/ice40/mainwindow.h
@@ -36,11 +36,20 @@ class MainWindow : public BaseMainWindow
public:
void createMenu();
+ Q_SIGNALS:
+ void budget(double freq);
+ void place(bool timing_driven);
+
protected Q_SLOTS:
virtual void open();
virtual bool save();
+
+ void budget();
+ void place();
+
void loadfile_finished(bool status);
void pack_finished(bool status);
+ void budget_finish(bool status);
void place_finished(bool status);
void route_finished(bool status);
@@ -53,11 +62,14 @@ class MainWindow : public BaseMainWindow
TaskManager *task;
QAction *actionPack;
+ QAction *actionAssignBudget;
QAction *actionPlace;
QAction *actionRoute;
QAction *actionPlay;
QAction *actionPause;
QAction *actionStop;
+
+ bool timing_driven;
};
NEXTPNR_NAMESPACE_END
diff --git a/gui/ice40/nextpnr.qrc b/gui/ice40/nextpnr.qrc
index 3bc68978..33f72ad8 100644
--- a/gui/ice40/nextpnr.qrc
+++ b/gui/ice40/nextpnr.qrc
@@ -6,5 +6,6 @@
<file>resources/pack.png</file>
<file>resources/place.png</file>
<file>resources/route.png</file>
+ <file>resources/time_add.png</file>
</qresource>
</RCC>
diff --git a/gui/ice40/resources/time_add.png b/gui/ice40/resources/time_add.png
new file mode 100644
index 00000000..dcc45cb2
--- /dev/null
+++ b/gui/ice40/resources/time_add.png
Binary files differ
diff --git a/gui/ice40/worker.cc b/gui/ice40/worker.cc
index ecf473ce..1558bc0c 100644
--- a/gui/ice40/worker.cc
+++ b/gui/ice40/worker.cc
@@ -72,20 +72,30 @@ void Worker::pack()
{
Q_EMIT taskStarted();
try {
- Q_EMIT pack_finished(pack_design(ctx));
+ bool res = pack_design(ctx);
+ print_utilisation(ctx);
+ Q_EMIT pack_finished(res);
} catch (WorkerInterruptionRequested) {
Q_EMIT taskCanceled();
}
}
-void Worker::place()
+void Worker::budget(double freq)
{
Q_EMIT taskStarted();
try {
- double freq = 50e6;
assign_budget(ctx, freq);
- print_utilisation(ctx);
- Q_EMIT place_finished(place_design_sa(ctx));
+ Q_EMIT budget_finish(true);
+ } catch (WorkerInterruptionRequested) {
+ Q_EMIT taskCanceled();
+ }
+}
+
+void Worker::place(bool timing_driven)
+{
+ Q_EMIT taskStarted();
+ try {
+ Q_EMIT place_finished(place_design_sa(ctx, timing_driven));
} catch (WorkerInterruptionRequested) {
Q_EMIT taskCanceled();
}
@@ -110,17 +120,16 @@ TaskManager::TaskManager(Context *ctx) : toTerminate(false), toPause(false)
connect(this, &TaskManager::loadfile, worker, &Worker::loadfile);
connect(this, &TaskManager::pack, worker, &Worker::pack);
+ connect(this, &TaskManager::budget, worker, &Worker::budget);
connect(this, &TaskManager::place, worker, &Worker::place);
connect(this, &TaskManager::route, worker, &Worker::route);
connect(worker, &Worker::log, this, &TaskManager::info);
- connect(worker, &Worker::loadfile_finished, this,
- &TaskManager::loadfile_finished);
+ connect(worker, &Worker::loadfile_finished, this, &TaskManager::loadfile_finished);
connect(worker, &Worker::pack_finished, this, &TaskManager::pack_finished);
- connect(worker, &Worker::place_finished, this,
- &TaskManager::place_finished);
- connect(worker, &Worker::route_finished, this,
- &TaskManager::route_finished);
+ connect(worker, &Worker::budget_finish, this, &TaskManager::budget_finish);
+ connect(worker, &Worker::place_finished, this, &TaskManager::place_finished);
+ connect(worker, &Worker::route_finished, this, &TaskManager::route_finished);
connect(worker, &Worker::taskCanceled, this, &TaskManager::taskCanceled);
connect(worker, &Worker::taskStarted, this, &TaskManager::taskStarted);
diff --git a/gui/ice40/worker.h b/gui/ice40/worker.h
index ae4dd146..d599e993 100644
--- a/gui/ice40/worker.h
+++ b/gui/ice40/worker.h
@@ -36,12 +36,14 @@ class Worker : public QObject
public Q_SLOTS:
void loadfile(const std::string &);
void pack();
- void place();
+ void budget(double freq);
+ void place(bool timing_driven);
void route();
Q_SIGNALS:
void log(const std::string &text);
void loadfile_finished(bool status);
void pack_finished(bool status);
+ void budget_finish(bool status);
void place_finished(bool status);
void route_finished(bool status);
void taskCanceled();
@@ -72,13 +74,15 @@ class TaskManager : public QObject
void terminate();
void loadfile(const std::string &);
void pack();
- void place();
+ void budget(double freq);
+ void place(bool timing_driven);
void route();
// redirected signals
void log(const std::string &text);
void loadfile_finished(bool status);
void pack_finished(bool status);
+ void budget_finish(bool status);
void place_finished(bool status);
void route_finished(bool status);
void taskCanceled();
diff --git a/gui/infotab.cc b/gui/infotab.cc
index 9127bd06..dd44b806 100644
--- a/gui/infotab.cc
+++ b/gui/infotab.cc
@@ -37,8 +37,7 @@ InfoTab::InfoTab(QWidget *parent) : QWidget(parent)
contextMenu = plainTextEdit->createStandardContextMenu();
contextMenu->addSeparator();
contextMenu->addAction(clearAction);
- connect(plainTextEdit, SIGNAL(customContextMenuRequested(const QPoint)),
- this, SLOT(showContextMenu(const QPoint)));
+ connect(plainTextEdit, SIGNAL(customContextMenuRequested(const QPoint)), this, SLOT(showContextMenu(const QPoint)));
QGridLayout *mainLayout = new QGridLayout();
mainLayout->addWidget(plainTextEdit);
@@ -52,10 +51,7 @@ void InfoTab::info(std::string str)
plainTextEdit->moveCursor(QTextCursor::End);
}
-void InfoTab::showContextMenu(const QPoint &pt)
-{
- contextMenu->exec(mapToGlobal(pt));
-}
+void InfoTab::showContextMenu(const QPoint &pt) { contextMenu->exec(mapToGlobal(pt)); }
void InfoTab::clearBuffer() { plainTextEdit->clear(); }
diff --git a/gui/line_editor.cc b/gui/line_editor.cc
index d4be9d3a..9d9dac25 100644
--- a/gui/line_editor.cc
+++ b/gui/line_editor.cc
@@ -33,8 +33,7 @@ LineEditor::LineEditor(QWidget *parent) : QLineEdit(parent), index(0)
contextMenu->addAction(clearAction);
connect(this, SIGNAL(returnPressed()), SLOT(textInserted()));
- connect(this, SIGNAL(customContextMenuRequested(const QPoint)), this,
- SLOT(showContextMenu(const QPoint)));
+ connect(this, SIGNAL(customContextMenuRequested(const QPoint)), this, SLOT(showContextMenu(const QPoint)));
}
void LineEditor::keyPressEvent(QKeyEvent *ev)
@@ -74,10 +73,7 @@ void LineEditor::textInserted()
Q_EMIT textLineInserted(lines.back());
}
-void LineEditor::showContextMenu(const QPoint &pt)
-{
- contextMenu->exec(mapToGlobal(pt));
-}
+void LineEditor::showContextMenu(const QPoint &pt) { contextMenu->exec(mapToGlobal(pt)); }
void LineEditor::clearHistory()
{
diff --git a/gui/pythontab.cc b/gui/pythontab.cc
index 8e8b7be4..397920d9 100644
--- a/gui/pythontab.cc
+++ b/gui/pythontab.cc
@@ -16,7 +16,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
- #ifndef NO_PYTHON
+#ifndef NO_PYTHON
#include "pythontab.h"
#include <QGridLayout>
@@ -44,8 +44,7 @@ PythonTab::PythonTab(QWidget *parent) : QWidget(parent)
contextMenu = plainTextEdit->createStandardContextMenu();
contextMenu->addSeparator();
contextMenu->addAction(clearAction);
- connect(plainTextEdit, SIGNAL(customContextMenuRequested(const QPoint)),
- this, SLOT(showContextMenu(const QPoint)));
+ connect(plainTextEdit, SIGNAL(customContextMenuRequested(const QPoint)), this, SLOT(showContextMenu(const QPoint)));
lineEdit = new LineEditor();
lineEdit->setMinimumHeight(30);
@@ -57,8 +56,7 @@ PythonTab::PythonTab(QWidget *parent) : QWidget(parent)
mainLayout->addWidget(lineEdit, 1, 0);
setLayout(mainLayout);
- connect(lineEdit, SIGNAL(textLineInserted(QString)), this,
- SLOT(editLineReturnPressed(QString)));
+ connect(lineEdit, SIGNAL(textLineInserted(QString)), this, SLOT(editLineReturnPressed(QString)));
write = [this](std::string s) {
plainTextEdit->moveCursor(QTextCursor::End);
@@ -88,9 +86,7 @@ int PythonTab::executePython(std::string &command)
if (m == NULL)
return -1;
d = PyModule_GetDict(m);
- v = PyRun_StringFlags(command.c_str(),
- (command.empty() ? Py_file_input : Py_single_input),
- d, d, NULL);
+ v = PyRun_StringFlags(command.c_str(), (command.empty() ? Py_file_input : Py_single_input), d, d, NULL);
if (v == NULL) {
PyObject *exception, *v, *tb;
@@ -111,8 +107,7 @@ int PythonTab::executePython(std::string &command)
PyErr_Clear();
PyObject *objectsRepresentation = PyObject_Str(v);
- std::string errorStr =
- PyUnicode_AsUTF8(objectsRepresentation) + std::string("\n");
+ std::string errorStr = PyUnicode_AsUTF8(objectsRepresentation) + std::string("\n");
print(errorStr);
Py_DECREF(objectsRepresentation);
Py_XDECREF(exception);
@@ -131,10 +126,7 @@ void PythonTab::editLineReturnPressed(QString text)
executePython(input);
}
-void PythonTab::showContextMenu(const QPoint &pt)
-{
- contextMenu->exec(mapToGlobal(pt));
-}
+void PythonTab::showContextMenu(const QPoint &pt) { contextMenu->exec(mapToGlobal(pt)); }
void PythonTab::clearBuffer() { plainTextEdit->clear(); }