diff options
-rw-r--r-- | gui/worker.cc | 84 | ||||
-rw-r--r-- | inc/controller.h | 6 | ||||
-rw-r--r-- | inc/ex.h | 19 | ||||
-rw-r--r-- | inc/id.h | 2 | ||||
-rw-r--r-- | inc/stage.h | 6 | ||||
-rw-r--r-- | src/sim/controller.cc | 16 | ||||
-rw-r--r-- | src/sim/ex.cc | 22 | ||||
-rw-r--r-- | src/sim/id.cc | 34 | ||||
-rw-r--r-- | src/sim/if.cc | 3 | ||||
-rw-r--r-- | src/sim/mm.cc | 11 | ||||
-rw-r--r-- | src/sim/stage.cc | 1 | ||||
-rw-r--r-- | src/sim/wb.cc | 8 | ||||
-rw-r--r-- | tests/controller.cc | 320 | ||||
-rw-r--r-- | tests/id.cc | 78 | ||||
-rw-r--r-- | tests/if.cc | 2 |
15 files changed, 163 insertions, 449 deletions
diff --git a/gui/worker.cc b/gui/worker.cc index 2b00620..df6ebd2 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, 256)); 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); } @@ -60,8 +84,8 @@ Worker::~Worker() delete this->c; } -void Worker::loadProgram(std::vector<signed int> p) { - this->d->load(p); +void Worker::loadProgram(std::vector<signed int> p) { + this->d->load(p); } void Worker::refreshDram() @@ -100,7 +124,7 @@ 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, 256)); emit register_storage(this->ct->get_gprs()); 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; }; @@ -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; }; @@ -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]); |