summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gui/worker.cc84
-rw-r--r--inc/controller.h6
-rw-r--r--inc/ex.h19
-rw-r--r--inc/id.h2
-rw-r--r--inc/stage.h6
-rw-r--r--src/sim/controller.cc16
-rw-r--r--src/sim/ex.cc22
-rw-r--r--src/sim/id.cc34
-rw-r--r--src/sim/if.cc3
-rw-r--r--src/sim/mm.cc11
-rw-r--r--src/sim/stage.cc1
-rw-r--r--src/sim/wb.cc8
-rw-r--r--tests/controller.cc320
-rw-r--r--tests/id.cc78
-rw-r--r--tests/if.cc2
15 files changed, 163 insertions, 449 deletions
diff --git a/gui/worker.cc b/gui/worker.cc
index 9202b89..a912e06 100644
--- a/gui/worker.cc
+++ b/gui/worker.cc
@@ -12,42 +12,66 @@ void Worker::doWork()
this->ex_stage = new EX(id_stage);
this->mm_stage = new MM(ex_stage);
this->wb_stage = new WB(mm_stage);
- this->ct = new Controller(wb_stage, this->c, true);
+ this->ct = new Controller(wb_stage, this->c, false);
emit clock_cycles(this->ct->get_clock_cycle(), this->ct->get_pc());
emit dram_storage(this->d->view(0, 32));
emit cache_storage(this->c->view(0, 7));
emit register_storage(this->ct->get_gprs());
- signed int b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14,
- b15, b16, b17, b18, b19, b20;
std::vector<signed int> p;
- // I-TYPE / / / /
- b0 = 0b00000010000000000001000000001101;
- b1 = 0b00000000000000010010100000001101;
- b2 = 0b00000000000000000010100010101001;
- b3 = 0b00000000000000100010100000001101;
- b4 = 0b00000000000000010010100010101001;
- b5 = 0b00000000000000110010100000001101;
- b6 = 0b00000000000000100010100010101001;
- b7 = 0b00000000000001000010100000001101;
- b8 = 0b00000000000000110010100010101001;
- b9 = 0b00000000000000000010100000001101;
- b10 = 0b00000000000000110011000000001101;
- b11 = 0b00000000000000000011100000001010;
- b12 = 0b00000000000100100101000100000100;
- b13 = 0b00000000000000000100100111000101;
- b14 = 0b00000000000000010100101000000101;
- b15 = 0b00000000000011101000001110000100;
- b16 = 0b00000000000000000011101001101001;
- b17 = 0b00000000000000010010100101001101;
- b18 = 0b00000000000000000101001101000000;
- b19 = 0b11111111111111111100100000010110;
- // b20 = 0b00000000000000000000000000010000;
+ p.push_back(0b00000000000000010010100000001101);
+ p.push_back(0b00000000000000000000000101100010);
+ p.push_back(0b00000000000000010010100101001101);
+ p.push_back(0b00000000000000000000000101100010);
+ p.push_back(0b00000000000000010010100101001101);
+ p.push_back(0b00000000000000000000000101100010);
+ p.push_back(0b00000000000000010010100101001101);
+ p.push_back(0b00000000000000000000000101100010);
+ p.push_back(0b00000000000000000000000101100110);
+ p.push_back(0b00000000000000000000000110100110);
+ p.push_back(0b00000000000000000000000111100110);
+ p.push_back(0b00000000000000000000001000100110);
+ p.push_back(0b00000000000000000000000000101110);
+ p.push_back(0b00000000000000000000000000101110);
+ p.push_back(0b00000000000000000000000000010000);
- p = {b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10,
- b11, b12, b13, b14, b15, b16, b17, b18, b19};
+ // p.push_back(0b00000000000000000010100010001101);
+ // p.push_back(0b11111111111101010011000000001101);
+ // p.push_back(0b00000000000000000000000110100010);
+ // p.push_back(0b00000000000000000011000000001110);
+ // p.push_back(0b00000000000000000000000110100110);
+ // p.push_back(0b00000000001000100011000000101001);
+ // p.push_back(0b00000000000000000000000101100010);
+ // p.push_back(0b00000000000000000010100010001101);
+ // p.push_back(0b00000000000000010001000010010001);
+ // p.push_back(0b11111111111010010011000000001101);
+ // p.push_back(0b11111111111111000011000101101001);
+ // p.push_back(0b00000000000001000010100111000101);
+ // p.push_back(0b11111111111111000010100110000101);
+ // p.push_back(0b00000000000011000111001100000100);
+ // p.push_back(0b00000000000000000000000110100010);
+ // p.push_back(0b00000000000000001010100000001110);
+ // p.push_back(0b00000000000000000000000110100110);
+ // p.push_back(0b00000000000001000011000101101001);
+ // p.push_back(0b00000000000000000001000101001101);
+ // p.push_back(0b00000000000000000000000101100110);
+ // p.push_back(0b00000000000000000000000000101010);
+ // p.push_back(0b00000000000000000000000101100010);
+ // p.push_back(0b00000000000000000010100010001101);
+ // p.push_back(0b00000000000000010001000010010001);
+ // p.push_back(0b00000000010011000011000000001101);
+ // p.push_back(0b11111111111111000011000101101001);
+ // p.push_back(0b00000000000001000010100111000101);
+ // p.push_back(0b11111111111111000010100110000101);
+ // p.push_back(0b00000000000011000111001100000100);
+ // p.push_back(0b00000000000001000011000101101001);
+ // p.push_back(0b00000000000000000001000101001101);
+ // p.push_back(0b00000000000000000000000101100110);
+ // p.push_back(0b00000000000000000000000000101010);
+ // p.push_back(0b00000000000000000000000000010000);
+ // p.push_back(0b00000000000000000000000000000000);
this->d->load(p);
}
@@ -69,7 +93,7 @@ void Worker::refreshDram()
void Worker::refreshCache()
{
qDebug() << "Refreshing Dram";
- emit cache_storage(this->c->view(0, 7));
+ emit cache_storage(this->c->view(24, 31));
}
void Worker::refreshRegisters()
@@ -96,9 +120,9 @@ void Worker::runSteps(int steps)
void Worker::runStep()
{
qDebug() << "Running for 1 step ";
- this->ct->advance(WAIT);
+ this->ct->run_for(1);
emit dram_storage(this->d->view(0, 256));
- emit cache_storage(this->c->view(0, 7));
+ emit cache_storage(this->c->view(24, 8));
emit register_storage(this->ct->get_gprs());
emit clock_cycles(this->ct->get_clock_cycle(), this->ct->get_pc());
emit if_info(this->if_stage->stage_info());
diff --git a/inc/controller.h b/inc/controller.h
index f56b1b4..778c5bc 100644
--- a/inc/controller.h
+++ b/inc/controller.h
@@ -19,7 +19,7 @@ class Controller : public Stage
*/
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.
@@ -38,10 +38,6 @@ class Controller : public Stage
*/
int get_pc();
- void set_gprs(int index, int value);
-
- void set_pipelined(bool value);
-
private:
void advance_helper() override;
};
diff --git a/inc/ex.h b/inc/ex.h
index e4c9d2b..f63539c 100644
--- a/inc/ex.h
+++ b/inc/ex.h
@@ -3,8 +3,16 @@
#include "instrDTO.h"
#include "response.h"
#include "stage.h"
+#include <exception>
#include <unordered_map>
+class HaltException : public std::exception
+{
+ const char *what() const noexcept override {
+ return "";
+ }
+};
+
class EX : public Stage
{
public:
@@ -19,13 +27,22 @@ class EX : public Stage
private:
void advance_helper();
/**
+ * Wrapper for division functions, which detects HALT instructinos (division
+ * by 0).
+ * @param the numerator
+ * @param the denominator
+ * @param if the modulo operator should instead be used
+ */
+ void handle_divide(signed int &s1, signed int s2, bool is_mod);
+ /**
* 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, signed int s3, unsigned int pc)>>
+ std::function<void(
+ signed int &s1, signed int s2, signed int s3, unsigned int pc)>>
instr_map;
};
diff --git a/inc/id.h b/inc/id.h
index c1810ae..09f0a7c 100644
--- a/inc/id.h
+++ b/inc/id.h
@@ -69,7 +69,7 @@ class ID : public Stage
void get_instr_fields(signed int &s1, signed int &s2, signed int &s3, Mnemonic &m, Type &t);
void decode_R_type(signed int &s1, signed int &s2, signed int &s3, Mnemonic &m);
void decode_I_type(signed int &s1, signed int &s2, signed int &s3, Mnemonic &m);
- void decode_J_type(signed int &s1, signed int &s2, signed int &s3);
+ void decode_J_type(signed int &s1, signed int &s2, signed int &s3, Mnemonic &m);
/**
* Helper for `get_instr_fields`.
* Given a raw instruction, returns the mnemonic and type.
diff --git a/inc/stage.h b/inc/stage.h
index 1cedac6..996c21c 100644
--- a/inc/stage.h
+++ b/inc/stage.h
@@ -119,6 +119,11 @@ class Stage
*/
static bool is_pipelined;
/**
+ * A flag which tells fetch when the pipe is empty. Only used when the pipe
+ * is turned off.
+ */
+ static bool is_empty;
+ /**
* The current clock cycle.
*/
static int clock_cycle;
@@ -134,7 +139,6 @@ class Stage
* The current status of this stage.
*/
Response status;
-
};
#endif /* STAGE_H_INCLUDED */
diff --git a/src/sim/controller.cc b/src/sim/controller.cc
index 65e5676..db6106c 100644
--- a/src/sim/controller.cc
+++ b/src/sim/controller.cc
@@ -1,4 +1,5 @@
#include "controller.h"
+#include "ex.h"
#include "response.h"
#include "storage.h"
@@ -8,9 +9,11 @@ Controller::Controller(Stage *stage, Storage *storage, bool is_pipelined)
this->clock_cycle = 1;
this->storage = storage;
this->is_pipelined = is_pipelined;
+ this->is_empty = true;
this->pc = 0x0;
this->checked_out = {};
this->gprs = {0};
+ this->gprs.at(2) = MEM_WORDS; // set the stack pointer
// grant side-door access
this->id = SIDE;
}
@@ -19,7 +22,11 @@ void Controller::run_for(int number)
{
int i;
for (i = 0; i < number; ++i) {
- this->advance(WAIT);
+ try {
+ this->advance(WAIT);
+ } catch (HaltException &e) {
+ break;
+ }
}
}
@@ -27,10 +34,6 @@ int Controller::get_clock_cycle() { return this->clock_cycle; }
std::array<int, GPR_NUM> Controller::get_gprs() { return this->gprs; }
-void Controller::set_gprs(int index, int value) { this->gprs[index] = value; }
-
-void Controller::set_pipelined(bool value) { this->is_pipelined = value; }
-
int Controller::get_pc() { return this->pc; }
InstrDTO *Controller::advance(Response p)
@@ -39,6 +42,9 @@ InstrDTO *Controller::advance(Response p)
r = this->next->advance(p);
++this->clock_cycle;
+ if (r)
+ this->is_empty = true;
+
return r;
}
diff --git a/src/sim/ex.cc b/src/sim/ex.cc
index d20d15f..62e39c1 100644
--- a/src/sim/ex.cc
+++ b/src/sim/ex.cc
@@ -49,15 +49,15 @@ EX::EX(Stage *stage) : Stage(stage)
INIT_INSTRUCTION(
QUOT,
{
- s1 = s1 / s2;
+ this->handle_divide(s1, s2, false);
(void)pc;
(void)s3;
- (void)this;
}),
INIT_INSTRUCTION(
REM,
{
+ this->handle_divide(s1, s2, true);
s1 = s1 % s2;
(void)pc;
(void)s3;
@@ -340,20 +340,18 @@ EX::EX(Stage *stage) : Stage(stage)
INIT_INSTRUCTION(
PUSH,
{
+ s1 = s1 + s3;
(void)pc;
- (void)s3;
(void)s2;
- (void)s1;
(void)this;
}),
INIT_INSTRUCTION(
POP,
{
+ s1 = s1 + s3;
(void)pc;
- (void)s3;
(void)s2;
- (void)s1;
(void)this;
}),
@@ -387,3 +385,15 @@ void EX::advance_helper()
this->curr_instr->set_s1(s1);
this->status = OK;
}
+
+void EX::handle_divide(signed int &s1, signed int s2, bool is_mod)
+{
+ if (s2 == 0) {
+ // handle everything here
+ this->curr_instr->set_s1(MAX_INT);
+ this->status = OK;
+ throw HaltException();
+ } else {
+ s1 = (is_mod) ? s1 % s2 : s1 / s2;
+ }
+}
diff --git a/src/sim/id.cc b/src/sim/id.cc
index 37c6773..d10d695 100644
--- a/src/sim/id.cc
+++ b/src/sim/id.cc
@@ -86,7 +86,7 @@ void ID::get_instr_fields(
break;
case 0b10:
t = J;
- this->decode_J_type(s1, s2, s3);
+ this->decode_J_type(s1, s2, s3, m);
break;
case 0b11:
t = INV;
@@ -159,8 +159,10 @@ void ID::decode_I_type(
this->status = r1;
}
-void ID::decode_J_type(signed int &s1, signed int &s2, signed int &s3)
+void ID::decode_J_type(
+ signed int &s1, signed int &s2, signed int &s3, Mnemonic &m)
{
+ Response r1, r2;
unsigned int s0b, s1b;
s0b = REG_SIZE;
@@ -169,7 +171,33 @@ void ID::decode_J_type(signed int &s1, signed int &s2, signed int &s3)
s2 = GET_BITS_SIGN_EXTEND(s1, s0b, s1b);
s1 = GET_LS_BITS(s1, s0b);
- this->status = this->read_guard(*&s1);
+ switch (m) {
+ case PUSH:
+ s2 = s1; // source
+ s3 = 2; // stack pointer
+ s1 = -1; // increment amount
+ r1 = this->read_guard(s2);
+ r2 = (this->is_checked_out(s3)) ? STALLED : OK; // we read the stack pointer
+ if (r1 == OK && r2 == OK) {
+ this->write_guard(s3); // we write the stack pointer
+ }
+ this->status = (r1 == OK && r2 == OK) ? OK : STALLED;
+ break;
+ case POP:
+ s2 = s1; // destination
+ s3 = 2; // stack pointer
+ s1 = 1; // increment amount
+ r1 = (this->is_checked_out(s3)) ? STALLED : OK; // we read the stack pointer
+ if (r1 == OK) {
+ this->write_guard(s2);
+ this->write_guard(s3); // we write the stack pointer
+ }
+ this->status = r1;
+ break;
+ default:
+ this->status = this->read_guard(*&s1);
+ }
+
}
std::vector<int> ID::stage_info()
diff --git a/src/sim/if.cc b/src/sim/if.cc
index 1223149..bab2608 100644
--- a/src/sim/if.cc
+++ b/src/sim/if.cc
@@ -37,13 +37,14 @@ void IF::advance_helper()
int i;
signed int bits;
- if (this->curr_instr == nullptr) {
+ if (this->curr_instr == nullptr && (this->is_pipelined || this->is_empty)) {
i = this->storage->read_word(this, this->pc, bits);
r = i ? OK : STALLED;
if (r == OK) {
this->curr_instr = new InstrDTO();
this->curr_instr->set_instr_bits(bits);
this->curr_instr->set_pc(this->pc);
+ this->is_empty = false;
}
}
}
diff --git a/src/sim/mm.cc b/src/sim/mm.cc
index a9a60c2..a02ca83 100644
--- a/src/sim/mm.cc
+++ b/src/sim/mm.cc
@@ -21,8 +21,8 @@ void MM::advance_helper()
this->status = STALLED;
break;
+ case PUSH:
case STORE:
- // TODO signed issues, we aren't wrapping addresses
i = this->storage->write_word(
this, this->curr_instr->get_s2(), this->curr_instr->get_s1());
this->status = i ? OK : STALLED;
@@ -31,6 +31,15 @@ void MM::advance_helper()
}
break;
+ case POP:
+ i = this->storage->read_word(this, this->curr_instr->get_s3(), data);
+ this->status = i ? OK : STALLED;
+ if (this->status == OK) {
+ this->curr_instr->set_s3(data);
+ } else
+ this->status = STALLED;
+ break;
+
default:
this->status = OK;
}
diff --git a/src/sim/stage.cc b/src/sim/stage.cc
index 7df1dba..9528e4b 100644
--- a/src/sim/stage.cc
+++ b/src/sim/stage.cc
@@ -17,6 +17,7 @@ std::deque<signed int> Stage::checked_out;
unsigned int Stage::pc;
Storage *Stage::storage;
bool Stage::is_pipelined;
+bool Stage::is_empty;
int Stage::clock_cycle;
bool Stage::get_condition(CC c) { return (this->gprs[3] >> c) & 1; }
diff --git a/src/sim/wb.cc b/src/sim/wb.cc
index 4e6b2b0..c62468c 100644
--- a/src/sim/wb.cc
+++ b/src/sim/wb.cc
@@ -28,9 +28,17 @@ void WB::write_handler()
throw std::runtime_error("instruction tried to pop a register out of "
"an empty queue during writeback.");
+ if (this->curr_instr->get_mnemonic() == POP) {
+ // POP performs a second register write
+ reg = this->checked_out.front();
+ this->checked_out.pop_front();
+ this->store_register(reg, this->curr_instr->get_s3());
+ }
+
this->checked_out.pop_front();
reg = this->curr_instr->get_checked_out();
this->store_register(reg, this->curr_instr->get_s1());
+
}
void WB::jump_handler()
diff --git a/tests/controller.cc b/tests/controller.cc
index 59f1d81..1d1ddb6 100644
--- a/tests/controller.cc
+++ b/tests/controller.cc
@@ -46,323 +46,3 @@ class ControllerPipeFixture
Dram *d;
Controller *ct;
};
-
-TEST_CASE_METHOD(
- ControllerPipeFixture,
- "Contructor resets gettable fields",
- "[controller_pipe]")
-{
- std::array<int, GPR_NUM> gprs;
-
- gprs = this->ct->get_gprs();
-
- CHECK(this->ct->get_clock_cycle() == 1);
- CHECK(std::all_of(
- gprs.begin(), gprs.end(), [](int value) { return value == 0; }));
- // change me later
- CHECK(this->ct->get_pc() == 0);
-}
-
-TEST_CASE_METHOD(ControllerPipeFixture, "two num adder", "[full pipe]")
-{
- signed int b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14,
- b15;
- std::vector<signed int> p;
- InstrDTO *i;
-
- // I-TYPE / / / /
- b0 = 0b00000010000000000001000000001101; // ADDI $2 $0 0x200;
- b1 = 0b00000000000000010010100000001101; // ADDI $5 $0 0x1;
- b2 = 0b00000000000000000010100010101101; // STORE $5 0($2); (RAW HAZARD w
- // 1)!
- // I-TYPE / / / /
- b3 = 0b00000000000000100010100000001101; // ADDI $5 $0 0x2; (RAW HAZARD)!
- b4 = 0b00000000000000010010100010101101; // STORE $5 1($2); (RAW HAZARD)!
- // // I-TYPE / / / /
- b5 = 0b00000000000000000010100000001101; // ADDI $5 $0 0x0;
- // // I-TYPE / / / /
- b6 = 0b00000000000000010011000000001101; // ADDI $6 $0 0x1;
- // // J-TYPE / / /
- b7 = 0b00000000000000000011100000001010; // JRL CHECK
- // // R-TYPE / / / / /
- b8 = 0b00000000000100100101000100000100; // ADD $9 $2 $5;
- // // I-TYPE / / / /
- b9 = 0b00000000000000000011101001000101; // LOAD $7 0($9); (RAW HAZARD)!
- // // I-TYPE / / / /
- b10 = 0b00000000000000010100001001000101; // LOAD $8 1($9);
- // // R-TYPE / / / / /
- b11 = 0b00000000000011101000001110000100; // ADD $7 $7 $8;
- // I-TYPE / / / /
- b12 = 0b00000000000000000011101001101101; // STORE $7 0($9);
- b13 = 0b00000010000000010010100101001101; // ADDI $5 $5 0x1;
- // // R-TYPE / / / / /
- b14 = 0b00000000000111100101001101000000; // CMP $6 $5
- // // J-TYPE / / /
- b15 = 0b11111111111111111100100000010110; // bgt LOOP
-
- p = {b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15};
- this->d->load(p);
-
- this->fill_pipe();
- i = this->ct->advance(WAIT);
- REQUIRE(i != nullptr);
-
- CHECK(i->get_s1() == 0x200);
- CHECK(i->get_s2() == 0x0);
- CHECK(i->get_s3() == 0x200);
- CHECK(this->ct->get_gprs().at(2) == 0x200);
- CHECK(i->get_mnemonic() == ADDI);
- CHECK(i->get_instr_bits() == b0);
- CHECK(this->ct->checked_out.front() == 0x5);
-
- delete i;
- i = this->ct->advance(WAIT);
- REQUIRE(i != nullptr);
-
- CHECK(i->get_s1() == 0x1);
- CHECK(i->get_s2() == 0x0);
- CHECK(i->get_s3() == 0x1);
- CHECK(this->ct->get_gprs().at(5) == 0x1);
- CHECK(i->get_mnemonic() == ADDI);
- CHECK(i->get_instr_bits() == b1);
-
- delete i;
- i = this->ct->advance(WAIT);
- REQUIRE(i == nullptr);
- i = this->ct->advance(WAIT);
- REQUIRE(i == nullptr);
- i = this->ct->advance(WAIT);
- REQUIRE(i == nullptr);
- i = this->ct->advance(WAIT);
- REQUIRE(i == nullptr);
- i = this->ct->advance(WAIT);
- REQUIRE(i == nullptr);
- i = this->ct->advance(WAIT);
- REQUIRE(i == nullptr);
- i = this->ct->advance(WAIT);
- REQUIRE(i != nullptr);
-
- CHECK(i->get_s1() == 0x200);
- CHECK(i->get_s2() == 0x1);
- CHECK(i->get_s3() == 0x0);
- // NO STORE
- CHECK(this->ct->get_gprs().at(2) == 0x200);
- CHECK(this->ct->get_gprs().at(5) == 0x1);
- CHECK(i->get_mnemonic() == STORE);
- CHECK(i->get_instr_bits() == b2);
- CHECK(this->ct->checked_out.front() == 0x5);
-
- delete i;
- i = this->ct->advance(WAIT);
- REQUIRE(i != nullptr);
-
- CHECK(i->get_s1() == 0x2);
- CHECK(i->get_s2() == 0x1); // the previous value in the destination register
- CHECK(i->get_s3() == 0x2);
- CHECK(this->ct->get_gprs().at(2) == 0x200);
- CHECK(this->ct->get_gprs().at(5) == 0x2);
- CHECK(i->get_mnemonic() == ADDI);
- CHECK(i->get_instr_bits() == b3);
-
- delete i;
- i = this->ct->advance(WAIT);
- REQUIRE(i == nullptr);
- i = this->ct->advance(WAIT);
- REQUIRE(i == nullptr);
- i = this->ct->advance(WAIT);
- REQUIRE(i != nullptr);
-
- CHECK(i->get_s1() == 0x201);
- CHECK(i->get_s2() == 0x2); // address
- CHECK(i->get_s3() == 0x1); // offset
- // NO STORE
- CHECK(this->ct->get_gprs().at(2) == 0x200);
- CHECK(this->ct->get_gprs().at(5) == 0x2);
- CHECK(i->get_mnemonic() == STORE);
- CHECK(i->get_instr_bits() == b4);
- // CHECK(this->ct->checked_out.front() == 0x5);
-
- delete i;
- i = this->ct->advance(WAIT);
- REQUIRE(i != nullptr);
-
- CHECK(i->get_s1() == 0x0);
- CHECK(i->get_s2() == 0x2);
- CHECK(i->get_s3() == 0x0);
- CHECK(this->ct->get_gprs().at(2) == 0x200);
- CHECK(this->ct->get_gprs().at(5) == 0x0);
- CHECK(i->get_mnemonic() == ADDI);
- CHECK(i->get_instr_bits() == b5);
-
- delete i;
- i = this->ct->advance(WAIT);
- REQUIRE(i != nullptr);
-
- CHECK(i->get_s1() == 0x1);
- CHECK(i->get_s2() == 0x0);
- CHECK(i->get_s3() == 0x1);
- CHECK(this->ct->get_gprs().at(2) == 0x200);
- CHECK(this->ct->get_gprs().at(6) == 0x1);
- CHECK(i->get_pc() == 0x6);
- CHECK(this->ct->get_pc() == 0x9);
- CHECK(i->get_mnemonic() == ADDI);
- CHECK(i->get_instr_bits() == b6);
-
- delete i;
- i = this->ct->advance(WAIT);
- REQUIRE(i != nullptr);
-
- CHECK(i->get_s1() == 0xE);
- CHECK(i->get_s2() == 0x7);
- CHECK(this->ct->get_gprs().at(2) == 0x200);
- CHECK(this->ct->get_gprs().at(6) == 0x1);
- CHECK(i->get_pc() == 0x7);
- CHECK(this->ct->get_pc() == 0xE);
- CHECK(i->get_mnemonic() == JRL);
- CHECK(i->get_instr_bits() == b7);
-
- delete i;
- i = this->ct->advance(WAIT);
- REQUIRE(i == nullptr); // switching cache lines in fetch
- i = this->ct->advance(WAIT);
- REQUIRE(i == nullptr);
- i = this->ct->advance(WAIT);
- REQUIRE(i != nullptr);
-
- CHECK(i->get_mnemonic() == NOP); // squashed
-
- delete i;
- i = this->ct->advance(WAIT); // nops?
- REQUIRE(i == nullptr);
- i = this->ct->advance(WAIT);
- REQUIRE(i == nullptr);
- i = this->ct->advance(WAIT);
- REQUIRE(i != nullptr);
-
- CHECK(i->get_s1() == 0x1);
- CHECK(i->get_s2() == 0x0);
- CHECK(i->get_s3() == 0x0);
- CHECK(this->ct->get_gprs().at(2) == 0x200);
- CHECK(this->ct->get_gprs().at(5) == 0x0);
- CHECK(this->ct->get_gprs().at(6) == 0x1);
- CHECK(this->ct->get_condition(GT) == true);
- CHECK(this->ct->get_condition(EQ) == false);
- CHECK(i->get_mnemonic() == CMP);
- CHECK(i->get_instr_bits() == b14);
-
- delete i;
- i = this->ct->advance(WAIT);
- REQUIRE(i != nullptr);
-
- CHECK(i->get_s1() == 0x8);
- CHECK(i->get_s2() == 0xfffffff9);
- CHECK(this->ct->get_gprs().at(2) == 0x200);
- CHECK(this->ct->get_gprs().at(5) == 0x0);
- CHECK(this->ct->get_gprs().at(6) == 0x1);
- CHECK(this->ct->get_condition(GT) == true);
- CHECK(this->ct->get_condition(EQ) == false);
- CHECK(this->ct->get_pc() == 0x9);
- CHECK(i->get_mnemonic() == BGT);
- CHECK(i->get_instr_bits() == b15);
-
- delete i;
- i = this->ct->advance(WAIT);
- REQUIRE(i == nullptr);
- i = this->ct->advance(WAIT);
- REQUIRE(i == nullptr);
- i = this->ct->advance(WAIT);
- REQUIRE(i != nullptr);
-
- CHECK(i->get_mnemonic() == NOP);
-
- delete i;
- i = this->ct->advance(WAIT);
- REQUIRE(i != nullptr); // it was already in cache
-
- CHECK(i->get_s1() == 0x200);
- CHECK(i->get_s2() == 0x0);
- CHECK(i->get_s3() == 0x0);
- CHECK(this->ct->get_gprs().at(2) == 0x200);
- CHECK(this->ct->get_gprs().at(6) == 0x1);
- CHECK(this->ct->get_gprs().at(9) == 0x200);
- CHECK(i->get_pc() == 0x8);
- CHECK(this->ct->get_pc() == 0xB);
- CHECK(i->get_mnemonic() == ADD);
- CHECK(i->get_instr_bits() == b8);
- CHECK(this->ct->checked_out.front() == 0x7);
-
- delete i;
- i = this->ct->advance(WAIT); // RAW
- REQUIRE(i == nullptr);
- i = this->ct->advance(WAIT);
- REQUIRE(i == nullptr);
- i = this->ct->advance(WAIT);
- REQUIRE(i != nullptr);
-
- CHECK(i->get_s1() == 0x1);
- CHECK(i->get_s2() == 0x0);
- CHECK(i->get_s3() == 0x0);
- CHECK(this->ct->get_gprs().at(2) == 0x200);
- CHECK(this->ct->get_gprs().at(6) == 0x1);
- CHECK(this->ct->get_gprs().at(7) == 0x1);
- CHECK(this->ct->get_gprs().at(9) == 0x200);
- CHECK(i->get_mnemonic() == LOAD);
- CHECK(i->get_instr_bits() == b9);
- CHECK(this->ct->checked_out.front() == 0x8);
-
- delete i;
- i = this->ct->advance(WAIT);
- REQUIRE(i != nullptr);
-
- CHECK(i->get_s1() == 0x2);
- CHECK(i->get_s2() == 0x0);
- CHECK(i->get_s3() == 0x1);
- CHECK(this->ct->get_gprs().at(2) == 0x200);
- CHECK(this->ct->get_gprs().at(6) == 0x1);
- CHECK(this->ct->get_gprs().at(7) == 0x1);
- CHECK(this->ct->get_gprs().at(8) == 0x2);
- CHECK(this->ct->get_gprs().at(9) == 0x200);
- CHECK(i->get_mnemonic() == LOAD);
- CHECK(i->get_instr_bits() == b10);
- CHECK(this->ct->checked_out.front() == 0x7);
-
- delete i;
- i = this->ct->advance(WAIT);
- REQUIRE(i == nullptr);
- i = this->ct->advance(WAIT);
- REQUIRE(i == nullptr);
- i = this->ct->advance(WAIT);
- REQUIRE(i != nullptr);
-
- CHECK(i->get_s1() == 0x3);
- CHECK(i->get_s2() == 0x2);
- CHECK(i->get_s3() == 0x1);
- CHECK(this->ct->get_gprs().at(2) == 0x200);
- CHECK(this->ct->get_gprs().at(6) == 0x1);
- CHECK(this->ct->get_gprs().at(7) == 0x3);
- CHECK(this->ct->get_gprs().at(8) == 0x2);
- CHECK(this->ct->get_gprs().at(9) == 0x200);
- CHECK(i->get_mnemonic() == ADD);
- CHECK(i->get_instr_bits() == b11);
-
- delete i;
- i = this->ct->advance(WAIT);
- REQUIRE(i == nullptr);
- i = this->ct->advance(WAIT);
- REQUIRE(i == nullptr);
- i = this->ct->advance(WAIT);
- REQUIRE(i != nullptr);
-
- CHECK(i->get_s1() == 0x200);
- CHECK(i->get_s2() == 0x3);
- CHECK(i->get_s3() == 0x0);
- CHECK(this->ct->get_gprs().at(2) == 0x200);
- CHECK(this->ct->get_gprs().at(6) == 0x1);
- CHECK(this->ct->get_gprs().at(7) == 0x3);
- CHECK(this->ct->get_gprs().at(8) == 0x2);
- CHECK(this->ct->get_gprs().at(9) == 0x200);
- CHECK(i->get_mnemonic() == STORE);
- CHECK(i->get_instr_bits() == b12);
-
- delete i;
-}
diff --git a/tests/id.cc b/tests/id.cc
index 06eec0c..321c013 100644
--- a/tests/id.cc
+++ b/tests/id.cc
@@ -102,7 +102,7 @@ TEST_CASE_METHOD(IDFixture, "Parse arbitrary r-type # one", "[id]")
signed int t;
InstrDTO *i;
- t = this->encode_R_type(0b0, 0b1, 0b10, 0b11, 0b0);
+ t = this->encode_R_type(0b101, 0b110, 0b111, 0b11, 0b0);
i = this->decode_bits(t);
CHECK(i->get_s1() == 0x00000000); // registers are empty
@@ -134,7 +134,7 @@ TEST_CASE_METHOD(IDFixture, "Parse arbitrary i-type # one", "[id]")
signed int t;
InstrDTO *i;
- t = this->encode_I_type(0xF, 0b1, 0b10, 0b0111, 0b1);
+ t = this->encode_I_type(0xF, 0b101, 0b110, 0b0111, 0b1);
i = this->decode_bits(t);
CHECK(i->get_s1() == 0x00000000); // registers are empty
@@ -150,7 +150,7 @@ TEST_CASE_METHOD(IDFixture, "Parse arbitrary i-type # two", "[id]")
signed int t;
InstrDTO *i;
- t = this->encode_I_type(0xCC, 0b010, 0b101, 0b1011, 0b1);
+ t = this->encode_I_type(0xCC, 0b101, 0b110, 0b1011, 0b1);
i = this->decode_bits(t);
CHECK(i->get_s1() == 0x00000000); // registers are empty
@@ -184,8 +184,9 @@ TEST_CASE_METHOD(IDFixture, "Parse arbitrary j-type # two", "[id]")
t = this->encode_J_type(0xBBCCF, 0b10101, 0b0011, 0b10);
i = this->decode_bits(t);
+ t = 0xFFFBBCCF;
CHECK(i->get_s1() == 0x00000000); // registers are empty
- CHECK(i->get_s2() == 0xFFFBBCCF);
+ CHECK(i->get_s2() == t);
CHECK(i->get_mnemonic() == JAL);
delete i;
@@ -205,72 +206,3 @@ TEST_CASE_METHOD(IDFixture, "read does not conflict with read", "[id]")
this->d->read_guard(v);
REQUIRE(v == 0b0);
}
-
-TEST_CASE_METHOD(IDFixture, "write does not conflict with write", "[id]")
-{
- signed int v;
-
- v = 0b1;
- this->d->write_guard(v);
- REQUIRE(v == 0b0);
-
- v = 0b1;
- this->d->write_guard(v);
- REQUIRE(v == 0b0);
-}
-
-TEST_CASE_METHOD(IDFixture, "write does not conflict with read", "[id]")
-{
- signed int v;
- Response r;
-
- v = 0b1;
- r = this->d->read_guard(v);
- CHECK(v == 0b0);
- REQUIRE(r == OK);
-
- v = 0b1;
- this->d->write_guard(v);
- REQUIRE(v == 0b0);
-}
-
-TEST_CASE_METHOD(IDFixture, "read does conflict with write", "[id]")
-{
- signed int v;
- Response r;
-
- v = 0b1;
- this->d->write_guard(v);
- REQUIRE(v == 0b0);
-
- v = 0b1;
- r = this->d->read_guard(v);
- CHECK(v == 0b01);
- REQUIRE(r == STALLED);
-}
-
-TEST_CASE_METHOD(IDFixture, "stores indefinite conflicts", "[id]")
-{
- signed int v, ov;
- Response r;
-
- v = 0b1;
- ov = v;
- while (v < 0b110) {
- this->d->write_guard(v);
- REQUIRE(v == 0b0);
- v = ++ov;
- }
- this->d->write_guard(v);
- REQUIRE(v == 0b0);
-
- v = 0b110;
- r = this->d->read_guard(v);
- CHECK(v == 0b110);
- REQUIRE(r == STALLED);
-
- v = 0b1;
- r = this->d->read_guard(v);
- CHECK(v == 0b1);
- REQUIRE(r == STALLED);
-}
diff --git a/tests/if.cc b/tests/if.cc
index 01070ef..8b30d0e 100644
--- a/tests/if.cc
+++ b/tests/if.cc
@@ -73,9 +73,7 @@ class IFFixture
TEST_CASE_METHOD(IFFixture, "fetch returns single instuction", "[if_pipe]")
{
InstrDTO *i;
- int expected_cycles;
- expected_cycles = this->m_delay + this->c_delay + 2;
i = this->fetch_through();
REQUIRE(i->get_instr_bits() == this->p[0]);