summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiddarth Suresh <155843085+SiddarthSuresh98@users.noreply.github.com>2025-04-17 10:50:58 -0400
committerGitHub <noreply@github.com>2025-04-17 10:50:58 -0400
commit62b9e280d5d0222710e491dcd28fe26bea915dcd (patch)
treee1f68ac7a6e4dc481c19346e38ad20d113f13825
parentb778ccc3e7c2f2ac3c4892a87f5269f342fd895f (diff)
parent430986b4b1ee1013db070991ce289176f48fa8e8 (diff)
Merge pull request #52 from bdunahu/bdunahu
[WIP] Partial fixes for changes in DRAM/Cache, including uncovered bug
-rw-r--r--gui/worker.cc72
-rw-r--r--inc/id.h4
-rw-r--r--inc/instrDTO.h29
-rw-r--r--inc/pipe_spec.h17
m---------ram0
-rw-r--r--src/sim/dum.cc2
-rw-r--r--src/sim/ex.cc17
-rw-r--r--src/sim/id.cc72
-rw-r--r--src/sim/if.cc5
-rw-r--r--src/sim/instr.cc13
-rw-r--r--src/sim/instrDTO.cc12
-rw-r--r--src/sim/stage.cc27
-rw-r--r--src/sim/wb.cc16
-rw-r--r--tests/controller.cc85
-rw-r--r--tests/ex.cc2
-rw-r--r--tests/id.cc16
-rw-r--r--tests/if.cc6
17 files changed, 162 insertions, 233 deletions
diff --git a/gui/worker.cc b/gui/worker.cc
index e7c9876..9202b89 100644
--- a/gui/worker.cc
+++ b/gui/worker.cc
@@ -6,7 +6,7 @@ void Worker::doWork()
{
qDebug() << "Initializing...";
this->d = new Dram(0);
- this->c = new Cache(this->d, 0);
+ this->c = new Cache(this->d, 5, 0, 0);
this->if_stage = new IF(nullptr);
this->id_stage = new ID(if_stage);
this->ex_stage = new EX(id_stage);
@@ -16,55 +16,41 @@ void Worker::doWork()
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, 8));
+ emit cache_storage(this->c->view(0, 7));
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;
+ b15, b16, b17, b18, b19, b20;
std::vector<signed int> p;
// I-TYPE / / / /
- b0 = 0b00000010000000000001000000001101; // ADDI $2 $0 0x200;
- b1 = 0b00000000000000010010100000001101; // ADDI $5 $0 0x1;
- b2 = 0b00000000000000000010100010101101; // STORE $5 0($2);
- // I-TYPE / / / /
- b3 = 0b00000000000000100010100000001101; // ADDI $5 $0 0x2;
- b4 = 0b00000000000000010010100010101101; // STORE $5 1($2);
- // I-TYPE / / / /
- b5 = 0b00000000000000110010100000001101; // ADDI $5 $0 0x3;
- b6 = 0b00000000000000100010100010101101; // STORE $5 2($2);
- // I-TYPE / / / /
- b7 = 0b00000000000001000010100000001101; // ADDI $5 $0 0x4;
- b8 = 0b00000000000000110010100010101101; // STORE $5 3($2);
- // // I-TYPE / / / /
- b9 = 0b00000000000000000010100000001101; // ADDI $5 $0 0x0;
- // // I-TYPE / / / /
- b10 = 0b00000000000000110011000000001101; // ADDI $6 $0 0x3;
- // // J-TYPE / / /
- b11 = 0b00000000000000000011100000001010; // JRL CHECK
- // // R-TYPE / / / / /
- b12 = 0b00000000000100100101000100000100; // ADD $9 $2 $5;
- // // I-TYPE / / / /
- b13 = 0b00000000000000000011101001000101; // LOAD $7 0($9); (RAW HAZARD)!
- // // I-TYPE / / / /
- b14 = 0b00000000000000010100001001000101; // LOAD $8 1($9);
- // // R-TYPE / / / / /
- b15 = 0b00000000000011101000001110000100; // ADD $7 $7 $8;
- // I-TYPE / / / /
- b16 = 0b00000000000000000011101001101101; // STORE $7 0($9);
- b17 = 0b00000000000000010010100101001101; // ADDI $5 $5 0x1;
- // // R-TYPE / / / / /
- b18 = 0b00000000000111100101001101000000; // CMP $6 $5
- // // J-TYPE / / /
- b19 = 0b11111111111111111100000000010110; // bgt LOOP
+ 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 = {b0, b1, b2, b3, b4, b5, b6, b7, b8, b9,
- b10, b11, b12, b13, b14, b15, b16, b17, b18, b19};
+ p = {b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10,
+ b11, b12, b13, b14, b15, b16, b17, b18, b19};
this->d->load(p);
}
-
-
Worker::~Worker()
{
emit finished();
@@ -83,7 +69,7 @@ void Worker::refreshDram()
void Worker::refreshCache()
{
qDebug() << "Refreshing Dram";
- emit cache_storage(this->c->view(0, 8));
+ emit cache_storage(this->c->view(0, 7));
}
void Worker::refreshRegisters()
@@ -97,7 +83,7 @@ void Worker::runSteps(int steps)
qDebug() << "Running for steps: " << steps;
this->ct->run_for(steps);
emit dram_storage(this->d->view(0, 256));
- emit cache_storage(this->c->view(0, 8));
+ emit cache_storage(this->c->view(0, 7));
emit register_storage(this->ct->get_gprs());
emit clock_cycles(this->ct->get_clock_cycle(), this->ct->get_pc());
emit if_info(this->if_stage->stage_info());
@@ -112,7 +98,7 @@ void Worker::runStep()
qDebug() << "Running for 1 step ";
this->ct->advance(WAIT);
emit dram_storage(this->d->view(0, 256));
- emit cache_storage(this->c->view(0, 8));
+ emit cache_storage(this->c->view(0, 7));
emit register_storage(this->ct->get_gprs());
emit clock_cycles(this->ct->get_clock_cycle(), this->ct->get_pc());
emit if_info(this->if_stage->stage_info());
diff --git a/inc/id.h b/inc/id.h
index db22d7d..c1810ae 100644
--- a/inc/id.h
+++ b/inc/id.h
@@ -41,7 +41,6 @@ class ID : public Stage
std::vector<int> stage_info() override;
private:
- void advance_helper() override;
/**
* Helper for `get_instr_fields`
* Attempts to parse and dereference instruction arguments. Uses read and
@@ -52,6 +51,7 @@ class ID : public Stage
* @param the resulting second field.
* @param the resulting third field.
*/
+ void advance_helper() override;
/**
* Parse an instruction into a type, opcode, and fields. If the type is
* invalid, only the type field will be set.
@@ -67,7 +67,7 @@ class ID : public Stage
* @param the resulting mnemonic.
*/
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_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);
/**
diff --git a/inc/instrDTO.h b/inc/instrDTO.h
index b6dec06..755ab9f 100644
--- a/inc/instrDTO.h
+++ b/inc/instrDTO.h
@@ -15,19 +15,16 @@ class InstrDTO
InstrDTO();
~InstrDTO() = default;
- /**
- * @return hist entry for Accessor
- */
- int get_time_of(Accessor);
- /**
- * @return id_cycle
- */
int get_id_cycle();
/**
* @return instr_bits
*/
signed int get_instr_bits();
/**
+ * @return checked_out
+ */
+ signed int get_checked_out();
+ /**
* @return s1
*/
signed int get_s1();
@@ -53,14 +50,14 @@ class InstrDTO
unsigned int get_pc();
/**
- * @param set hist key
- */
- void set_time_of(Accessor, int);
- /**
* @param instr_bits
*/
void set_instr_bits(signed int);
/**
+ * @param checked_out
+ */
+ void set_checked_out(signed int);
+ /**
* @param s1
*/
void set_s1(signed int);
@@ -88,14 +85,16 @@ class InstrDTO
private:
/**
- * The clock cycle each stage finished an operation.
- */
- std::unordered_map<Accessor, int> hist;
- /**
* The raw bits encoding the instruction.
*/
signed int instr_bits;
/**
+ * The register, if any, this instruction has checked out. A checked out
+ * register cannot be checked out by another register. This prevents RAW
+ * conflicts.
+ */
+ signed int checked_out;
+ /**
* Slots in this instruction, for storing temporary registers, immediates,
* or other.
* Some instruction types may use these differently.
diff --git a/inc/pipe_spec.h b/inc/pipe_spec.h
index 772314e..d211b72 100644
--- a/inc/pipe_spec.h
+++ b/inc/pipe_spec.h
@@ -65,4 +65,21 @@
*/
#define GET_MID_BITS(k, m, n) GET_LS_BITS((k) >> (m), ((n) - (m)))
+/**
+ * Return the bits from integer K starting at N and ending at M using a bit
+ * mask, but sign-extends the result. This is required to parse immediates.
+ * @param the integer to be parsed
+ * @param the index of the starting bit to be parsed
+ * @param the index of the ending bit to be parsed
+ * @return a section of bits from K
+ */
+// clang-format off
+#define GET_BITS_SIGN_EXTEND(k, m, n) \
+ ({\
+ int _f = GET_MID_BITS(k, m, n); \
+ int _w = (n) - (m) - (1); \
+ _f = (_f & (1 << (_w - 1))) ? (_f | (-1 << _w)) : _f; \
+ })
+// clang-format on
+
#endif /* DEFINITIONS_H_INCLUDED */
diff --git a/ram b/ram
-Subproject be2bc108dc112ae7e21d4a77f7bcbfac88d6fcd
+Subproject a2381acb5489a735576a43f25053a7a5551a766
diff --git a/src/sim/dum.cc b/src/sim/dum.cc
index 76d4acd..ab4eaa4 100644
--- a/src/sim/dum.cc
+++ b/src/sim/dum.cc
@@ -3,7 +3,6 @@
#include "instrDTO.h"
#include "response.h"
#include "stage.h"
-#include "utils.h"
DUM::DUM(Stage *stage) : Stage(stage) { this->id = IDLE; }
@@ -12,7 +11,6 @@ InstrDTO *DUM::advance(Response p)
InstrDTO *r = nullptr;
if (this->curr_instr && p == WAIT) {
- this->curr_instr->set_time_of(this->id, this->clock_cycle);
r = new InstrDTO(*this->curr_instr);
delete this->curr_instr;
curr_instr = nullptr;
diff --git a/src/sim/ex.cc b/src/sim/ex.cc
index 50f00a8..d20d15f 100644
--- a/src/sim/ex.cc
+++ b/src/sim/ex.cc
@@ -1,10 +1,9 @@
#include "ex.h"
#include "accessor.h"
-#include "pipe_spec.h"
#include "instrDTO.h"
+#include "pipe_spec.h"
#include "response.h"
#include "stage.h"
-#include "utils.h"
#include <unordered_map>
// clang-format off
@@ -313,32 +312,28 @@ EX::EX(Stage *stage) : Stage(stage)
INIT_INSTRUCTION(
BEQ,
{
- (this->get_condition(EQ)) ? s1 = wrap_address(pc + s2)
- : s1 = -1;
+ (this->get_condition(EQ)) ? s1 = pc + s2 : s1 = -1;
(void)s3;
}),
INIT_INSTRUCTION(
BGT,
{
- (this->get_condition(GT)) ? s1 = wrap_address(pc + s2)
- : s1 = -1;
+ (this->get_condition(GT)) ? s1 = pc + s2 : s1 = -1;
(void)s3;
}),
INIT_INSTRUCTION(
BUF,
{
- (this->get_condition(UF)) ? s1 = wrap_address(pc + s2)
- : s1 = -1;
+ (this->get_condition(UF)) ? s1 = pc + s2 : s1 = -1;
(void)s3;
}),
INIT_INSTRUCTION(
BOF,
{
- (this->get_condition(OF)) ? s1 = wrap_address(pc + s2)
- : s1 = -1;
+ (this->get_condition(OF)) ? s1 = pc + s2 : s1 = -1;
(void)s3;
}),
@@ -387,7 +382,7 @@ void EX::advance_helper()
s3 = this->curr_instr->get_s3();
pc = this->curr_instr->get_pc();
- this->instr_map[m](s1, s2, s3, pc );
+ 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 46694ad..37c6773 100644
--- a/src/sim/id.cc
+++ b/src/sim/id.cc
@@ -38,7 +38,13 @@ Response ID::read_guard(signed int &v)
void ID::write_guard(signed int &v)
{
- this->checked_out.push_back(v);
+ // zero register shouldn't be written.
+ if (v != 0) {
+ // keep track in the instrDTO for displaying to user and writeback
+ // keep track in checked_out so we can still access this information!
+ this->checked_out.push_back(v);
+ this->curr_instr->set_checked_out(v);
+ }
v = this->dereference_register(v);
}
@@ -72,7 +78,7 @@ void ID::get_instr_fields(
switch (type) {
case 0b00:
t = R;
- this->decode_R_type(s1, s2, s3);
+ this->decode_R_type(s1, s2, s3, m);
break;
case 0b01:
t = I;
@@ -88,7 +94,8 @@ void ID::get_instr_fields(
}
}
-void ID::decode_R_type(signed int &s1, signed int &s2, signed int &s3)
+void ID::decode_R_type(
+ signed int &s1, signed int &s2, signed int &s3, Mnemonic &m)
{
unsigned int s0b, s1b, s2b;
Response r1, r2;
@@ -104,30 +111,52 @@ void ID::decode_R_type(signed int &s1, signed int &s2, signed int &s3)
r2 = this->read_guard(s2);
this->status = (r1 == OK && r2 == OK) ? OK : STALLED;
- if (this->status == OK)
- this->write_guard(s3);
+ switch (m) {
+ case CMP:
+ case CEV:
+ break;
+ default:
+ if (this->status == OK)
+ this->write_guard(s3);
+ }
}
void ID::decode_I_type(
signed int &s1, signed int &s2, signed int &s3, Mnemonic &m)
{
unsigned int s0b, s1b, s2b;
- Response r1;
+ Response r1, r2;
s0b = REG_SIZE;
s1b = s0b + REG_SIZE;
- s2b = WORD_SPEC;
- s3 = GET_MID_BITS(s1, s1b, s2b);
- s2 = GET_MID_BITS(s1, s0b, s1b);
- s1 = GET_LS_BITS(s1, s0b);
+ s2b = WORD_SPEC - LINE_SPEC - OPCODE_SIZE;
+ s3 = GET_BITS_SIGN_EXTEND(s1, s1b, s2b);
+
+ switch (m) {
+ case STORE:
+ case STOREV:
+ s2 = GET_MID_BITS(s1, s0b, s1b);
+ s1 = GET_LS_BITS(s1, s0b);
+
+ // both operands are read values
+ r1 = this->read_guard(s1);
+ r2 = this->read_guard(s2);
+ this->status = (r1 == OK && r2 == OK) ? OK : STALLED;
+ return;
+ case LOAD:
+ case LOADV:
+ s2 = GET_LS_BITS(s1, s0b);
+ s1 = GET_MID_BITS(s1, s0b, s1b);
+ break;
+ default:
+ s2 = GET_MID_BITS(s1, s0b, s1b);
+ s1 = GET_LS_BITS(s1, s0b);
+ }
r1 = this->read_guard(s1);
- if (m != STORE && m != STOREV) {
- this->status = r1;
- if (r1 == OK)
- this->write_guard(s2);
- } else
- this->status = (this->read_guard(s2) == OK && r1 == OK) ? OK : STALLED;
+ if (r1 == OK)
+ this->write_guard(s2);
+ this->status = r1;
}
void ID::decode_J_type(signed int &s1, signed int &s2, signed int &s3)
@@ -135,19 +164,20 @@ void ID::decode_J_type(signed int &s1, signed int &s2, signed int &s3)
unsigned int s0b, s1b;
s0b = REG_SIZE;
- s1b = WORD_SPEC;
+ s1b = WORD_SPEC - LINE_SPEC - OPCODE_SIZE;
s3 = 0;
- s2 = GET_MID_BITS(s1, s0b, s1b);
+ s2 = GET_BITS_SIGN_EXTEND(s1, s0b, s1b);
s1 = GET_LS_BITS(s1, s0b);
this->status = this->read_guard(*&s1);
}
-std::vector<int> ID::stage_info() {
+std::vector<int> ID::stage_info()
+{
std::vector<int> info;
- if(this->curr_instr){
+ if (this->curr_instr) {
info.push_back(this->curr_instr->get_pc());
info.push_back(this->curr_instr->get_instr_bits());
- }
+ }
return info;
}
diff --git a/src/sim/if.cc b/src/sim/if.cc
index fb49749..1223149 100644
--- a/src/sim/if.cc
+++ b/src/sim/if.cc
@@ -14,7 +14,6 @@ InstrDTO *IF::advance(Response p)
if (this->curr_instr != nullptr && p == WAIT) {
// mutual consent
++this->pc;
- this->curr_instr->set_time_of(this->id, this->clock_cycle);
r = new InstrDTO(*this->curr_instr);
delete curr_instr;
curr_instr = nullptr;
@@ -23,12 +22,12 @@ InstrDTO *IF::advance(Response p)
return r;
}
-std::vector<int> IF::stage_info() {
+std::vector<int> IF::stage_info() {
std::vector<int> info;
if(this->curr_instr){
info.push_back(this->curr_instr->get_pc());
info.push_back(this->curr_instr->get_instr_bits());
- }
+ }
return info;
}
diff --git a/src/sim/instr.cc b/src/sim/instr.cc
index e614de5..8bbd0b5 100644
--- a/src/sim/instr.cc
+++ b/src/sim/instr.cc
@@ -13,12 +13,11 @@ const std::unordered_map<unsigned int, Mnemonic> mnemonic_map = {
{0b0110100, SUBV}, {0b0111000, MULV}, {0b0111100, DIVV},
{0b1000000, CMP}, {0b1000100, CEV}, {0b000101, LOAD},
{0b001001, LOADV}, {0b0001101, ADDI}, {0b0010001, SUBI},
- {0b0010101, SFTRI}, {0b0011101, SFTLI}, {0b0100001, ANDI},
- {0b0100101, ORI}, {0b0101001, XORI}, {0b0101101, STORE},
- {0b0110001, STOREV}, {0b0000101, CEV}, {0b0000101, LOAD},
- {0b0001001, LOADV}, {0b0001001, LOADV}, {0b0000110, JMP},
- {0b0001010, JRL}, {0b0001110, JAL}, {0b0010010, BEQ},
- {0b0010110, BGT}, {0b0011010, BUF}, {0b0011110, BOF},
- {0b0100010, PUSH}, {0b0100110, POP},
+ {0b0010101, SFTRI}, {0b0011001, SFTLI}, {0b0011101, ANDI},
+ {0b0100001, ORI}, {0b0100101, XORI}, {0b0101001, STORE},
+ {0b0101101, STOREV}, {0b0000110, JMP}, {0b0001010, JRL},
+ {0b0001110, JAL}, {0b0010010, BEQ}, {0b0010110, BGT},
+ {0b0011010, BUF}, {0b0011110, BOF}, {0b0100010, PUSH},
+ {0b0100110, POP},
};
} // namespace instr
diff --git a/src/sim/instrDTO.cc b/src/sim/instrDTO.cc
index aa49b7e..a82ef28 100644
--- a/src/sim/instrDTO.cc
+++ b/src/sim/instrDTO.cc
@@ -4,6 +4,7 @@
InstrDTO::InstrDTO()
{
this->instr_bits = 0;
+ this->checked_out = -1;
this->s1 = 0;
this->s2 = 0;
this->s3 = 0;
@@ -12,10 +13,10 @@ InstrDTO::InstrDTO()
this->pc = 0;
}
-int InstrDTO::get_time_of(Accessor a) { return this->hist[a]; }
-
signed int InstrDTO::get_instr_bits() { return this->instr_bits; }
+signed int InstrDTO::get_checked_out() { return this->checked_out; }
+
signed int InstrDTO::get_s1() { return this->s1; }
signed int InstrDTO::get_s2() { return this->s2; }
@@ -28,10 +29,13 @@ 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; }
+void InstrDTO::set_checked_out(signed int checked_out)
+{
+ this->checked_out = checked_out;
+}
+
void InstrDTO::set_s1(signed int s) { this->s1 = s; }
void InstrDTO::set_s2(signed int s) { this->s2 = s; }
diff --git a/src/sim/stage.cc b/src/sim/stage.cc
index 8a570f0..7df1dba 100644
--- a/src/sim/stage.cc
+++ b/src/sim/stage.cc
@@ -1,5 +1,4 @@
#include "stage.h"
-#include "utils.h"
#include <array>
#include <deque>
@@ -28,18 +27,17 @@ InstrDTO *Stage::advance(Response p)
InstrDTO *s = nullptr;
Response n;
- // std::cout << "advance: " << this->id << ": " << this->curr_instr << "?: " << p << ": " << this->checked_out.size() << ": ";
- // if (curr_instr)
+ // std::cout << "advance: " << this->id << ": " << this->curr_instr << "?: "
+ // << p << ": " << this->checked_out.size() << ": "; if (curr_instr)
// std::cout << curr_instr->get_mnemonic();
// for (long unsigned int i = 0; i < this->checked_out.size(); ++i)
// std::cout << this->checked_out[i] << " ";
- // std::cout << std::endl;
+ // std::cout << std::endl;
if (this->curr_instr && this->status != OK) {
this->advance_helper();
}
if (this->status == OK && p == WAIT && this->curr_instr) {
// mutual consent
- this->curr_instr->set_time_of(this->id, this->clock_cycle);
r = new InstrDTO(*this->curr_instr);
delete curr_instr;
curr_instr = nullptr;
@@ -53,9 +51,10 @@ InstrDTO *Stage::advance(Response p)
return r;
}
-std::vector<int> Stage::stage_info() {
+std::vector<int> Stage::stage_info()
+{
std::vector<int> info;
- if(this->curr_instr){
+ if (this->curr_instr) {
info.push_back(this->curr_instr->get_mnemonic());
info.push_back(this->curr_instr->get_pc());
info.push_back(this->curr_instr->get_s1());
@@ -63,7 +62,7 @@ std::vector<int> Stage::stage_info() {
info.push_back(this->curr_instr->get_s3());
}
return info;
- }
+}
void Stage::set_condition(CC c, bool v)
{
@@ -78,10 +77,8 @@ signed int Stage::dereference_register(signed int v)
signed int r;
if (v < 0 || v >= GPR_NUM + V_NUM) {
- throw std::out_of_range(string_format(
- "instruction tried to access register %d, which does "
- "not exist",
- v));
+ throw std::out_of_range(
+ "instruction tried to access register which does not exist");
}
r = (v >= GPR_NUM) ? this->vrs[v % GPR_NUM] : this->gprs[v];
@@ -91,10 +88,8 @@ signed int Stage::dereference_register(signed int v)
void Stage::store_register(signed int v, signed int d)
{
if (v < 0 || v >= GPR_NUM + V_NUM) {
- throw std::out_of_range(string_format(
- "instruction tried to access register %d, which does "
- "not exist",
- v));
+ throw std::out_of_range(
+ "instruction tried to access register which does not exist");
}
if (v >= GPR_NUM)
diff --git a/src/sim/wb.cc b/src/sim/wb.cc
index 01768e8..4e6b2b0 100644
--- a/src/sim/wb.cc
+++ b/src/sim/wb.cc
@@ -3,6 +3,8 @@
#include "instrDTO.h"
#include "response.h"
#include "stage.h"
+#include <array>
+#include <algorithm>
WB::WB(Stage *stage) : Stage(stage) { this->id = WRITE; }
@@ -10,7 +12,7 @@ void WB::advance_helper()
{
if (this->curr_instr->get_mnemonic() != NOP &&
this->curr_instr->get_type() != INV) {
- if (this->should_write())
+ if (this->curr_instr->get_checked_out() > 0)
this->write_handler();
else if (this->should_jump())
this->jump_handler();
@@ -26,8 +28,8 @@ void WB::write_handler()
throw std::runtime_error("instruction tried to pop a register out of "
"an empty queue during writeback.");
- reg = this->checked_out.front();
this->checked_out.pop_front();
+ reg = this->curr_instr->get_checked_out();
this->store_register(reg, this->curr_instr->get_s1());
}
@@ -49,13 +51,3 @@ bool WB::should_jump()
t = this->curr_instr->get_type();
return t == J;
}
-
-bool WB::should_write()
-{
- Mnemonic m;
- Type t;
-
- m = this->curr_instr->get_mnemonic();
- t = this->curr_instr->get_type();
- return (t == R || t == I) && (m != STORE && m != STOREV);
-}
diff --git a/tests/controller.cc b/tests/controller.cc
index a009a70..59f1d81 100644
--- a/tests/controller.cc
+++ b/tests/controller.cc
@@ -16,7 +16,7 @@ class ControllerPipeFixture
ControllerPipeFixture()
{
this->d = new Dram(1);
- this->c = new Cache(this->d, 0);
+ this->c = new Cache(this->d, 5, 0, 0);
IF *f = new IF(nullptr);
ID *d = new ID(f);
@@ -107,11 +107,6 @@ TEST_CASE_METHOD(ControllerPipeFixture, "two num adder", "[full 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);
@@ -124,11 +119,6 @@ TEST_CASE_METHOD(ControllerPipeFixture, "two num adder", "[full pipe]")
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);
@@ -152,13 +142,6 @@ TEST_CASE_METHOD(ControllerPipeFixture, "two num adder", "[full pipe]")
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(EXEC) == 9);
- 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);
@@ -173,11 +156,6 @@ TEST_CASE_METHOD(ControllerPipeFixture, "two num adder", "[full pipe]")
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) == 14);
- CHECK(i->get_time_of(MEM) == 15);
- CHECK(i->get_time_of(WRITE) == 16);
CHECK(i->get_s1() == 0x2);
CHECK(i->get_s2() == 0x1); // the previous value in the destination register
CHECK(i->get_s3() == 0x2);
@@ -194,13 +172,6 @@ TEST_CASE_METHOD(ControllerPipeFixture, "two num adder", "[full pipe]")
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
@@ -215,11 +186,6 @@ TEST_CASE_METHOD(ControllerPipeFixture, "two num adder", "[full pipe]")
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);
@@ -232,11 +198,6 @@ TEST_CASE_METHOD(ControllerPipeFixture, "two num adder", "[full pipe]")
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);
@@ -251,11 +212,6 @@ TEST_CASE_METHOD(ControllerPipeFixture, "two num adder", "[full pipe]")
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(this->ct->get_gprs().at(2) == 0x200);
@@ -283,13 +239,6 @@ TEST_CASE_METHOD(ControllerPipeFixture, "two num adder", "[full pipe]")
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);
@@ -305,13 +254,8 @@ TEST_CASE_METHOD(ControllerPipeFixture, "two num adder", "[full pipe]")
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(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);
@@ -335,11 +279,6 @@ TEST_CASE_METHOD(ControllerPipeFixture, "two num adder", "[full pipe]")
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);
@@ -360,11 +299,6 @@ TEST_CASE_METHOD(ControllerPipeFixture, "two num adder", "[full pipe]")
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() == 0x1);
CHECK(i->get_s2() == 0x0);
CHECK(i->get_s3() == 0x0);
@@ -380,11 +314,6 @@ TEST_CASE_METHOD(ControllerPipeFixture, "two num adder", "[full pipe]")
i = this->ct->advance(WAIT);
REQUIRE(i != nullptr);
- CHECK(i->get_time_of(FETCH) == 33);
- CHECK(i->get_time_of(DCDE) == 34);
- CHECK(i->get_time_of(EXEC) == 35);
- CHECK(i->get_time_of(MEM) == 36);
- CHECK(i->get_time_of(WRITE) == 37);
CHECK(i->get_s1() == 0x2);
CHECK(i->get_s2() == 0x0);
CHECK(i->get_s3() == 0x1);
@@ -405,11 +334,6 @@ TEST_CASE_METHOD(ControllerPipeFixture, "two num adder", "[full pipe]")
i = this->ct->advance(WAIT);
REQUIRE(i != nullptr);
- CHECK(i->get_time_of(FETCH) == 34);
- CHECK(i->get_time_of(DCDE) == 37);
- CHECK(i->get_time_of(EXEC) == 38);
- CHECK(i->get_time_of(MEM) == 39);
- CHECK(i->get_time_of(WRITE) == 40);
CHECK(i->get_s1() == 0x3);
CHECK(i->get_s2() == 0x2);
CHECK(i->get_s3() == 0x1);
@@ -429,11 +353,6 @@ TEST_CASE_METHOD(ControllerPipeFixture, "two num adder", "[full pipe]")
i = this->ct->advance(WAIT);
REQUIRE(i != nullptr);
- CHECK(i->get_time_of(FETCH) == 37);
- CHECK(i->get_time_of(DCDE) == 40);
- CHECK(i->get_time_of(EXEC) == 41);
- CHECK(i->get_time_of(MEM) == 42);
- CHECK(i->get_time_of(WRITE) == 43);
CHECK(i->get_s1() == 0x200);
CHECK(i->get_s2() == 0x3);
CHECK(i->get_s3() == 0x0);
diff --git a/tests/ex.cc b/tests/ex.cc
index 13437f7..a493a21 100644
--- a/tests/ex.cc
+++ b/tests/ex.cc
@@ -13,7 +13,7 @@ class EXFixture
EXFixture()
{
this->dr = new Dram(3);
- this->c = new Cache(this->dr, 1);
+ this->c = new Cache(this->dr, 5, 0, 1);
this->dum = new DUM(nullptr);
this->e = new EX(dum);
this->ct = new Controller(this->e, this->c, true);
diff --git a/tests/id.cc b/tests/id.cc
index 77a7cd9..06eec0c 100644
--- a/tests/id.cc
+++ b/tests/id.cc
@@ -13,7 +13,7 @@ class IDFixture
IDFixture()
{
this->dr = new Dram(3);
- this->c = new Cache(this->dr, 1);
+ this->c = new Cache(this->dr, 5, 0, 1);
this->dum = new DUM(nullptr);
this->d = new ID(dum);
this->ct = new Controller(this->d, this->c, true);
@@ -140,7 +140,7 @@ TEST_CASE_METHOD(IDFixture, "Parse arbitrary i-type # one", "[id]")
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_mnemonic() == ANDI);
delete i;
}
@@ -152,11 +152,11 @@ TEST_CASE_METHOD(IDFixture, "Parse arbitrary i-type # two", "[id]")
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);
+ CHECK(i->get_mnemonic() == STOREV);
delete i;
}
@@ -185,7 +185,7 @@ TEST_CASE_METHOD(IDFixture, "Parse arbitrary j-type # two", "[id]")
i = this->decode_bits(t);
CHECK(i->get_s1() == 0x00000000); // registers are empty
- CHECK(i->get_s2() == 0xBBCCF);
+ CHECK(i->get_s2() == 0xFFFBBCCF);
CHECK(i->get_mnemonic() == JAL);
delete i;
@@ -254,7 +254,7 @@ TEST_CASE_METHOD(IDFixture, "stores indefinite conflicts", "[id]")
signed int v, ov;
Response r;
- v = 0b0;
+ v = 0b1;
ov = v;
while (v < 0b110) {
this->d->write_guard(v);
@@ -269,8 +269,8 @@ TEST_CASE_METHOD(IDFixture, "stores indefinite conflicts", "[id]")
CHECK(v == 0b110);
REQUIRE(r == STALLED);
- v = 0b0;
+ v = 0b1;
r = this->d->read_guard(v);
- CHECK(v == 0b0);
+ CHECK(v == 0b1);
REQUIRE(r == STALLED);
}
diff --git a/tests/if.cc b/tests/if.cc
index d6c1bca..01070ef 100644
--- a/tests/if.cc
+++ b/tests/if.cc
@@ -17,7 +17,7 @@ class IFFixture
p = {0xC000, 0xC001, 0xC002, 0xC003};
d->load(p);
- this->c = new Cache(d, this->c_delay);
+ this->c = new Cache(d, 5, 0, this->c_delay);
this->f = new IF(nullptr);
this->ct = new Controller(this->f, this->c, true);
}
@@ -77,7 +77,6 @@ TEST_CASE_METHOD(IFFixture, "fetch returns single instuction", "[if_pipe]")
expected_cycles = this->m_delay + this->c_delay + 2;
i = this->fetch_through();
- CHECK(i->get_time_of(FETCH) == expected_cycles);
REQUIRE(i->get_instr_bits() == this->p[0]);
delete i;
@@ -91,14 +90,12 @@ TEST_CASE_METHOD(IFFixture, "fetch returns two instuctions", "[if_pipe]")
expected_cycles = this->m_delay + this->c_delay + 2;
i = this->fetch_through();
- CHECK(i->get_time_of(FETCH) == expected_cycles);
REQUIRE(i->get_instr_bits() == this->p[0]);
delete i;
expected_cycles += this->c_delay + 1;
i = this->fetch_cache();
- CHECK(i->get_time_of(FETCH) == expected_cycles);
REQUIRE(i->get_instr_bits() == this->p[1]);
delete i;
}
@@ -129,7 +126,6 @@ TEST_CASE_METHOD(IFFixture, "fetch waits with old instruction", "[if_pipe]")
i = this->ct->advance(WAIT);
REQUIRE(i != nullptr);
- CHECK(i->get_time_of(FETCH) == expected_cycles);
REQUIRE(i->get_instr_bits() == this->p[0]);
delete i;