diff options
author | Siddarth Suresh <155843085+SiddarthSuresh98@users.noreply.github.com> | 2025-03-29 22:14:42 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-29 22:14:42 -0400 |
commit | d20623d031cf909d8892c2db38cf2e2e02bc6a9b (patch) | |
tree | 56ef4ae4325a5b803c484a3e5c8d87b89572cedf /tests | |
parent | caeff52f029920e027d18bc01149425560801f82 (diff) | |
parent | 1250c3765f59801d060152d5f6eed0a9faa11b50 (diff) |
Merge pull request #37 from bdunahu/bdunahu
Instr, InstrDTO gets/sets, other structures required for decode
-- tests as we move forward
-- base classes
-- decode stage implemented
Diffstat (limited to 'tests')
-rw-r--r-- | tests/id.cc | 251 | ||||
-rw-r--r-- | tests/if.cc | 46 | ||||
-rw-r--r-- | tests/utils.cc | 8 |
3 files changed, 293 insertions, 12 deletions
diff --git a/tests/id.cc b/tests/id.cc new file mode 100644 index 0000000..d9c1701 --- /dev/null +++ b/tests/id.cc @@ -0,0 +1,251 @@ +#include "id.h" +#include "cache.h" +#include "controller.h" +#include "dram.h" +#include "if.h" +#include "instr.h" +#include "instrDTO.h" +#include <catch2/catch_test_macros.hpp> + +class IDFixture +{ + public: + IDFixture() + { + Dram *dr; + + dr = new Dram(3); + this->c = new Cache(dr, 1); + IF *f = new IF(nullptr); + this->d = new ID(f); + this->ct = new Controller(this->d, this->c, true); + }; + ~IDFixture() + { + delete this->ct; + delete this->c; + }; + signed int encode_R_type( + signed int s3, + signed int s2, + signed int s1, + signed int opcode, + signed int type) + { + signed int t; + t = s3; + t = (t << REG_SIZE) + s2; + t = (t << REG_SIZE) + s1; + t = (t << R_OPCODE_SIZE) + opcode; + t = (t << TYPE_SIZE) + type; + return t; + } + signed int encode_I_type( + signed int s3, + signed int s2, + signed int s1, + signed int opcode, + signed int type) + { + signed int t; + t = s3; + t = (t << REG_SIZE) + s2; + t = (t << REG_SIZE) + s1; + t = (t << OPCODE_SIZE) + opcode; + t = (t << TYPE_SIZE) + type; + return t; + } + signed int encode_J_type( + signed int s2, signed int s1, signed int opcode, signed int type) + { + signed int t; + t = s2; + t = (t << REG_SIZE) + s1; + t = (t << OPCODE_SIZE) + opcode; + t = (t << TYPE_SIZE) + type; + return t; + } + Cache *c; + ID *d; + Controller *ct; +}; + +TEST_CASE_METHOD(IDFixture, "Parse invalid type", "[id]") +{ + signed int s1 = 0, s2 = 0, s3 = 0; + Mnemonic m; + + s1 = 0xFFFFFFFF; + this->d->get_instr_fields(s1, s2, s3, m); + CHECK(m == NOP); +} + +TEST_CASE_METHOD(IDFixture, "Parse arbitrary r-type # one", "[id]") +{ + signed int s1 = -1, s2 = -1, s3 = -1; + Mnemonic m; + + s1 = this->encode_R_type(0b0, 0b1, 0b10, 0b11, 0b0); + this->d->get_instr_fields(s1, s2, s3, m); + + CHECK(s1 == 0x00000000); // registers are empty + CHECK(s2 == 0x00000000); + CHECK(s3 == 0x00000000); + CHECK(m == MUL); +} + +TEST_CASE_METHOD(IDFixture, "Parse arbitrary r-type # two", "[id]") +{ + signed int s1 = -1, s2 = -1, s3 = -1; + Mnemonic m; + + s1 = this->encode_R_type(0b10000, 0b01000, 0b00100, 0b10, 0b0); + this->d->get_instr_fields(s1, s2, s3, m); + + CHECK(s1 == 0x00000000); // registers are empty + CHECK(s2 == 0b00000000); + CHECK(s3 == 0b00000000); + CHECK(m == SUB); +} + +TEST_CASE_METHOD(IDFixture, "Parse arbitrary i-type # one", "[id]") +{ + signed int s1 = -1, s2 = -1, s3 = -1; + Mnemonic m; + + s1 = this->encode_I_type(0xF, 0b1, 0b10, 0b0111, 0b1); + this->d->get_instr_fields(s1, s2, s3, m); + + CHECK(s1 == 0x00000000); // registers are empty + CHECK(s2 == 0x00000000); + CHECK(s3 == 0xF); + CHECK(m == SFTLI); +} + +TEST_CASE_METHOD(IDFixture, "Parse arbitrary i-type # two", "[id]") +{ + signed int s1 = -1, s2 = -1, s3 = -1; + Mnemonic m; + + s1 = this->encode_I_type(0xCC, 0b010, 0b101, 0b1011, 0b1); + this->d->get_instr_fields(s1, s2, s3, m); + + CHECK(s1 == 0x00000000); // registers are empty + CHECK(s2 == 0x00000000); + CHECK(s3 == 0xCC); + CHECK(m == STORE); +} + +TEST_CASE_METHOD(IDFixture, "Parse arbitrary j-type # one", "[id]") +{ + signed int s1 = -1, s2 = -1, s3 = -1; + Mnemonic m; + + s1 = this->encode_J_type(0x3456, 0b10101, 0b0111, 0b10); + this->d->get_instr_fields(s1, s2, s3, m); + + CHECK(s1 == 0x00000000); // registers are empty + CHECK(s2 == 0x3456); + CHECK(m == BOF); + // behavior does nothing + CHECK(s3 == -1); +} + +TEST_CASE_METHOD(IDFixture, "Parse arbitrary j-type # two", "[id]") +{ + signed int s1 = -1, s2 = -1, s3 = -1; + Mnemonic m; + + s1 = this->encode_J_type(0xBBCCF, 0b10101, 0b0011, 0b10); + this->d->get_instr_fields(s1, s2, s3, m); + + CHECK(s1 == 0x00000000); // registers are empty + CHECK(s2 == 0xBBCCF); + CHECK(m == JAL); + // behavior does nothing + CHECK(s3 == -1); +} + +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 == BLOCKED); +} + +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 == BLOCKED); + + v = 0b0; + r = this->d->read_guard(v); + CHECK(v == 0b0); + REQUIRE(r == BLOCKED); +} diff --git a/tests/if.cc b/tests/if.cc index 5c1b645..bb25afa 100644 --- a/tests/if.cc +++ b/tests/if.cc @@ -36,9 +36,9 @@ class IFPipeFixture Response r; for (i = 0; i < this->m_delay + 1; ++i) { - r = this->ct->advance(instr); + r = this->ct->advance(instr, OK); // check response - CHECK(r == BLOCKED); + CHECK(r == STALLED); } this->fetch_cache(instr); } @@ -52,11 +52,11 @@ class IFPipeFixture Response r; for (i = 0; i < this->c_delay; ++i) { - r = this->ct->advance(instr); + r = this->ct->advance(instr, OK); // check response - CHECK(r == WAIT); + CHECK(r == STALLED); } - r = this->ct->advance(instr); + r = this->ct->advance(instr, OK); // check response CHECK(r == OK); } @@ -77,7 +77,7 @@ TEST_CASE_METHOD(IFPipeFixture, "fetch returns single instuction", "[if_pipe]") expected_cycles = this->m_delay + this->c_delay + 2; this->fetch_through(instr); - CHECK(instr.get_if_cycle() == expected_cycles); + CHECK(instr.get_time_of(FETCH) == expected_cycles); REQUIRE(instr.get_instr_bits() == this->p[0]); } @@ -89,12 +89,42 @@ TEST_CASE_METHOD(IFPipeFixture, "fetch returns two instuctions", "[if_pipe]") expected_cycles = this->m_delay + this->c_delay + 2; this->fetch_through(instr); - CHECK(instr.get_if_cycle() == expected_cycles); + CHECK(instr.get_time_of(FETCH) == expected_cycles); REQUIRE(instr.get_instr_bits() == this->p[0]); expected_cycles += this->c_delay + 1; this->fetch_cache(instr); - CHECK(instr.get_if_cycle() == expected_cycles); + CHECK(instr.get_time_of(FETCH) == expected_cycles); REQUIRE(instr.get_instr_bits() == this->p[1]); } + +TEST_CASE_METHOD(IFPipeFixture, "fetch waits with old instruction", "[if_pipe]") +{ + Response r; + InstrDTO instr; + int i, expected_cycles, fetch_cycles; + + fetch_cycles = this->m_delay + this->c_delay + 2; + expected_cycles = this->m_delay + (this->c_delay * 2) + 1; + + for (i = 0; i < this->m_delay + 1; ++i) { + r = this->ct->advance(instr, BLOCKED); + // check response + CHECK(r == STALLED); + } + for (i = 0; i < this->c_delay; ++i) { + r = this->ct->advance(instr, BLOCKED); + // check response + CHECK(r == STALLED); + } + for (i = 0; i < expected_cycles - fetch_cycles; ++i) { + r = this->ct->advance(instr, BLOCKED); + // check response + CHECK(r == OK); + } + + r = this->ct->advance(instr, OK); + CHECK(instr.get_time_of(FETCH) == expected_cycles); + REQUIRE(instr.get_instr_bits() == this->p[0]); +} diff --git a/tests/utils.cc b/tests/utils.cc index ea1a1ed..2e0e934 100644 --- a/tests/utils.cc +++ b/tests/utils.cc @@ -2,21 +2,21 @@ #include "definitions.h" #include <catch2/catch_test_macros.hpp> -TEST_CASE("Parse arbitrary fields # one", "[cache]") +TEST_CASE("Parse arbitrary fields # one", "[utils]") { int tag, index, offset; int address = 0b0001010101; - get_bit_fields(address, &tag, &index, &offset); + get_cache_fields(address, &tag, &index, &offset); CHECK(tag == 0b000); CHECK(index == 0b10101); CHECK(offset == 0b01); } -TEST_CASE("Parse arbitrary fields # two", "[cache]") +TEST_CASE("Parse arbitrary fields # two", "[utils]") { int tag, index, offset; int address = 0b0100111011; - get_bit_fields(address, &tag, &index, &offset); + get_cache_fields(address, &tag, &index, &offset); CHECK(tag == 0b010); CHECK(index == 0b01110); CHECK(offset == 0b11); |