summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiddarth Suresh <155843085+SiddarthSuresh98@users.noreply.github.com>2025-03-30 19:34:17 -0400
committerGitHub <noreply@github.com>2025-03-30 19:34:17 -0400
commit12a9e93f913c0057f2ef32f5894931c8b4bd3a85 (patch)
tree88669ed2be55b4f455ef4ac56263a01dd5f70a40
parenteedf9686eb60f2008e7766cc9a5d3e037b9dae64 (diff)
parent36dabe6183af98b2e3f6d0316436dc3affc3d986 (diff)
Merge pull request #41 from bdunahu/bdunahu
Add mock stage, proper decode tests changes look good
-rw-r--r--inc/controller.h9
-rw-r--r--inc/definitions.h6
-rw-r--r--inc/dum.h28
-rw-r--r--inc/ex.h14
-rw-r--r--inc/id.h8
-rw-r--r--inc/if.h9
-rw-r--r--inc/instr.h1
-rw-r--r--inc/mm.h4
-rw-r--r--inc/stage.h30
-rw-r--r--inc/wb.h6
-rw-r--r--src/logger/logger.cc8
-rw-r--r--src/sim/controller.cc2
-rw-r--r--src/sim/dum.cc31
-rw-r--r--src/sim/ex.cc197
-rw-r--r--src/sim/id.cc25
-rw-r--r--src/sim/if.cc4
-rw-r--r--src/sim/instr.cc29
-rw-r--r--src/sim/mm.cc5
-rw-r--r--src/sim/stage.cc35
-rw-r--r--src/sim/wb.cc2
-rw-r--r--tests/id.cc159
-rw-r--r--tests/if.cc6
22 files changed, 469 insertions, 149 deletions
diff --git a/inc/controller.h b/inc/controller.h
index 1c7b2d6..17aba37 100644
--- a/inc/controller.h
+++ b/inc/controller.h
@@ -1,8 +1,8 @@
#ifndef CONTROLLER_H
#define CONTROLLER_H
+#include "instrDTO.h"
#include "response.h"
#include "stage.h"
-#include "instrDTO.h"
/**
* Houses the clock, and acts as the main API to the GUI.
@@ -18,7 +18,8 @@ class Controller : public Stage
* @return A newly allocated controller object.
*/
Controller(Stage *stage, Storage *storage, bool is_pipelined);
-
+ InstrDTO *advance(Response p) override;
+
/**
* Direct the simulator to run for `number` clock cycles.
* @param the number of clock cycles to run for.
@@ -36,7 +37,9 @@ class Controller : public Stage
* @return the pc.
*/
int get_pc();
- InstrDTO *advance(Response p) override;
+
+ private:
+ void advance_helper() override;
};
#endif /* CONTROLLER_H_INCLUDED */
diff --git a/inc/definitions.h b/inc/definitions.h
index 3238a8b..c81c4e3 100644
--- a/inc/definitions.h
+++ b/inc/definitions.h
@@ -77,6 +77,12 @@
#define OPCODE_SIZE 4
/**
+ * The maximum value an integer can hold.
+ * The minimum is always this number plus one negated.
+ */
+#define MAX_INT 2147483647
+
+/**
* Return the N least-significant bits from integer K using a bit mask
* @param the integer to be parsed
* @param the number of bits to be parsed
diff --git a/inc/dum.h b/inc/dum.h
new file mode 100644
index 0000000..da64b9d
--- /dev/null
+++ b/inc/dum.h
@@ -0,0 +1,28 @@
+#ifndef DUM_H
+#define DUM_H
+#include "instrDTO.h"
+#include "response.h"
+#include "stage.h"
+
+/**
+ * Don't underestimate mocks (the DUM pipe stage).
+ */
+class DUM : public Stage
+{
+ public:
+ /**
+ * Constructor.
+ * @param The next stage in the pipeline.
+ * @return A newly allocated DUM object.
+ */
+ DUM(Stage *next);
+
+ InstrDTO *advance(Response p) override;
+
+ void set_curr_instr(InstrDTO *);
+
+ private:
+ void advance_helper() override;
+};
+
+#endif /* DUM_H_INCLUDED */
diff --git a/inc/ex.h b/inc/ex.h
index 2ca8876..cc8062b 100644
--- a/inc/ex.h
+++ b/inc/ex.h
@@ -3,6 +3,7 @@
#include "instrDTO.h"
#include "response.h"
#include "stage.h"
+#include <unordered_map>
class EX : public Stage
{
@@ -13,8 +14,19 @@ class EX : public Stage
* @return A newly allocated EX object.
*/
EX(Stage *next);
+ using Stage::advance;
- InstrDTO *advance(Response p) override;
+ private:
+ void advance_helper();
+ /**
+ * Maps each mnemonic to a function which carries out the instruction's base
+ * logic.
+ * All instructions store the result into s1.
+ */
+ std::unordered_map<
+ Mnemonic,
+ std::function<void(signed int &s1, signed int s2)>>
+ instr_map;
};
#endif /* EX_H_INCLUDED */
diff --git a/inc/id.h b/inc/id.h
index c5c1f1d..9911440 100644
--- a/inc/id.h
+++ b/inc/id.h
@@ -14,8 +14,7 @@ class ID : public Stage
* @return A newly allocated ID object.
*/
ID(Stage *next);
-
- InstrDTO *advance(Response p) override;
+ using Stage::advance;
/* The following methods are made public so that they may be tested, and are
* not to be called from outside classes during standard execution.
@@ -56,10 +55,7 @@ class ID : public Stage
void write_guard(signed int &r);
private:
- /**
- * Decodes `curr_instr` and sets status to BLOCKED if a data hazard occurs.
- */
- void advance_helper();
+ void advance_helper() override;
/**
* Helper for `get_instr_fields`
* Attempts to parse and dereference instruction arguments. Uses read and
diff --git a/inc/if.h b/inc/if.h
index d58b06a..63ca90e 100644
--- a/inc/if.h
+++ b/inc/if.h
@@ -18,14 +18,7 @@ class IF : public Stage
InstrDTO *advance(Response p) override;
private:
- /**
- * Performs a fetch only if a current fetch is not pending. Pending means
- * that a fetch has completed successfully, but the caller stage in the
- * pipeline is not ready to receive it. In this case, `curr_instr` is not
- * the nullptr.
- * @return STALLED if we are waiting on the storage devices, OK otherwise.
- */
- void advance_helper();
+ void advance_helper() override;
};
#endif /* IF_H_INCLUDED */
diff --git a/inc/instr.h b/inc/instr.h
index 08b4fd0..7fbb42b 100644
--- a/inc/instr.h
+++ b/inc/instr.h
@@ -49,7 +49,6 @@ namespace instr
{
// clang-format off
extern const std::unordered_map<unsigned int, Mnemonic> mnemonic_map;
- extern const std::unordered_map<Mnemonic, std::function<void(signed int &s1, signed int &s2, signed int &s3)>> instr_map;
// clang-format on
} // namespace instr
diff --git a/inc/mm.h b/inc/mm.h
index 6081802..cee3f17 100644
--- a/inc/mm.h
+++ b/inc/mm.h
@@ -13,8 +13,10 @@ class MM : public Stage
* @return A newly allocated MM object.
*/
MM(Stage *next);
+ using Stage::advance;
- InstrDTO *advance(Response p) override;
+ private:
+ void advance_helper() override;
};
#endif /* MM_H_INCLUDED */
diff --git a/inc/stage.h b/inc/stage.h
index 50c413a..56a3589 100644
--- a/inc/stage.h
+++ b/inc/stage.h
@@ -9,6 +9,13 @@
#include <deque>
#include <memory>
+enum CC {
+ GT,
+ EQ,
+ UF,
+ OF,
+};
+
class Stage
{
public:
@@ -21,16 +28,37 @@ class Stage
virtual ~Stage();
/**
* Advances this stage by a single clock cycle.
+ * A boilerplate version is provided in stage.cc.
+ *
* @param a DTO object containing the next instruction to be processed.
* @param a response, indicating whether or not the parent pipe stage is
* ready to accept a new instruction object next cycle.
* @return a response, indicating whether this pipeline stage is stalling,
* busy, or done.
+ *
+ * Must set the status to STALLED when an operation completes.
*/
- virtual InstrDTO *advance(Response p) = 0;
+ virtual InstrDTO *advance(Response p);
protected:
/**
+ * The function expected to do the majority of the work.
+ *
+ * Must set the status to OK when an operation is ready.
+ */
+ virtual void advance_helper() = 0;
+ /**
+ * Sets the bit in the condition code register corresponding to `c`.
+ * @param the condition code to set.
+ * @param the truthy value to set it to.
+ */
+ void set_condition(CC c, bool v);
+ /**
+ * Gets the bit in the condition code register correspondng to `c`.
+ * @param the condition code to retrieve,
+ */
+ bool get_condition(CC c);
+ /**
* Helper for `check_out`.
* Returns true if r are not checked out, false otherwise.
* @param a list of register numbers.
diff --git a/inc/wb.h b/inc/wb.h
index 7c796ab..62cef17 100644
--- a/inc/wb.h
+++ b/inc/wb.h
@@ -13,8 +13,10 @@ class WB : public Stage
* @return A newly allocated WB object.
*/
WB(Stage *next);
-
- InstrDTO *advance(Response p) override;
+ using Stage::advance;
+
+ private:
+ void advance_helper() override;
};
#endif /* WB_H_INCLUDED */
diff --git a/src/logger/logger.cc b/src/logger/logger.cc
index 6dfaef1..b07e66f 100644
--- a/src/logger/logger.cc
+++ b/src/logger/logger.cc
@@ -8,11 +8,11 @@ using namespace std;
LogLevel Logger::level = INFO;
Logger *Logger::logger_instance;
-void Logger::setLevel(LogLevel level) { level = level; }
+void Logger::setLevel(LogLevel level) { this->level = level; }
void Logger::log(LogLevel level, const string &message)
{
- if (level_to_int(level) > level_to_int(level)) {
+ if (level_to_int(level) > level_to_int(this->level)) {
return;
}
@@ -65,9 +65,7 @@ int Logger::level_to_int(LogLevel level)
return 3;
case ERROR:
return 2;
- case CRITICAL:
- return 1;
default:
- return 0;
+ return 1;
}
}
diff --git a/src/sim/controller.cc b/src/sim/controller.cc
index 622f1dc..06591af 100644
--- a/src/sim/controller.cc
+++ b/src/sim/controller.cc
@@ -36,3 +36,5 @@ InstrDTO *Controller::advance(Response p)
++this->clock_cycle;
return r;
}
+
+void Controller::advance_helper() {}
diff --git a/src/sim/dum.cc b/src/sim/dum.cc
new file mode 100644
index 0000000..dd16660
--- /dev/null
+++ b/src/sim/dum.cc
@@ -0,0 +1,31 @@
+#include "dum.h"
+#include "accessor.h"
+#include "instrDTO.h"
+#include "response.h"
+#include "stage.h"
+#include "utils.h"
+
+DUM::DUM(Stage *stage) : Stage(stage) { this->id = IDLE; }
+
+InstrDTO *DUM::advance(Response p)
+{
+ InstrDTO *r = curr_instr;
+
+ this->advance_helper();
+ if (this->status == OK && p == OK) {
+ this->curr_instr->set_time_of(this->id, this->clock_cycle);
+ r = new InstrDTO(*this->curr_instr);
+ delete curr_instr;
+ curr_instr = nullptr;
+ }
+
+ return r;
+}
+
+void DUM::advance_helper() {}
+
+void DUM::set_curr_instr(InstrDTO *d)
+{
+ this->curr_instr = d;
+ this->status = OK;
+}
diff --git a/src/sim/ex.cc b/src/sim/ex.cc
index 3a1e92c..50882d2 100644
--- a/src/sim/ex.cc
+++ b/src/sim/ex.cc
@@ -1,9 +1,202 @@
#include "ex.h"
#include "accessor.h"
+#include "definitions.h"
#include "instrDTO.h"
#include "response.h"
#include "stage.h"
+#include <unordered_map>
-EX::EX(Stage *stage) : Stage(stage) { this->id = EXEC; }
+// clang-format off
+#define INIT_INSTRUCTION(mnemonic, body) \
+ {mnemonic, [this](signed int &s1, signed int s2) { \
+ body; \
+ }}
+// clang-format on
-InstrDTO *EX::advance(Response p) { return nullptr; }
+EX::EX(Stage *stage) : Stage(stage)
+{
+ this->id = EXEC;
+ instr_map = {
+
+ /* R type instructions */
+ INIT_INSTRUCTION(
+ ADD,
+ {
+ s1 = s1 + s2;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ SUB,
+ {
+ s1 = s1 - s2;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ MUL,
+ {
+ s1 = s1 * s2;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ QUOT,
+ {
+ s1 = s1 / s2;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ REM,
+ {
+ s1 = s1 % s2;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ SFTR,
+ {
+ s1 = s1 >> s2;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ SFTL,
+ {
+ s1 = s1 << s2;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ AND,
+ {
+ s1 = s1 & s2;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ OR,
+ {
+ s1 = s1 | s2;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ NOT,
+ {
+ s1 = ~s1;
+ (void)s2;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ XOR,
+ {
+ s1 = s1 ^ s2;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ ADDV,
+ {
+ (void)s2;
+ (void)s1;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ SUBV,
+ {
+ (void)s2;
+ (void)s1;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ MULV,
+ {
+ (void)s2;
+ (void)s1;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ DIVV,
+ {
+ (void)s2;
+ (void)s1;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ CMP,
+ {
+ (s1 > s2) ? this->set_condition(GT, true)
+ : this->set_condition(GT, false);
+ (s1 == s2) ? this->set_condition(EQ, true)
+ : this->set_condition(EQ, false);
+ }),
+
+ INIT_INSTRUCTION(
+ CEV,
+ {
+ (void)s2;
+ (void)s1;
+ (void)this;
+ }),
+
+ /* I type instructions */
+ INIT_INSTRUCTION(LOAD, {}),
+
+ INIT_INSTRUCTION(LOADV, {}),
+
+ INIT_INSTRUCTION(ADDI, {}),
+
+ INIT_INSTRUCTION(SUBI, {}),
+
+ INIT_INSTRUCTION(SFTRI, {}),
+
+ INIT_INSTRUCTION(SFTL, {}),
+
+ INIT_INSTRUCTION(ANDI, {}),
+
+ INIT_INSTRUCTION(ORI, {}),
+
+ INIT_INSTRUCTION(XORI, {}),
+
+ INIT_INSTRUCTION(STORE, {}),
+
+ INIT_INSTRUCTION(STOREV, {}),
+
+ /* J type instructions */
+ INIT_INSTRUCTION(JMP, {}),
+
+ INIT_INSTRUCTION(JRL, {}),
+
+ INIT_INSTRUCTION(JAL, {}),
+
+ INIT_INSTRUCTION(BEQ, {}),
+
+ INIT_INSTRUCTION(BGT, {}),
+
+ INIT_INSTRUCTION(BUF, {}),
+
+ INIT_INSTRUCTION(BOF, {}),
+
+ INIT_INSTRUCTION(PUSH, {}),
+
+ INIT_INSTRUCTION(POP, {}),
+
+ /* NOP */
+ INIT_INSTRUCTION(
+ NOP,
+ {
+ (void)s2;
+ (void)s1;
+ (void)this;
+ }),
+ };
+}
+
+void EX::advance_helper() {}
diff --git a/src/sim/id.cc b/src/sim/id.cc
index 969cb9d..36addbb 100644
--- a/src/sim/id.cc
+++ b/src/sim/id.cc
@@ -8,26 +8,6 @@
ID::ID(Stage *stage) : Stage(stage) { this->id = DCDE; }
-InstrDTO *ID::advance(Response p)
-{
- InstrDTO *r = nullptr;
- Response n;
-
- this->advance_helper();
- if (this->status == OK && p == OK) {
- // mutual consent
- this->curr_instr->set_time_of(this->id, this->clock_cycle);
- r = new InstrDTO(*this->curr_instr);
- delete curr_instr;
- curr_instr = nullptr;
- }
-
- n = (p != OK || this->status != OK) ? BLOCKED : OK;
- // the power of consent
- this->curr_instr = this->next->advance(n);
- return r;
-}
-
void ID::get_instr_fields(
signed int &s1, signed int &s2, signed int &s3, Mnemonic &m)
{
@@ -67,7 +47,7 @@ Response ID::read_guard(signed int &v)
{
Response r;
if (this->is_checked_out(v))
- r = BLOCKED;
+ r = STALLED;
else {
r = OK;
v = this->dereference_register(v);
@@ -116,8 +96,9 @@ void ID::decode_R_type(signed int &s1, signed int &s2, signed int &s3)
r2 = this->read_guard(s2);
this->write_guard(s3);
- this->status = (r1 == BLOCKED || r2 == BLOCKED) ? BLOCKED : OK;
+ this->status = (r1 == OK && r2 == OK) ? OK : STALLED;
}
+
void ID::decode_I_type(signed int &s1, signed int &s2, signed int &s3)
{
unsigned int s0b, s1b, s2b;
diff --git a/src/sim/if.cc b/src/sim/if.cc
index 43132ed..77a2704 100644
--- a/src/sim/if.cc
+++ b/src/sim/if.cc
@@ -18,6 +18,7 @@ InstrDTO *IF::advance(Response p)
r = new InstrDTO(*this->curr_instr);
delete curr_instr;
curr_instr = nullptr;
+ this->status = STALLED;
}
return r;
@@ -34,7 +35,6 @@ void IF::advance_helper()
this->status = r;
this->curr_instr = new InstrDTO();
this->curr_instr->set_instr_bits(bits);
- } else
- this->status = STALLED;
+ }
}
}
diff --git a/src/sim/instr.cc b/src/sim/instr.cc
index 08edf5e..e614de5 100644
--- a/src/sim/instr.cc
+++ b/src/sim/instr.cc
@@ -3,36 +3,8 @@
#include <map>
#include <unordered_map>
-// clang-format off
-#define INIT_INSTRUCTION(mnemonic, body) \
- {mnemonic, [](signed int &s1, signed int &s2, signed int &s3) { \
- body; \
- }}
-// clang-format on
-
namespace instr
{
-// clang-format off
-const std::unordered_map<Mnemonic, std::function<void(signed int &s1, signed int &s2, signed int &s3)>>
- // clang-format on
- instr_map = {
-
- /* R type instructions */
- // TODO these need to be WRAPPED with a function that sets overflow.
- // future note to self, if these are more than 2 lines each, you're
- // doing it wrong
- INIT_INSTRUCTION(ADD, s3 = s1 + s2;),
- INIT_INSTRUCTION(SUB, s3 = s1 - s2;),
-
- /* I type instructions */
-
- /* J type instructions */
-
- /* NOP */
- INIT_INSTRUCTION(NOP, (void)s3; (void)s2; (void)s1;),
-
-};
-
const std::unordered_map<unsigned int, Mnemonic> mnemonic_map = {
{0b0000100, ADD}, {0b0001000, SUB}, {0b0001100, MUL},
{0b0010000, QUOT}, {0b0010100, REM}, {0b0011000, SFTR},
@@ -48,6 +20,5 @@ const std::unordered_map<unsigned int, Mnemonic> mnemonic_map = {
{0b0001010, JRL}, {0b0001110, JAL}, {0b0010010, BEQ},
{0b0010110, BGT}, {0b0011010, BUF}, {0b0011110, BOF},
{0b0100010, PUSH}, {0b0100110, POP},
-
};
} // namespace instr
diff --git a/src/sim/mm.cc b/src/sim/mm.cc
index 5bc5836..2b73207 100644
--- a/src/sim/mm.cc
+++ b/src/sim/mm.cc
@@ -6,7 +6,4 @@
MM::MM(Stage *stage) : Stage(stage) { this->id = MEM; }
-InstrDTO *MM::advance(Response p)
-{
- return nullptr;
-}
+void MM::advance_helper() {}
diff --git a/src/sim/stage.cc b/src/sim/stage.cc
index 62a7fd6..929a4b9 100644
--- a/src/sim/stage.cc
+++ b/src/sim/stage.cc
@@ -7,7 +7,7 @@ Stage::Stage(Stage *next)
{
this->next = next;
this->curr_instr = nullptr;
- this->status = OK;
+ this->status = STALLED;
this->checked_out = {};
}
@@ -21,6 +21,39 @@ Storage *Stage::storage;
bool Stage::is_pipelined;
int Stage::clock_cycle;
+InstrDTO *Stage::advance(Response p)
+{
+ InstrDTO *r = nullptr;
+ Response n;
+
+ this->advance_helper();
+ if (this->status == OK && p == OK) {
+ // mutual consent
+ this->curr_instr->set_time_of(this->id, this->clock_cycle);
+ r = new InstrDTO(*this->curr_instr);
+ delete curr_instr;
+ curr_instr = nullptr;
+ this->status = STALLED;
+ }
+
+ n = (p != OK || this->status != OK) ? STALLED : OK;
+ // the power of consent
+ this->curr_instr = this->next->advance(n);
+ return r;
+}
+
+void Stage::set_condition(CC c, bool v)
+{
+ if (v)
+ this->gprs[3] = this->gprs[3] & 1 << c;
+ else
+ this->gprs[3] = this->gprs[3] & ~(1 << c);
+}
+
+bool Stage::get_condition(CC c) {
+ return (this->gprs[3] >> c) & 1;
+}
+
signed int Stage::dereference_register(signed int v)
{
signed int r;
diff --git a/src/sim/wb.cc b/src/sim/wb.cc
index 7a8d64c..9337aa0 100644
--- a/src/sim/wb.cc
+++ b/src/sim/wb.cc
@@ -6,4 +6,4 @@
WB::WB(Stage *stage) : Stage(stage) { this->id = WRITE; }
-InstrDTO *WB::advance(Response p) { return nullptr; }
+void WB::advance_helper() {}
diff --git a/tests/id.cc b/tests/id.cc
index 65cc16a..be50ed5 100644
--- a/tests/id.cc
+++ b/tests/id.cc
@@ -2,7 +2,7 @@
#include "cache.h"
#include "controller.h"
#include "dram.h"
-#include "if.h"
+#include "dum.h"
#include "instr.h"
#include "instrDTO.h"
#include <catch2/catch_test_macros.hpp>
@@ -14,8 +14,8 @@ class IDFixture
{
this->dr = new Dram(3);
this->c = new Cache(this->dr, 1);
- IF *f = new IF(nullptr);
- this->d = new ID(f);
+ this->dum = new DUM(nullptr);
+ this->d = new ID(dum);
this->ct = new Controller(this->d, this->c, true);
};
~IDFixture()
@@ -23,6 +23,12 @@ class IDFixture
delete this->ct;
delete this->c;
};
+ void prime_bits(signed int raw)
+ {
+ InstrDTO *i = new InstrDTO();
+ i->set_instr_bits(raw);
+ this->dum->set_curr_instr(i);
+ }
signed int encode_R_type(
signed int s3,
signed int s2,
@@ -63,10 +69,11 @@ class IDFixture
t = (t << TYPE_SIZE) + type;
return t;
}
-
+
Dram *dr;
Cache *c;
ID *d;
+ DUM *dum;
Controller *ct;
};
@@ -82,88 +89,126 @@ TEST_CASE_METHOD(IDFixture, "Parse invalid type", "[id]")
TEST_CASE_METHOD(IDFixture, "Parse arbitrary r-type # one", "[id]")
{
- signed int s1 = -1, s2 = -1, s3 = -1;
- Mnemonic m;
+ signed int t;
+ InstrDTO *i;
- s1 = this->encode_R_type(0b0, 0b1, 0b10, 0b11, 0b0);
- this->d->get_instr_fields(s1, s2, s3, m);
+ t = this->encode_R_type(0b0, 0b1, 0b10, 0b11, 0b0);
+ this->prime_bits(t);
+
+ i = this->ct->advance(OK);
+ REQUIRE(i == nullptr);
+ i = this->ct->advance(OK);
+ REQUIRE(i != nullptr);
- CHECK(s1 == 0x00000000); // registers are empty
- CHECK(s2 == 0x00000000);
- CHECK(s3 == 0x00000000);
- CHECK(m == MUL);
+ CHECK(i->get_s1() == 0x00000000); // registers are empty
+ CHECK(i->get_s2() == 0x00000000);
+ CHECK(i->get_s3() == 0x00000000);
+ CHECK(i->get_mnemonic() == MUL);
+
+ delete i;
}
TEST_CASE_METHOD(IDFixture, "Parse arbitrary r-type # two", "[id]")
{
- signed int s1 = -1, s2 = -1, s3 = -1;
- Mnemonic m;
+ signed int t;
+ InstrDTO *i;
- s1 = this->encode_R_type(0b10000, 0b01000, 0b00100, 0b10, 0b0);
- this->d->get_instr_fields(s1, s2, s3, m);
+ t = this->encode_R_type(0b10000, 0b01000, 0b00100, 0b10, 0b0);
+ this->prime_bits(t);
+
+ i = this->ct->advance(OK);
+ REQUIRE(i == nullptr);
+ i = this->ct->advance(OK);
+ REQUIRE(i != nullptr);
- CHECK(s1 == 0x00000000); // registers are empty
- CHECK(s2 == 0b00000000);
- CHECK(s3 == 0b00000000);
- CHECK(m == SUB);
+ CHECK(i->get_s1() == 0x00000000); // registers are empty
+ CHECK(i->get_s2() == 0x00000000);
+ CHECK(i->get_s3() == 0x00000000);
+ CHECK(i->get_mnemonic() == SUB);
+
+ delete i;
}
TEST_CASE_METHOD(IDFixture, "Parse arbitrary i-type # one", "[id]")
{
- signed int s1 = -1, s2 = -1, s3 = -1;
- Mnemonic m;
+ signed int t;
+ InstrDTO *i;
- s1 = this->encode_I_type(0xF, 0b1, 0b10, 0b0111, 0b1);
- this->d->get_instr_fields(s1, s2, s3, m);
+ t = this->encode_I_type(0xF, 0b1, 0b10, 0b0111, 0b1);
+ this->prime_bits(t);
- CHECK(s1 == 0x00000000); // registers are empty
- CHECK(s2 == 0x00000000);
- CHECK(s3 == 0xF);
- CHECK(m == SFTLI);
+ i = this->ct->advance(OK);
+ REQUIRE(i == nullptr);
+ i = this->ct->advance(OK);
+ REQUIRE(i != nullptr);
+
+ CHECK(i->get_s1() == 0x00000000); // registers are empty
+ CHECK(i->get_s2() == 0x00000000);
+ CHECK(i->get_s3() == 0xF);
+ CHECK(i->get_mnemonic() == SFTLI);
+
+ delete i;
}
TEST_CASE_METHOD(IDFixture, "Parse arbitrary i-type # two", "[id]")
{
- signed int s1 = -1, s2 = -1, s3 = -1;
- Mnemonic m;
+ signed int t;
+ InstrDTO *i;
- s1 = this->encode_I_type(0xCC, 0b010, 0b101, 0b1011, 0b1);
- this->d->get_instr_fields(s1, s2, s3, m);
+ t = this->encode_I_type(0xCC, 0b010, 0b101, 0b1011, 0b1);
+ this->prime_bits(t);
- CHECK(s1 == 0x00000000); // registers are empty
- CHECK(s2 == 0x00000000);
- CHECK(s3 == 0xCC);
- CHECK(m == STORE);
+ i = this->ct->advance(OK);
+ REQUIRE(i == nullptr);
+ i = this->ct->advance(OK);
+ REQUIRE(i != nullptr);
+
+ CHECK(i->get_s1() == 0x00000000); // registers are empty
+ CHECK(i->get_s2() == 0x00000000);
+ CHECK(i->get_s3() == 0xCC);
+ CHECK(i->get_mnemonic() == STORE);
+
+ delete i;
}
TEST_CASE_METHOD(IDFixture, "Parse arbitrary j-type # one", "[id]")
{
- signed int s1 = -1, s2 = -1, s3 = -1;
- Mnemonic m;
+ signed int t;
+ InstrDTO *i;
- s1 = this->encode_J_type(0x3456, 0b10101, 0b0111, 0b10);
- this->d->get_instr_fields(s1, s2, s3, m);
+ t = this->encode_J_type(0x3456, 0b10101, 0b0111, 0b10);
+ this->prime_bits(t);
+
+ i = this->ct->advance(OK);
+ REQUIRE(i == nullptr);
+ i = this->ct->advance(OK);
+ REQUIRE(i != nullptr);
- CHECK(s1 == 0x00000000); // registers are empty
- CHECK(s2 == 0x3456);
- CHECK(m == BOF);
- // behavior does nothing
- CHECK(s3 == -1);
+ CHECK(i->get_s1() == 0x00000000); // registers are empty
+ CHECK(i->get_s2() == 0x3456);
+ CHECK(i->get_mnemonic() == BOF);
+
+ delete i;
}
TEST_CASE_METHOD(IDFixture, "Parse arbitrary j-type # two", "[id]")
{
- signed int s1 = -1, s2 = -1, s3 = -1;
- Mnemonic m;
+ signed int t;
+ InstrDTO *i;
- s1 = this->encode_J_type(0xBBCCF, 0b10101, 0b0011, 0b10);
- this->d->get_instr_fields(s1, s2, s3, m);
+ t = this->encode_J_type(0xBBCCF, 0b10101, 0b0011, 0b10);
+ this->prime_bits(t);
+
+ i = this->ct->advance(OK);
+ REQUIRE(i == nullptr);
+ i = this->ct->advance(OK);
+ REQUIRE(i != nullptr);
+
+ CHECK(i->get_s1() == 0x00000000); // registers are empty
+ CHECK(i->get_s2() == 0xBBCCF);
+ CHECK(i->get_mnemonic() == JAL);
- CHECK(s1 == 0x00000000); // registers are empty
- CHECK(s2 == 0xBBCCF);
- CHECK(m == JAL);
- // behavior does nothing
- CHECK(s3 == -1);
+ delete i;
}
TEST_CASE_METHOD(IDFixture, "read does not conflict with read", "[id]")
@@ -221,7 +266,7 @@ TEST_CASE_METHOD(IDFixture, "read does conflict with write", "[id]")
v = 0b1;
r = this->d->read_guard(v);
CHECK(v == 0b01);
- REQUIRE(r == BLOCKED);
+ REQUIRE(r == STALLED);
}
TEST_CASE_METHOD(IDFixture, "stores indefinite conflicts", "[id]")
@@ -242,10 +287,10 @@ TEST_CASE_METHOD(IDFixture, "stores indefinite conflicts", "[id]")
v = 0b110;
r = this->d->read_guard(v);
CHECK(v == 0b110);
- REQUIRE(r == BLOCKED);
+ REQUIRE(r == STALLED);
v = 0b0;
r = this->d->read_guard(v);
CHECK(v == 0b0);
- REQUIRE(r == BLOCKED);
+ REQUIRE(r == STALLED);
}
diff --git a/tests/if.cc b/tests/if.cc
index 185a52a..1f02cb0 100644
--- a/tests/if.cc
+++ b/tests/if.cc
@@ -113,17 +113,17 @@ TEST_CASE_METHOD(IFPipeFixture, "fetch waits with old instruction",
expected_cycles = this->m_delay + (this->c_delay * 2) + 1;
for (j = 0; j < this->m_delay + 1; ++j) {
- i = this->ct->advance(BLOCKED);
+ i = this->ct->advance(STALLED);
// check response
CHECK(i == nullptr);
}
for (j = 0; j < this->c_delay; ++j) {
- i = this->ct->advance(BLOCKED);
+ i = this->ct->advance(STALLED);
// check response
CHECK(i == nullptr);
}
for (j = 0; j < expected_cycles - fetch_cycles; ++j) {
- i = this->ct->advance(BLOCKED);
+ i = this->ct->advance(STALLED);
// check response
CHECK(i != nullptr);
}