diff options
Diffstat (limited to 'gui')
| -rw-r--r-- | gui/cachewaysselector.cc | 58 | ||||
| -rw-r--r-- | gui/cachewaysselector.h (renamed from gui/dynamicwaysentry.h) | 45 | ||||
| -rw-r--r-- | gui/digitlabeldelegate.cc | 8 | ||||
| -rw-r--r-- | gui/dynamicwaysentry.cc | 99 | ||||
| -rw-r--r-- | gui/gui.cc | 65 | ||||
| -rw-r--r-- | gui/gui.h | 4 | ||||
| -rw-r--r-- | gui/gui.ui | 128 | ||||
| -rw-r--r-- | gui/messages.h | 3 | ||||
| -rw-r--r-- | gui/registerview.cc | 69 | ||||
| -rw-r--r-- | gui/registerview.h | 64 | ||||
| -rw-r--r-- | gui/resources.qrc | 4 | ||||
| -rw-r--r-- | gui/resources/arrow_down.png | bin | 0 -> 228 bytes | |||
| -rw-r--r-- | gui/resources/arrow_down_pressed.png | bin | 0 -> 234 bytes | |||
| -rw-r--r-- | gui/resources/arrow_up.png | bin | 0 -> 221 bytes | |||
| -rw-r--r-- | gui/resources/arrow_up_pressed.png | bin | 0 -> 227 bytes | |||
| -rw-r--r-- | gui/resources/styles.qss | 62 | ||||
| -rw-r--r-- | gui/storageview.cc | 5 | ||||
| -rw-r--r-- | gui/storageview.h | 14 | ||||
| -rw-r--r-- | gui/worker.cc | 25 | ||||
| -rw-r--r-- | gui/worker.h | 22 | 
20 files changed, 374 insertions, 301 deletions
| diff --git a/gui/cachewaysselector.cc b/gui/cachewaysselector.cc new file mode 100644 index 0000000..14dae6f --- /dev/null +++ b/gui/cachewaysselector.cc @@ -0,0 +1,58 @@ +// Simulator for the RISC-V[ECTOR] mini-ISA +// Copyright (C) 2025 Siddarth Suresh +// Copyright (C) 2025 bdunahu + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <https://www.gnu.org/licenses/>. + +#include "cachewaysselector.h" +#include <QHBoxLayout> +#include <QLabel> +#include <QSpinBox> +#include <QVBoxLayout> + +CacheWaysSelector::CacheWaysSelector(QWidget *parent) : QWidget(parent) +{ +	QVBoxLayout *v; +	QHBoxLayout *l; +	QSpinBox *sb; +	QLabel *b; +	int i; + +	v = new QVBoxLayout(this); + +	for (i = 1; i <= 6; ++i) { +		l = new QHBoxLayout; + +		b = new QLabel(QString("L%1 2^").arg(i), this); + +		sb = new QSpinBox; +		sb->setRange(-1, 4); +		sb->setValue(-1); + +		l->addWidget(b); +		l->addWidget(sb); + +		v->addLayout(l); +		this->sbs.append(sb); +	} +} + +QList<int> CacheWaysSelector::values() const +{ +	QList<int> r; +	for (const QSpinBox *sb : this->sbs) { +		r.append(sb->value()); +	} +	return r; +} diff --git a/gui/dynamicwaysentry.h b/gui/cachewaysselector.h index 26b8b3e..4612b0c 100644 --- a/gui/dynamicwaysentry.h +++ b/gui/cachewaysselector.h @@ -15,37 +15,36 @@  // You should have received a copy of the GNU General Public License  // along with this program.  If not, see <https://www.gnu.org/licenses/>. -#ifndef DYNAMICWAYSENTRY_H -#define DYNAMICWAYSENTRY_H +#ifndef CACHEWAYSSELECTOR_H +#define CACHEWAYSSELECTOR_H - -#include <QLineEdit> -#include <QStringList> -#include <QVBoxLayout> -#include <QVector> +#include <QSpinBox>  #include <QWidget> -class DynamicWaysEntry : public QWidget +class CacheWaysSelector : public QWidget  { +	Q_OBJECT +    public: -	DynamicWaysEntry(QWidget *parent = nullptr); -	QStringList get_entries() const;  	/** -	 * Parses a string from this entry field, if it is valid. -	 * @param a string -	 * @param -1 if the string is not suitable as a way, an integer compatible -	 * with the cache constructor otherwise. +	 * Constructor. +	 * This class provides a simple group of labeled spinboxs meant for +	 * selecting cache ways. +	 * @param The parent widget. +	 * @param a newly allocated CacheWaysSelector  	 */ -	int parse_valid_way(QString t); -  private slots: -	void on_number_enter(const QString &t); +	explicit CacheWaysSelector(QWidget *parent = nullptr); + +	/** +	 * @return the values in the spinboxes. +	 */ +	QList<int> values() const;    private: -	QVBoxLayout *l; -	QVector<QLineEdit *> fields; -	QStringList entries; -	void add_field(); -	void remove_last_field(); +	/** +	 * A list of spinboxes. +	 */ +	QList<QSpinBox *> sbs;  }; -#endif // DYNAMICWAYSENTRY_H +#endif // CACHEWAYSSELECTOR_H diff --git a/gui/digitlabeldelegate.cc b/gui/digitlabeldelegate.cc index 430946c..7a6a1d5 100644 --- a/gui/digitlabeldelegate.cc +++ b/gui/digitlabeldelegate.cc @@ -37,9 +37,13 @@ void DigitLabelDelegate::paint(  	QString t;  	QStyleOptionViewItem o;  	QStyle *s; +	QVariant a; +	bool e; -	v = index.data(Qt::DisplayRole).toInt(); -	t = format_toggled_value(v, this->is_hex); +	a = index.data(Qt::DisplayRole); +	v = a.toInt(); +	e = a.isNull(); +	t = format_toggled_value(v, this->is_hex, e);  	o = option;  	initStyleOption(&o, index); diff --git a/gui/dynamicwaysentry.cc b/gui/dynamicwaysentry.cc deleted file mode 100644 index cbd5342..0000000 --- a/gui/dynamicwaysentry.cc +++ /dev/null @@ -1,99 +0,0 @@ -// Simulator for the RISC-V[ECTOR] mini-ISA -// Copyright (C) 2025 Siddarth Suresh -// Copyright (C) 2025 bdunahu - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program.  If not, see <https://www.gnu.org/licenses/>. - -#include "dynamicwaysentry.h" -#include <QLabel> -#include <QLineEdit> -#include <QStringList> -#include <QVBoxLayout> -#include <QVector> -#include <QWidget> - -DynamicWaysEntry::DynamicWaysEntry(QWidget *parent) : QWidget(parent) -{ -	this->l = new QVBoxLayout(this); -	this->l->setAlignment(Qt::AlignTop); -	this->l->setSpacing(6); -	this->l->setContentsMargins(0, 0, 0, 0); -	this->setLayout(l); -	this->add_field(); -} - -QStringList DynamicWaysEntry::get_entries() const { return this->entries; } - -int DynamicWaysEntry::parse_valid_way(QString t) -{ -	bool s; -	int i; -	i = t.toInt(&s); -	return (s && i >= 0 && 5 > i) ? i : -1; -} - -// TODO if you enter something valid and then make it invalid, -// the next box still shows -void DynamicWaysEntry::on_number_enter(const QString &t) -{ -	int i; -	QLineEdit *sender_field; - -	sender_field = qobject_cast<QLineEdit *>(sender()); -	i = fields.indexOf(sender_field); -	entries[i] = t; - -	if (i == this->fields.size() - 1 && !t.isEmpty() && -		(this->parse_valid_way(t) >= 0) && fields.size() < 4) -		add_field(); - -	// TODO, unlink, don't trash everything after -	if (t.isEmpty()) { -		while (this->fields.size() > i + 1) { -			remove_last_field(); -		} -		while (entries.size() > fields.size()) { -			entries.removeLast(); -		} -	} -} - -void DynamicWaysEntry::add_field() -{ -	QLineEdit *f; - -	f = new QLineEdit(this); -	f->setPlaceholderText("# ways (a power of 2)"); - -	this->l->addWidget(f);; -	this->fields.append(f); -	this->entries.append(QString()); -	connect( -		f, &QLineEdit::textChanged, this, &DynamicWaysEntry::on_number_enter); -} - -void DynamicWaysEntry::remove_last_field() -{ -	QLineEdit *f; - -	if (this->fields.isEmpty()) -		return; - -	f = this->fields.takeLast(); -	this->l->removeWidget(f); -	f->deleteLater(); - -	if (!this->entries.isEmpty()) -		entries.removeLast(); -} @@ -17,9 +17,10 @@  #include "gui.h"  #include "./ui_gui.h" +#include "cachewaysselector.h"  #include "digitlabeldelegate.h" -#include "dynamicwaysentry.h"  #include "messages.h" +#include "registerview.h"  #include "storageview.h"  #include "util.h"  #include <QHeaderView> @@ -72,6 +73,8 @@ GUI::GUI(QWidget *parent) : QMainWindow(parent), ui(new Ui::GUI)  	connect(worker, &Worker::wb_info, this, &GUI::onWorkerWriteBackInfo); +	connect(worker, &Worker::steps_done, this, &GUI::onWorkerStepsDone); +  	// Display cache  	connect(worker, &Worker::storage, this, &GUI::onWorkerShowStorage); @@ -109,37 +112,10 @@ GUI::~GUI()  	delete ui;  } -void displayArrayHTML(QTextEdit *textEdit, const std::array<int, GPR_NUM> &data) -{ -	textEdit->setReadOnly(false); -	QString tableText = "<table border='1' cellspacing='0' cellpadding='8' " -						"style='border-collapse: collapse; width: 100%; " -						"border: 2px solid black;'>"; - -	tableText += "<tr>"; -	int index = 0; -	for (int value : data) { -		tableText += QString("<td align='center' style='border: 2px solid " -							 "black; min-width: 60px; padding: 10px;'>" -							 "%1 <sup style='font-size: 10px; font-weight: " -							 "bold; color: black;'>%2</sup>" -							 "</td>") -						 .arg(QString::asprintf("%04X", value)) -						 .arg(index); -		index++; -	} -	tableText += "</tr>"; -	tableText += "</table>"; - -	textEdit->setHtml(tableText); -	textEdit->setReadOnly(true); -} -  void GUI::on_worker_refresh_gui(int cycles, int pc)  {  	ui->p_counter->set_value(pc);  	ui->cycle_counter->set_value(cycles); -	this->set_status(get_waiting, "idle");  }  void GUI::onWorkerFetchInfo(const InstrDTO *i) @@ -215,15 +191,20 @@ void GUI::onWorkerWriteBackInfo(const InstrDTO *i)  	}  } +void GUI::onWorkerStepsDone() { this->set_status(get_waiting, "idle"); } +  void GUI::onWorkerShowStorage(const QVector<QVector<int>> &data, int i)  {  	this->tab_boxes.at(i)->set_data(data);  } -void GUI::onWorkerShowRegisters(const std::array<int, GPR_NUM> &data) +void GUI::onWorkerShowRegisters( +	const QVector<signed int> &gprs, const QVector<QVector<signed int>> &vrs)  { -	; -	// displayArrayHTML(this->tab_boxes.at(0), data); +	RegisterView *rv; + +	rv = dynamic_cast<RegisterView *>(this->tab_boxes.at(0)); +	rv->set_data(gprs, vrs);  }  void GUI::on_upload_intructions_btn_clicked() @@ -301,21 +282,15 @@ void GUI::on_config_clicked()  {  	std::vector<unsigned int> ways;  	QStringList entries; -	signed int i; -	DynamicWaysEntry *dwe = ui->cache_way_selector; +	CacheWaysSelector *cws = ui->cache_ways_selector; -	for (const QString &s : dwe->get_entries()) { +	for (int i : cws->values()) { -		if (s.isEmpty()) +		// invalid +		if (i == -1)  			continue; -		i = dwe->parse_valid_way(s); -		if (i >= 0) { -			ways.push_back((unsigned int)i); -		} else { -			this->set_status(get_bad_cache, "angry"); -			return; -		} +		ways.push_back((unsigned int)i);  	}  	if (this->p.empty()) { @@ -355,15 +330,15 @@ void GUI::make_tabs(int num)  	for (i = 0; i < num; ++i) {  		if (i == 0) {  			n = "Registers"; -			e = new StorageView(0, this); +			e = new RegisterView(GPR_NUM + V_NUM, V_R_LIMIT, this);  		} else if (i == num - 1) {  			n = "DRAM"; -			e = new StorageView(MEM_LINES, this); +			e = new StorageView(MEM_LINES, LINE_SIZE, this);  		} else {  			n = QString("L%1").arg(i);  			e = new StorageView(  				(1 << cache_size_mapper(this->curr_cache_levels - 1, i - 1)), -				this); +				LINE_SIZE, this);  		}  		t = new QTableView(ui->storage); @@ -68,9 +68,11 @@ class GUI : public QMainWindow  	void onWorkerWriteBackInfo(const InstrDTO *); +	void onWorkerStepsDone(); +  	void onWorkerShowStorage(const QVector<QVector<int>> &data, int i); -	void onWorkerShowRegisters(const std::array<int, GPR_NUM> &data); +	void onWorkerShowRegisters(const QVector<signed int> &gprs, const QVector<QVector<signed int>> &vrs);  	void on_upload_intructions_btn_clicked(); @@ -6,7 +6,7 @@     <rect>      <x>0</x>      <y>0</y> -    <width>1499</width> +    <width>1686</width>      <height>621</height>     </rect>    </property> @@ -18,14 +18,17 @@      <item>       <layout class="QGridLayout" name="gridLayout_2" rowstretch="0" columnstretch="0">        <item row="0" column="0"> -       <layout class="QHBoxLayout" name="control_separator"> +       <layout class="QHBoxLayout" name="control_separator" stretch="6,1"> +        <property name="spacing"> +         <number>6</number> +        </property>          <item>           <layout class="QVBoxLayout" name="storage_pipe_separator">            <item>             <widget class="QTabWidget" name="storage">              <property name="minimumSize">               <size> -              <width>700</width> +              <width>0</width>                <height>0</height>               </size>              </property> @@ -35,7 +38,7 @@             </widget>            </item>            <item> -           <layout class="QHBoxLayout" name="pipe_view"> +           <layout class="QHBoxLayout" name="pipe_view" stretch="1,2,2,2,2,2">              <item>               <widget class="QGroupBox" name="groupBox">                <property name="maximumSize"> @@ -45,7 +48,7 @@                 </size>                </property>                <property name="title"> -               <string> </string> +               <string/>                </property>                <property name="alignment">                 <set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set> @@ -93,7 +96,7 @@               <widget class="QGroupBox" name="Fetch">                <property name="minimumSize">                 <size> -                <width>200</width> +                <width>0</width>                  <height>0</height>                 </size>                </property> @@ -146,7 +149,7 @@               <widget class="QGroupBox" name="Decode">                <property name="minimumSize">                 <size> -                <width>200</width> +                <width>0</width>                  <height>0</height>                 </size>                </property> @@ -199,7 +202,7 @@               <widget class="QGroupBox" name="Execute">                <property name="minimumSize">                 <size> -                <width>200</width> +                <width>0</width>                  <height>0</height>                 </size>                </property> @@ -255,7 +258,7 @@               <widget class="QGroupBox" name="Memory">                <property name="minimumSize">                 <size> -                <width>200</width> +                <width>0</width>                  <height>0</height>                 </size>                </property> @@ -308,7 +311,7 @@               <widget class="QGroupBox" name="WriteBack">                <property name="minimumSize">                 <size> -                <width>200</width> +                <width>0</width>                  <height>0</height>                 </size>                </property> @@ -376,93 +379,14 @@             </widget>            </item>            <item> -           <layout class="QHBoxLayout" name="cache_controls"> -            <property name="sizeConstraint"> -             <enum>QLayout::SizeConstraint::SetMinimumSize</enum> +           <widget class="QLabel" name="label"> +            <property name="text"> +             <string>Ways Selector (powers of 2)</string>              </property> -            <item> -             <widget class="Line" name="line_8"> -              <property name="orientation"> -               <enum>Qt::Orientation::Vertical</enum> -              </property> -             </widget> -            </item> -            <item> -             <layout class="QVBoxLayout" name="cache_way_text"> -              <property name="sizeConstraint"> -               <enum>QLayout::SizeConstraint::SetMinimumSize</enum> -              </property> -              <item> -               <widget class="QLabel" name="label"> -                <property name="maximumSize"> -                 <size> -                  <width>16777215</width> -                  <height>16777215</height> -                 </size> -                </property> -                <property name="text"> -                 <string>C1 2^</string> -                </property> -               </widget> -              </item> -              <item> -               <widget class="QLabel" name="label_2"> -                <property name="maximumSize"> -                 <size> -                  <width>16777215</width> -                  <height>16777215</height> -                 </size> -                </property> -                <property name="text"> -                 <string>C2 2^</string> -                </property> -               </widget> -              </item> -              <item> -               <widget class="QLabel" name="label_3"> -                <property name="minimumSize"> -                 <size> -                  <width>0</width> -                  <height>0</height> -                 </size> -                </property> -                <property name="maximumSize"> -                 <size> -                  <width>16777215</width> -                  <height>16777215</height> -                 </size> -                </property> -                <property name="text"> -                 <string>C3 2^</string> -                </property> -               </widget> -              </item> -              <item> -               <widget class="QLabel" name="label_4"> -                <property name="maximumSize"> -                 <size> -                  <width>16777215</width> -                  <height>16777215</height> -                 </size> -                </property> -                <property name="text"> -                 <string>C4 2^</string> -                </property> -               </widget> -              </item> -             </layout> -            </item> -            <item> -             <widget class="DynamicWaysEntry" name="cache_way_selector" native="true"> -              <property name="minimumSize"> -               <size> -                <width>0</width> -                <height>0</height> -               </size> -              </property> -             </widget> -            </item> -           </layout> +           </widget> +          </item> +          <item> +           <widget class="CacheWaysSelector" name="cache_ways_selector" native="true"/>            </item>            <item>             <widget class="QCheckBox" name="enable_pipeline_checkbox"> @@ -675,16 +599,16 @@   </widget>   <customwidgets>    <customwidget> -   <class>DynamicWaysEntry</class> -   <extends>QWidget</extends> -   <header>dynamicwaysentry.h</header> -   <container>1</container> -  </customwidget> -  <customwidget>     <class>DigitLabel</class>     <extends>QLabel</extends>     <header location="global">digitlabel.h</header>    </customwidget> +  <customwidget> +   <class>CacheWaysSelector</class> +   <extends>QWidget</extends> +   <header>cachewaysselector.h</header> +   <container>1</container> +  </customwidget>   </customwidgets>   <resources/>   <connections/> diff --git a/gui/messages.h b/gui/messages.h index 461c461..0c38751 100644 --- a/gui/messages.h +++ b/gui/messages.h @@ -35,8 +35,6 @@ const std::vector<std::string> load_file = {  const std::vector<std::string> no_instructions = {  	"NO PROGRAM PROVIDED", "NOTHING TO DO, GIVING UP", "INSTRUCTIONS MISSING",  	"404 INSTRUCTIONS NOT FOUND"}; -const std::vector<std::string> bad_cache = { -	"WAYS CANNOT BE BELOW 0 OR ABOVE 4"};  const std::vector<std::string> no_pipeline = {  	"SIMULATION READY: NO PIPE", "PIPE OFF, SIMULATION READY"};  const std::vector<std::string> no_cache = { @@ -59,7 +57,6 @@ std::string get_load_file() { return RANDOM_MESSAGE(load_file); }   * @return a friendly reminder that the simulation is not configured yet   */  std::string get_no_instructions() { return RANDOM_MESSAGE(no_instructions); } -std::string get_bad_cache() { return RANDOM_MESSAGE(bad_cache); }  /**   * @return unsolicited complaints for successful initialization diff --git a/gui/registerview.cc b/gui/registerview.cc new file mode 100644 index 0000000..b1a1333 --- /dev/null +++ b/gui/registerview.cc @@ -0,0 +1,69 @@ +// Simulator for the RISC-V[ECTOR] mini-ISA +// Copyright (C) 2025 Siddarth Suresh +// Copyright (C) 2025 bdunahu + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <https://www.gnu.org/licenses/>. + +#include "pipe_spec.h" +#include "registerview.h" +#include "util.h" +#include <QAbstractTableModel> +#include <QVector> + +QVariant RegisterView::data(const QModelIndex &i, int role) const +{ +	Qt::Alignment a; + +	if (role == Qt::TextAlignmentRole) { +		a = Qt::AlignRight | Qt::AlignVCenter; +		return QVariant(static_cast<int>(a)); +	} + +	if (!i.isValid() || role != Qt::DisplayRole) +		return QVariant(); + +	if (i.row() < 16) { +		if (i.column() < 1) +			return this->gprs[i.row()]; +		else +			return QVariant(); +	} + +	return this->vrs[i.row() - GPR_NUM][i.column() - GPR_NUM]; +} + +QVariant +RegisterView::headerData(int section, Qt::Orientation o, int role) const +{ +	Qt::Alignment a; + +	if (role == Qt::TextAlignmentRole) { +		a = Qt::AlignRight | Qt::AlignVCenter; +		return QVariant(static_cast<int>(a)); +	} + +	if (role != Qt::DisplayRole) +		return QVariant(); + +	if (o == Qt::Vertical) { +		return format_toggled_value(section, this->is_hex); +	} +	return QVariant(); +} + +void RegisterView::set_data(const QVector<int> &gprs, const QVector<QVector<int>> &vrs) +{ +	this->gprs = gprs; +	this->vrs = vrs; +} diff --git a/gui/registerview.h b/gui/registerview.h new file mode 100644 index 0000000..cc5a1f8 --- /dev/null +++ b/gui/registerview.h @@ -0,0 +1,64 @@ +// Simulator for the RISC-V[ECTOR] mini-ISA +// Copyright (C) 2025 Siddarth Suresh +// Copyright (C) 2025 bdunahu + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <https://www.gnu.org/licenses/>. + +#ifndef REGISTERVIEW_H +#define REGISTERVIEW_H + +#include "storageview.h" +#include <QAbstractTableModel> +#include <QVector> + +// see https://doc.qt.io/qt-6/qabstracttablemodel.html +class RegisterView : public StorageView +{ +	Q_OBJECT +  public: +	using StorageView::StorageView; + +	/** +	 * Returns a properly formatted cell, including alignment.This function is +	 * specific to the implementation details of QAbstractTableModel. +	 */ +	QVariant +	data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + +	/** +	 * Adds custom formatting options for row and column headers. +	 */ +	QVariant headerData( +		int section, +		Qt::Orientation o, +		int role = Qt::DisplayRole) const override; + +	/** +	 * @param field to assign to `this->gprs'. +	 * @param field to assign to `this->vrs'. +	 */ +	void set_data(const QVector<int> &gprs, const QVector<QVector<int>> &vrs); + +  private: +	/** +	 * The general purpose registers. +	 */ +	QVector<int> gprs; +	/** +	 * The vector registers. +	 */ +	QVector<QVector<int>> vrs; +}; + +#endif // REGISTERVIEW_H diff --git a/gui/resources.qrc b/gui/resources.qrc index 569cc22..66cd6e4 100644 --- a/gui/resources.qrc +++ b/gui/resources.qrc @@ -1,6 +1,10 @@  <!DOCTYPE RCC>  <RCC version="1.0">      <qresource> +      <file>resources/arrow_down.png</file> +      <file>resources/arrow_up.png</file> +      <file>resources/arrow_down_pressed.png</file> +      <file>resources/arrow_up_pressed.png</file>        <file>resources/styles.qss</file>        <file>resources/idle.png</file>        <file>resources/angry.png</file> diff --git a/gui/resources/arrow_down.png b/gui/resources/arrow_down.pngBinary files differ new file mode 100644 index 0000000..80b1753 --- /dev/null +++ b/gui/resources/arrow_down.png diff --git a/gui/resources/arrow_down_pressed.png b/gui/resources/arrow_down_pressed.pngBinary files differ new file mode 100644 index 0000000..0981cf2 --- /dev/null +++ b/gui/resources/arrow_down_pressed.png diff --git a/gui/resources/arrow_up.png b/gui/resources/arrow_up.pngBinary files differ new file mode 100644 index 0000000..69b65af --- /dev/null +++ b/gui/resources/arrow_up.png diff --git a/gui/resources/arrow_up_pressed.png b/gui/resources/arrow_up_pressed.pngBinary files differ new file mode 100644 index 0000000..98d50ac --- /dev/null +++ b/gui/resources/arrow_up_pressed.png diff --git a/gui/resources/styles.qss b/gui/resources/styles.qss index a61035e..c6d8daa 100644 --- a/gui/resources/styles.qss +++ b/gui/resources/styles.qss @@ -4,6 +4,8 @@      color: "#00cc00";      background-color: "#000200";      border: 0px solid "#000200"; +    selection-background-color: "#00cc00"; +    selection-color: "#000200";  }  QStatusBar { @@ -50,6 +52,66 @@ QGroupBox::title {  QLabel {  } +QSpinBox { +    padding-right: 15px; /* make room for the arrows */ +    border: none; +} + +QSpinBox::up-button { +    color: "#000200"; +    background-color: "#00cc00"; +    subcontrol-origin: border; +    subcontrol-position: top right; /* position at the top right corner */ + +    width: 16px; +    border: none; +    subcontrol-origin: border; +} + +QSpinBox::up-arrow { +    image: url(:/resources/arrow_up.png); +    width: 7px; +    height: 7px; +} + +QSpinBox::up-arrow:pressed { +    image: url(:/resources/arrow_up_pressed.png); +    width: 7px; +    height: 7px; +} + +QSpinBox::up-button:pressed { +    color: "#00cc00"; +    background-color: "#000200"; +} + +QSpinBox::down-button { +    color: "#000200"; +    background-color: "#00cc00"; +    subcontrol-origin: border; +    subcontrol-position: bottom right; /* position at bottom right corner */ + +    width: 16px; +    border: none; +} + +QSpinBox::down-button:pressed { +    color: "#00cc00"; +    background-color: "#000200"; +} + +QSpinBox::down-arrow { +    image: url(:/resources/arrow_down.png); +    width: 7px; +    height: 7px; +} + +QSpinBox::down-arrow:pressed { +    image: url(:/resources/arrow_down_pressed.png); +    width: 7px; +    height: 7px; +} +  QTableView {      border: 0px;      selection-background-color: transparent; diff --git a/gui/storageview.cc b/gui/storageview.cc index 2f444a9..60391f9 100644 --- a/gui/storageview.cc +++ b/gui/storageview.cc @@ -21,10 +21,11 @@  #include <QAbstractTableModel>  #include <QVector> -StorageView::StorageView(int rows, QObject *parent) +StorageView::StorageView(int rows, int columns, QObject *parent)  	: QAbstractTableModel(parent)  {  	this->r = rows; +	this->c = columns;  	this->d.resize(rows);  	for (auto &row : this->d)  		row.resize(LINE_SIZE, 0); @@ -32,7 +33,7 @@ StorageView::StorageView(int rows, QObject *parent)  int StorageView::rowCount(const QModelIndex &) const { return this->r; } -int StorageView::columnCount(const QModelIndex &) const { return LINE_SIZE; } +int StorageView::columnCount(const QModelIndex &) const { return this->c; }  QVariant StorageView::data(const QModelIndex &i, int role) const  { diff --git a/gui/storageview.h b/gui/storageview.h index 0518d8f..a0f8dbb 100644 --- a/gui/storageview.h +++ b/gui/storageview.h @@ -31,7 +31,7 @@ class StorageView : public QAbstractTableModel  	 * `rows' rows.  	 * @param the number of rows  	 */ -	StorageView(int rows, QObject *parent = nullptr); +	StorageView(int rows, int columns, QObject *parent = nullptr);  	/**  	 * Returns the number of rows in this table. @@ -51,13 +51,13 @@ class StorageView : public QAbstractTableModel  	 * Returns a properly formatted cell, including alignment.This function is  	 * specific to the implementation details of QAbstractTableModel.  	 */ -	QVariant +	virtual QVariant  	data(const QModelIndex &index, int role = Qt::DisplayRole) const override;  	/**  	 * Adds custom formatting options for row and column headers.  	 */ -	QVariant headerData( +	virtual QVariant headerData(  		int section,  		Qt::Orientation o,  		int role = Qt::DisplayRole) const override; @@ -75,15 +75,21 @@ class StorageView : public QAbstractTableModel    public slots:  	void set_hex_display(bool hex); -  private: +  protected:  	/**  	 * The number of rows in this table.  	 */  	int r;  	/** +	 * The number of columns in this table. +	 */ +	int c; +	/**  	 * Whether or not the headers should be displayed in hex.  	 */  	bool is_hex = true; + +  private:  	/**  	 * The data this table displays.  	 */ diff --git a/gui/worker.cc b/gui/worker.cc index 0ba364b..a48888c 100644 --- a/gui/worker.cc +++ b/gui/worker.cc @@ -72,14 +72,22 @@ void Worker::runSteps(int steps)  {  	this->ct->run_for(steps);  	this->update(); +	emit steps_done();  }  void Worker::update()  {  	unsigned long i; +	std::array<int, GPR_NUM> gprs; +	std::array<std::array<signed int, V_R_LIMIT>, V_NUM> vrs;  	this->ct_mutex.lock(); -	emit register_storage(this->ct->get_gprs()); +	gprs = this->ct->get_gprs(); +	vrs = this->ct->get_vrs(); +	std::vector<std::array<signed int, V_R_LIMIT>> v(vrs.begin(), vrs.end()); + +	emit register_storage( +		QVector<int>(gprs.begin(), gprs.end()), this->data_to_QT(v));  	for (i = 0; i < s.size(); ++i)  		emit storage(this->data_to_QT(this->s.at(i)->get_data()), i + 1); @@ -92,18 +100,3 @@ void Worker::update()  	emit wb_info(this->wb_stage->get_instr());  	this->ct_mutex.unlock();  } - -QVector<QVector<int>> -Worker::data_to_QT(std::vector<std::array<signed int, LINE_SIZE>> data) -{ -	QVector<QVector<int>> r; -	QVector<int> tmp; - -	r.reserve(static_cast<int>(data.size())); - -	for (const auto &line : data) { -		tmp = QVector<int>(line.begin(), line.end()); -		r.append(tmp); -	} -	return r; -} diff --git a/gui/worker.h b/gui/worker.h index c62f4ed..2a362a4 100644 --- a/gui/worker.h +++ b/gui/worker.h @@ -64,14 +64,15 @@ class Worker : public QObject    signals:  	void clock_cycles(int value, int pc); -	void -	storage(QVector<QVector<int>> data, int i); -	void register_storage(const std::array<int, GPR_NUM> data); +	void storage(QVector<QVector<int>> data, int i); +	void register_storage( +		QVector<signed int> gprs, QVector<QVector<signed int>> vrs);  	void if_info(const InstrDTO *);  	void id_info(const InstrDTO *);  	void ex_info(const InstrDTO *);  	void mm_info(const InstrDTO *);  	void wb_info(const InstrDTO *); +	void steps_done();  	void finished();    private: @@ -80,8 +81,21 @@ class Worker : public QObject  	 * @param the original data  	 * @return a less universal version of the same thing  	 */ +	template <size_t N>  	QVector<QVector<int>> -	data_to_QT(std::vector<std::array<signed int, LINE_SIZE>> data); +	data_to_QT(const std::vector<std::array<signed int, N>> &data) +	{ +		QVector<QVector<int>> r; +		QVector<int> tmp; + +		r.reserve(static_cast<int>(data.size())); + +		for (const auto &line : data) { +			tmp = QVector<int>(line.begin(), line.end()); +			r.append(tmp); +		} +		return r; +	}  	/**  	 * Sets the GUI signals to update the storage, clock cycle, and stage  	 * displays. | 
