diff options
author | bd <bdunahu@operationnull.com> | 2025-04-01 15:57:14 -0400 |
---|---|---|
committer | bd <bdunahu@operationnull.com> | 2025-04-01 15:57:14 -0400 |
commit | 25ce77db5f0dbfe6064eb0553591f1b956bad24a (patch) | |
tree | 5a1c347f05f14496d2d3a2f1befd88be9020cad3 /tests | |
parent | 6579f7272905d1e25b43ef051da6c2180e60ca2b (diff) |
Fix a lot of pipeline bugs
Diffstat (limited to 'tests')
-rw-r--r-- | tests/controller.cc | 111 | ||||
-rw-r--r-- | tests/id.cc | 320 |
2 files changed, 253 insertions, 178 deletions
diff --git a/tests/controller.cc b/tests/controller.cc index f6d9b25..f2ef3de 100644 --- a/tests/controller.cc +++ b/tests/controller.cc @@ -21,15 +21,27 @@ class ControllerPipeFixture IF *f = new IF(nullptr); ID *d = new ID(f); EX *e = new EX(d); + MM *m = new MM(e); + WB *w = new WB(m); + this->stage_num = 5; - this->ct = new Controller(e, this->c, true); + this->ct = new Controller(w, this->c, true); } ~ControllerPipeFixture() { delete this->ct; delete this->c; }; - + void fill_pipe() + { + InstrDTO *i = nullptr; + int j; + for (j = 0; j < this->stage_num + 1; ++j) { + i = this->ct->advance(WAIT); + REQUIRE(i == nullptr); + } + } + int stage_num; Cache *c; Dram *d; Controller *ct; @@ -51,40 +63,103 @@ TEST_CASE_METHOD( CHECK(this->ct->get_pc() == 0); } -TEST_CASE_METHOD(ControllerPipeFixture, "Add until exec", "[tmp]") +TEST_CASE_METHOD(ControllerPipeFixture, "two num adder", "[full pipe]") { - signed int b; + signed int b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11; std::vector<signed int> p; InstrDTO *i; - b = 0b1010100000000001001101; - p = {b}; + // I-TYPE / / / / + b0 = 0b00000010000000000001000000001101; // ADDI $sp $0 0x200; + b1 = 0b00000000000000010010100000001101; // ADDI $5 $0 0x1; + b2 = 0b00000000000000000001000101101101; // STORE $5 0($sp); (RAW HAZARD)! + // 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}; this->d->load(p); - // dram + this->fill_pipe(); + i = this->ct->advance(WAIT); + REQUIRE(i != nullptr); + + CHECK(i->get_time_of(FETCH) == 3); + CHECK(i->get_time_of(DCDE) == 4); + CHECK(i->get_time_of(EXEC) == 5); + CHECK(i->get_time_of(MEM) == 6); + CHECK(i->get_time_of(WRITE) == 7); + 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); + + delete i; + i = this->ct->advance(WAIT); + REQUIRE(i != nullptr); + + CHECK(i->get_time_of(FETCH) == 4); + CHECK(i->get_time_of(DCDE) == 5); + CHECK(i->get_time_of(EXEC) == 6); + CHECK(i->get_time_of(MEM) == 7); + CHECK(i->get_time_of(WRITE) == 8); + 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); - // fetch i = this->ct->advance(WAIT); REQUIRE(i == nullptr); - // decode i = this->ct->advance(WAIT); REQUIRE(i == nullptr); - // exec i = this->ct->advance(WAIT); REQUIRE(i == nullptr); - // done i = this->ct->advance(WAIT); REQUIRE(i != nullptr); - CHECK(i->get_time_of(FETCH) == 3); - CHECK(i->get_time_of(DCDE) == 4); - CHECK(i->get_time_of(EXEC) == 5); - CHECK(i->get_s1() == 42); - CHECK(i->get_s2() == 0); - CHECK(i->get_s3() == 42); + 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(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_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); + + delete i; + i = this->ct->advance(WAIT); + REQUIRE(i != nullptr); + + 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_s1() == 0x2); + CHECK(i->get_s2() == 0x0); + CHECK(i->get_s3() == 0x2); + // NO STORE + CHECK(this->ct->get_gprs().at(5) == 0x2); CHECK(i->get_mnemonic() == ADDI); - CHECK(i->get_instr_bits() == b); + CHECK(i->get_instr_bits() == b3); delete i; } diff --git a/tests/id.cc b/tests/id.cc index 7d5e05d..77a7cd9 100644 --- a/tests/id.cc +++ b/tests/id.cc @@ -84,18 +84,18 @@ class IDFixture Controller *ct; }; -// TEST_CASE_METHOD(IDFixture, "Parse invalid type", "[id]") -// { -// signed int t; -// InstrDTO *i; +TEST_CASE_METHOD(IDFixture, "Parse invalid type", "[id]") +{ + signed int t; + InstrDTO *i; -// t = this->encode_R_type(0b0, 0b1, 0b10, 0b11, 0b11); -// i = this->decode_bits(t); + t = this->encode_R_type(0b0, 0b1, 0b10, 0b11, 0b11); + i = this->decode_bits(t); -// CHECK(i->get_mnemonic() == NOP); + CHECK(i->get_mnemonic() == NOP); -// delete i; -// } + delete i; +} TEST_CASE_METHOD(IDFixture, "Parse arbitrary r-type # one", "[id]") { @@ -113,164 +113,164 @@ TEST_CASE_METHOD(IDFixture, "Parse arbitrary r-type # one", "[id]") delete i; } -// TEST_CASE_METHOD(IDFixture, "Parse arbitrary r-type # two", "[id]") -// { -// signed int t; -// InstrDTO *i; +TEST_CASE_METHOD(IDFixture, "Parse arbitrary r-type # two", "[id]") +{ + signed int t; + InstrDTO *i; -// t = this->encode_R_type(0b10000, 0b01000, 0b00100, 0b10, 0b0); -// i = this->decode_bits(t); + t = this->encode_R_type(0b10000, 0b01000, 0b00100, 0b10, 0b0); + i = this->decode_bits(t); -// CHECK(i->get_s1() == 0x00000000); // registers are empty -// CHECK(i->get_s2() == 0x00000000); -// CHECK(i->get_s3() == 0x00000000); -// CHECK(i->get_mnemonic() == 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; -// } + delete i; +} -// TEST_CASE_METHOD(IDFixture, "Parse arbitrary i-type # one", "[id]") -// { -// signed int t; -// InstrDTO *i; +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); -// i = this->decode_bits(t); + t = this->encode_I_type(0xF, 0b1, 0b10, 0b0111, 0b1); + i = this->decode_bits(t); -// CHECK(i->get_s1() == 0x00000000); // registers are empty -// CHECK(i->get_s2() == 0x00000000); -// CHECK(i->get_s3() == 0xF); -// CHECK(i->get_mnemonic() == SFTLI); + 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; -// } + delete i; +} -// TEST_CASE_METHOD(IDFixture, "Parse arbitrary i-type # two", "[id]") -// { -// signed int t; -// InstrDTO *i; +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); -// i = this->decode_bits(t); + t = this->encode_I_type(0xCC, 0b010, 0b101, 0b1011, 0b1); + i = this->decode_bits(t); -// 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 t; -// InstrDTO *i; - -// t = this->encode_J_type(0x3456, 0b10101, 0b0111, 0b10); -// i = this->decode_bits(t); - -// 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 t; -// InstrDTO *i; - -// t = this->encode_J_type(0xBBCCF, 0b10101, 0b0011, 0b10); -// i = this->decode_bits(t); - -// CHECK(i->get_s1() == 0x00000000); // registers are empty -// CHECK(i->get_s2() == 0xBBCCF); -// CHECK(i->get_mnemonic() == JAL); - -// delete i; -// } - -// TEST_CASE_METHOD(IDFixture, "read 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->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 = 0b0; -// 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 = 0b0; -// r = this->d->read_guard(v); -// CHECK(v == 0b0); -// REQUIRE(r == STALLED); -// } + 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 t; + InstrDTO *i; + + t = this->encode_J_type(0x3456, 0b10101, 0b0111, 0b10); + i = this->decode_bits(t); + + 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 t; + InstrDTO *i; + + t = this->encode_J_type(0xBBCCF, 0b10101, 0b0011, 0b10); + i = this->decode_bits(t); + + CHECK(i->get_s1() == 0x00000000); // registers are empty + CHECK(i->get_s2() == 0xBBCCF); + CHECK(i->get_mnemonic() == JAL); + + delete i; +} + +TEST_CASE_METHOD(IDFixture, "read 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->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 = 0b0; + 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 = 0b0; + r = this->d->read_guard(v); + CHECK(v == 0b0); + REQUIRE(r == STALLED); +} |