From 68324683cde10c636a4a602644f3e64d24b0e412 Mon Sep 17 00:00:00 2001 From: bd Date: Tue, 1 Apr 2025 20:36:31 -0400 Subject: Lots of fixes and tests --- inc/ex.h | 2 +- inc/id.h | 2 +- inc/instrDTO.h | 15 ++- inc/stage.h | 10 +- src/sim/controller.cc | 1 + src/sim/ex.cc | 53 +++++++++-- src/sim/id.cc | 21 +++- src/sim/if.cc | 1 + src/sim/instrDTO.cc | 4 + src/sim/mm.cc | 1 - src/sim/stage.cc | 7 +- src/sim/wb.cc | 1 + tests/controller.cc | 259 +++++++++++++++++++++++++++++++++++++++++++++----- 13 files changed, 331 insertions(+), 46 deletions(-) diff --git a/inc/ex.h b/inc/ex.h index 6d4254e..e4c9d2b 100644 --- a/inc/ex.h +++ b/inc/ex.h @@ -25,7 +25,7 @@ class EX : public Stage */ std::unordered_map< Mnemonic, - std::function> + std::function> instr_map; }; diff --git a/inc/id.h b/inc/id.h index ebbe290..6178ad2 100644 --- a/inc/id.h +++ b/inc/id.h @@ -66,7 +66,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); - void decode_I_type(signed int &s1, signed int &s2, signed int &s3); + 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); /** * Helper for `get_instr_fields`. diff --git a/inc/instrDTO.h b/inc/instrDTO.h index 8249122..b6dec06 100644 --- a/inc/instrDTO.h +++ b/inc/instrDTO.h @@ -47,6 +47,10 @@ class InstrDTO * @return the type of the instruction */ Type get_type(); + /** + * @return the program counter at the time this instruction was fetched + */ + unsigned int get_pc(); /** * @param set hist key @@ -72,11 +76,15 @@ class InstrDTO * @param the mnemonic of the instruction */ void set_mnemonic(Mnemonic); - + /** * @param the type of the instruction */ void set_type(Type); + /** + * @param the program counter at the time this instruction was fetched + */ + void set_pc(unsigned int pc); private: /** @@ -100,11 +108,14 @@ class InstrDTO * The mnemonic of the operation. */ Mnemonic mnemonic; - /** * Type of the instruction */ Type type; + /** + * The PC of the instruction + */ + unsigned int pc; }; #endif /* INSTRDTO_H_INCLUDED */ diff --git a/inc/stage.h b/inc/stage.h index 87ee9c1..20f0191 100644 --- a/inc/stage.h +++ b/inc/stage.h @@ -64,6 +64,11 @@ class Stage */ void squash(); + /** + * The set of registers currently checked out. + */ + static std::deque checked_out; + protected: /** * The function expected to do the majority of the work. @@ -120,11 +125,6 @@ class Stage * The current clock cycle. */ static int clock_cycle; - // TODO fix this comment after writeback stage - /** - * The set of registers currently checked out. - */ - static std::deque checked_out; /** * A pointer to the next stage in the pipeline. */ diff --git a/src/sim/controller.cc b/src/sim/controller.cc index 293ee73..0b5c4d0 100644 --- a/src/sim/controller.cc +++ b/src/sim/controller.cc @@ -34,6 +34,7 @@ InstrDTO *Controller::advance(Response p) InstrDTO *r; r = this->next->advance(p); ++this->clock_cycle; + return r; } diff --git a/src/sim/ex.cc b/src/sim/ex.cc index ec4c47f..98a2d19 100644 --- a/src/sim/ex.cc +++ b/src/sim/ex.cc @@ -9,7 +9,7 @@ // clang-format off #define INIT_INSTRUCTION(mnemonic, body) \ - {mnemonic, [this](signed int &s1, signed int s2, signed int s3) { \ + {mnemonic, [this](signed int &s1, signed int s2, signed int s3, unsigned int pc) { \ body; \ }} // clang-format on @@ -24,6 +24,7 @@ EX::EX(Stage *stage) : Stage(stage) ADD, { s1 = s1 + s2; + (void)pc; (void)s3; (void)this; }), @@ -32,6 +33,7 @@ EX::EX(Stage *stage) : Stage(stage) SUB, { s1 = s1 - s2; + (void)pc; (void)s3; (void)this; }), @@ -40,6 +42,7 @@ EX::EX(Stage *stage) : Stage(stage) MUL, { s1 = s1 * s2; + (void)pc; (void)s3; (void)this; }), @@ -48,6 +51,7 @@ EX::EX(Stage *stage) : Stage(stage) QUOT, { s1 = s1 / s2; + (void)pc; (void)s3; (void)this; }), @@ -56,6 +60,7 @@ EX::EX(Stage *stage) : Stage(stage) REM, { s1 = s1 % s2; + (void)pc; (void)s3; (void)this; }), @@ -64,6 +69,7 @@ EX::EX(Stage *stage) : Stage(stage) SFTR, { s1 = s1 >> s2; + (void)pc; (void)s3; (void)this; }), @@ -72,6 +78,7 @@ EX::EX(Stage *stage) : Stage(stage) SFTL, { s1 = s1 << s2; + (void)pc; (void)s3; (void)this; }), @@ -80,6 +87,7 @@ EX::EX(Stage *stage) : Stage(stage) AND, { s1 = s1 & s2; + (void)pc; (void)s3; (void)this; }), @@ -88,6 +96,7 @@ EX::EX(Stage *stage) : Stage(stage) OR, { s1 = s1 | s2; + (void)pc; (void)s3; (void)this; }), @@ -96,6 +105,7 @@ EX::EX(Stage *stage) : Stage(stage) NOT, { s1 = ~s1; + (void)pc; (void)s3; (void)s2; (void)this; @@ -105,6 +115,7 @@ EX::EX(Stage *stage) : Stage(stage) XOR, { s1 = s1 ^ s2; + (void)pc; (void)s3; (void)this; }), @@ -112,6 +123,7 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( ADDV, { + (void)pc; (void)s3; (void)s2; (void)s1; @@ -121,6 +133,7 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( SUBV, { + (void)pc; (void)s3; (void)s2; (void)s1; @@ -130,6 +143,7 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( MULV, { + (void)pc; (void)s3; (void)s2; (void)s1; @@ -139,6 +153,7 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( DIVV, { + (void)pc; (void)s3; (void)s2; (void)s1; @@ -148,16 +163,19 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( CMP, { + cout << "CMP: " << s1 << ":" << s2 << std::endl; (s1 > s2) ? this->set_condition(GT, true) : this->set_condition(GT, false); (s1 == s2) ? this->set_condition(EQ, true) : this->set_condition(EQ, false); + (void)pc; (void)s3; }), INIT_INSTRUCTION( CEV, { + (void)pc; (void)s3; (void)s2; (void)s1; @@ -169,6 +187,7 @@ EX::EX(Stage *stage) : Stage(stage) LOAD, { s1 = s1 + s3; + (void)pc; (void)s2; (void)this; }), @@ -176,6 +195,7 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( LOADV, { + (void)pc; (void)s3; (void)s2; (void)s1; @@ -185,8 +205,10 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( ADDI, { + std::cout << this->id << ": " << s1 << "," << s2 << "," << s3 + << std::endl; s1 = s1 + s3; - std::cout << "= " << s2 << std::endl; + (void)pc; (void)s2; (void)this; }), @@ -195,6 +217,7 @@ EX::EX(Stage *stage) : Stage(stage) SUBI, { s1 = s1 - s3; + (void)pc; (void)s2; (void)this; }), @@ -203,6 +226,7 @@ EX::EX(Stage *stage) : Stage(stage) SFTRI, { s1 = s1 >> s3; + (void)pc; (void)s2; (void)this; }), @@ -211,6 +235,7 @@ EX::EX(Stage *stage) : Stage(stage) SFTLI, { s1 = s1 << s3; + (void)pc; (void)s2; (void)this; }), @@ -219,6 +244,7 @@ EX::EX(Stage *stage) : Stage(stage) ANDI, { s1 = s1 & s3; + (void)pc; (void)s2; (void)this; }), @@ -227,6 +253,7 @@ EX::EX(Stage *stage) : Stage(stage) ORI, { s1 = s1 | s3; + (void)pc; (void)s2; (void)this; }), @@ -235,6 +262,7 @@ EX::EX(Stage *stage) : Stage(stage) XORI, { s1 = s1 ^ s3; + (void)pc; (void)s2; (void)this; }), @@ -243,6 +271,7 @@ EX::EX(Stage *stage) : Stage(stage) STORE, { s1 = s1 + s3; + (void)pc; (void)s2; (void)this; }), @@ -250,6 +279,7 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( STOREV, { + (void)pc; (void)s3; (void)s2; (void)s1; @@ -261,6 +291,7 @@ EX::EX(Stage *stage) : Stage(stage) JMP, { s1 = s1 + s2; + (void)pc; (void)s3; (void)this; }), @@ -268,7 +299,7 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( JRL, { - s1 = this->pc + s2; + s1 = pc + s2; (void)s3; (void)this; }), @@ -277,6 +308,7 @@ EX::EX(Stage *stage) : Stage(stage) JAL, { s1 = s1 + s2; + (void)pc; (void)s3; (void)this; }), @@ -284,7 +316,7 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( BEQ, { - (this->get_condition(EQ)) ? s1 = wrap_address(this->pc + s2) + (this->get_condition(EQ)) ? s1 = wrap_address(pc + s2) : s1 = -1; (void)s3; }), @@ -292,7 +324,7 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( BGT, { - (this->get_condition(GT)) ? s1 = wrap_address(this->pc + s2) + (this->get_condition(GT)) ? s1 = wrap_address(pc + s2) : s1 = -1; (void)s3; }), @@ -300,7 +332,7 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( BUF, { - (this->get_condition(UF)) ? s1 = wrap_address(this->pc) + s2 + (this->get_condition(UF)) ? s1 = wrap_address(pc + s2) : s1 = -1; (void)s3; }), @@ -308,7 +340,7 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( BOF, { - (this->get_condition(OF)) ? s1 = wrap_address(this->pc + s2) + (this->get_condition(OF)) ? s1 = wrap_address(pc + s2) : s1 = -1; (void)s3; }), @@ -316,6 +348,7 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( PUSH, { + (void)pc; (void)s3; (void)s2; (void)s1; @@ -325,6 +358,7 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( POP, { + (void)pc; (void)s3; (void)s2; (void)s1; @@ -335,6 +369,7 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( NOP, { + (void)pc; (void)s3; (void)s2; (void)s1; @@ -346,14 +381,16 @@ EX::EX(Stage *stage) : Stage(stage) void EX::advance_helper() { signed int s1, s2, s3; + unsigned int pc; Mnemonic m; m = this->curr_instr->get_mnemonic(); s1 = this->curr_instr->get_s1(); s2 = this->curr_instr->get_s2(); s3 = this->curr_instr->get_s3(); + pc = this->curr_instr->get_pc(); - this->instr_map[m](s1, s2, s3); + this->instr_map[m](s1, s2, s3, pc ); this->curr_instr->set_s1(s1); this->status = OK; diff --git a/src/sim/id.cc b/src/sim/id.cc index ddac35b..805a4df 100644 --- a/src/sim/id.cc +++ b/src/sim/id.cc @@ -51,6 +51,9 @@ void ID::advance_helper() if (curr_instr->get_mnemonic() == NOP) this->status = OK; else { + std::cout << this->id << ": " << this->curr_instr->get_s1() << "," + << this->curr_instr->get_s2() << "," + << this->curr_instr->get_s3() << std::endl; s1 = curr_instr->get_instr_bits(); get_instr_fields(s1, s2, s3, m, t); if (this->status == OK) { @@ -60,6 +63,9 @@ void ID::advance_helper() curr_instr->set_mnemonic(m); curr_instr->set_type(t); } + std::cout << this->id << ": " << this->curr_instr->get_s1() << "," + << this->curr_instr->get_s2() << "," + << this->curr_instr->get_s3() << std::endl; } } @@ -76,7 +82,7 @@ void ID::get_instr_fields( break; case 0b01: t = I; - this->decode_I_type(s1, s2, s3); + this->decode_I_type(s1, s2, s3, m); break; case 0b10: t = J; @@ -107,9 +113,11 @@ void ID::decode_R_type(signed int &s1, signed int &s2, signed int &s3) this->status = (r1 == OK && r2 == OK) ? OK : STALLED; } -void ID::decode_I_type(signed int &s1, signed int &s2, signed int &s3) +void ID::decode_I_type( + signed int &s1, signed int &s2, signed int &s3, Mnemonic &m) { unsigned int s0b, s1b, s2b; + Response r1; s0b = REG_SIZE; s1b = s0b + REG_SIZE; @@ -118,8 +126,13 @@ void ID::decode_I_type(signed int &s1, signed int &s2, signed int &s3) s2 = GET_MID_BITS(s1, s0b, s1b); s1 = GET_LS_BITS(s1, s0b); - this->status = this->read_guard(s1); - this->write_guard(s2); + std::cout << m << ":" << s2 << std::endl; + r1 = this->read_guard(s1); + if (m != STORE && m != STOREV) { + this->status = r1; + this->write_guard(s2); + } else + this->status = (this->read_guard(s2) == OK && r1 == OK) ? OK : STALLED; } void ID::decode_J_type(signed int &s1, signed int &s2) diff --git a/src/sim/if.cc b/src/sim/if.cc index bc40688..85fb27f 100644 --- a/src/sim/if.cc +++ b/src/sim/if.cc @@ -33,6 +33,7 @@ void IF::advance_helper() if (r == OK) { this->curr_instr = new InstrDTO(); this->curr_instr->set_instr_bits(bits); + this->curr_instr->set_pc(this->pc); } } } diff --git a/src/sim/instrDTO.cc b/src/sim/instrDTO.cc index 7324ba9..d36e957 100644 --- a/src/sim/instrDTO.cc +++ b/src/sim/instrDTO.cc @@ -25,6 +25,8 @@ Mnemonic InstrDTO::get_mnemonic() { return this->mnemonic; } Type InstrDTO::get_type() { return this->type; } +unsigned int InstrDTO::get_pc() { return this->pc; } + void InstrDTO::set_time_of(Accessor a, int i) { this->hist[a] = i; } void InstrDTO::set_instr_bits(signed int instr) { this->instr_bits = instr; } @@ -38,3 +40,5 @@ void InstrDTO::set_s3(signed int s) { this->s3 = s; } void InstrDTO::set_mnemonic(Mnemonic m) { this->mnemonic = m; } void InstrDTO::set_type(Type t) { this->type = t; } + +void InstrDTO::set_pc(unsigned int pc) { this->pc = pc; } diff --git a/src/sim/mm.cc b/src/sim/mm.cc index e29bf90..c83ae7d 100644 --- a/src/sim/mm.cc +++ b/src/sim/mm.cc @@ -10,7 +10,6 @@ void MM::advance_helper() { signed int data; - std::cout << "mem" << this->curr_instr->get_s2() << std::endl; switch (this->curr_instr->get_mnemonic()) { case LOAD: this->status = this->storage->read_word( diff --git a/src/sim/stage.cc b/src/sim/stage.cc index b10a206..bd0ff6b 100644 --- a/src/sim/stage.cc +++ b/src/sim/stage.cc @@ -95,8 +95,11 @@ bool Stage::is_checked_out(signed int r) void Stage::squash() { - this->curr_instr->set_mnemonic(NOP); - this->status = OK; + if (curr_instr) { + std::cout << "!!!" << std::endl; + this->curr_instr->set_mnemonic(NOP); + this->status = OK; + } if (this->next) { this->next->squash(); } diff --git a/src/sim/wb.cc b/src/sim/wb.cc index 01768e8..50acd05 100644 --- a/src/sim/wb.cc +++ b/src/sim/wb.cc @@ -28,6 +28,7 @@ void WB::write_handler() reg = this->checked_out.front(); this->checked_out.pop_front(); + std::cout << "storing " << reg << " with " << this->curr_instr->get_s1() << std::endl; this->store_register(reg, this->curr_instr->get_s1()); } diff --git a/tests/controller.cc b/tests/controller.cc index f2ef3de..c36eba6 100644 --- a/tests/controller.cc +++ b/tests/controller.cc @@ -65,25 +65,42 @@ TEST_CASE_METHOD( TEST_CASE_METHOD(ControllerPipeFixture, "two num adder", "[full pipe]") { - signed int b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11; + signed int b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, + b15; std::vector p; InstrDTO *i; // I-TYPE / / / / - b0 = 0b00000010000000000001000000001101; // ADDI $sp $0 0x200; + b0 = 0b00000010000000000001000000001101; // ADDI $2 $0 0x200; b1 = 0b00000000000000010010100000001101; // ADDI $5 $0 0x1; - b2 = 0b00000000000000000001000101101101; // STORE $5 0($sp); (RAW HAZARD)! + b2 = 0b00000000000000000010100010101101; // STORE $5 0($2); (RAW HAZARD w + // 1)! // I-TYPE / / / / b3 = 0b00000000000000100010100000001101; // ADDI $5 $0 0x2; (RAW HAZARD)! - b4 = 0b00000000000000010001000101101101; // STORE $5 1($sp); (RAW HAZARD)! - // // I-TYPE / / / / - // b9 = 0b00000000000000000010100000001101; // ADDI $5 $0 0x0; - // // I-TYPE / / / / - // b10 = 0b00000000000000110011000000001101; // ADDI $6 $0 0x3; - // // J-TYPE / / / - // b11 = 0b00000000000000000011100000001010; // jrl CHECK - - p = {b0, b1, b2, b3}; + 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(); @@ -101,6 +118,7 @@ TEST_CASE_METHOD(ControllerPipeFixture, "two num adder", "[full pipe]") 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); @@ -128,21 +146,28 @@ TEST_CASE_METHOD(ControllerPipeFixture, "two num adder", "[full pipe]") 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_time_of(FETCH) == 5); - CHECK(i->get_time_of(DCDE) == 8); // the previous conflicting instruction wrote here! + CHECK( + i->get_time_of(DCDE) == + 8); // the previous conflicting instruction wrote here! CHECK(i->get_time_of(EXEC) == 9); - CHECK(i->get_time_of(MEM) == 12); // waited for fetch + 2 dram - CHECK(i->get_time_of(WRITE) == 13); - CHECK(i->get_s1() == 0x1); - CHECK(i->get_s2() == 0x200); + CHECK(i->get_time_of(MEM) == 14); // waited for fetch + 3 dram + CHECK(i->get_time_of(WRITE) == 15); + 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); @@ -150,16 +175,206 @@ TEST_CASE_METHOD(ControllerPipeFixture, "two num adder", "[full pipe]") CHECK(i->get_time_of(FETCH) == 8); CHECK(i->get_time_of(DCDE) == 9); - CHECK(i->get_time_of(EXEC) == 12); - CHECK(i->get_time_of(MEM) == 13); - CHECK(i->get_time_of(WRITE) == 14); + CHECK(i->get_time_of(EXEC) == 14); + CHECK(i->get_time_of(MEM) == 15); + CHECK(i->get_time_of(WRITE) == 16); CHECK(i->get_s1() == 0x2); - CHECK(i->get_s2() == 0x0); + CHECK(i->get_s2() == 0x1); // the previous value in the destination register CHECK(i->get_s3() == 0x2); - // NO STORE + 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_time_of(FETCH) == 14); // fetching new line + mem + CHECK( + i->get_time_of(DCDE) == + 16); // the previous conflicting instruction wrote here! + CHECK(i->get_time_of(EXEC) == 17); + CHECK(i->get_time_of(MEM) == 18); + CHECK(i->get_time_of(WRITE) == 19); + 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_time_of(FETCH) == 16); + CHECK(i->get_time_of(DCDE) == 17); + CHECK(i->get_time_of(EXEC) == 18); + CHECK(i->get_time_of(MEM) == 19); + CHECK(i->get_time_of(WRITE) == 20); + 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_time_of(FETCH) == 17); + CHECK(i->get_time_of(DCDE) == 18); + CHECK(i->get_time_of(EXEC) == 19); + CHECK(i->get_time_of(MEM) == 20); + CHECK(i->get_time_of(WRITE) == 21); + 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_time_of(FETCH) == 18); + CHECK(i->get_time_of(DCDE) == 19); + CHECK(i->get_time_of(EXEC) == 20); + CHECK(i->get_time_of(MEM) == 21); + CHECK(i->get_time_of(WRITE) == 22); + CHECK(i->get_s1() == 0xE); + CHECK(i->get_s2() == 0x7); + CHECK(i->get_s3() == 0x0); // doesn't exist + 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_time_of(FETCH) == + 24); // 6 greater than last fetch (4 flush pipe, 2 dram) + CHECK(i->get_time_of(DCDE) == 25); + CHECK(i->get_time_of(EXEC) == 26); + CHECK(i->get_time_of(MEM) == 27); + CHECK(i->get_time_of(WRITE) == 28); + 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_time_of(FETCH) == 25); + CHECK(i->get_time_of(DCDE) == 26); + CHECK(i->get_time_of(EXEC) == 27); + CHECK(i->get_time_of(MEM) == 28); + CHECK(i->get_time_of(WRITE) == 29); + CHECK(i->get_s1() == 0x8); + CHECK(i->get_s2() == 0b111111111111111111001); + 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_time_of(FETCH) == 29); // clear out pipe (4) + CHECK(i->get_time_of(DCDE) == 30); + CHECK(i->get_time_of(EXEC) == 31); + CHECK(i->get_time_of(MEM) == 32); + CHECK(i->get_time_of(WRITE) == 33); + 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); + + 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_time_of(FETCH) == 30); + CHECK(i->get_time_of(DCDE) == 33); + CHECK(i->get_time_of(EXEC) == 34); + CHECK(i->get_time_of(MEM) == 35); + CHECK(i->get_time_of(WRITE) == 36); + CHECK(i->get_s1() == 0x0); + CHECK(i->get_s2() == 0x200); + 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); + + delete i; } -- cgit v1.2.3