summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--inc/ex.h2
-rw-r--r--inc/id.h2
-rw-r--r--inc/instrDTO.h15
-rw-r--r--inc/stage.h10
-rw-r--r--src/sim/controller.cc1
-rw-r--r--src/sim/ex.cc53
-rw-r--r--src/sim/id.cc21
-rw-r--r--src/sim/if.cc1
-rw-r--r--src/sim/instrDTO.cc4
-rw-r--r--src/sim/mm.cc1
-rw-r--r--src/sim/stage.cc7
-rw-r--r--src/sim/wb.cc1
-rw-r--r--tests/controller.cc259
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<void(signed int &s1, signed int s2, signed int s3)>>
+ 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 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<signed int> 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<signed int> 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<signed int> 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;
}