summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSiddarth-Suresh <65844402+Siddarth-Suresh@users.noreply.github.com>2025-03-31 13:45:56 -0400
committerSiddarth-Suresh <65844402+Siddarth-Suresh@users.noreply.github.com>2025-03-31 13:45:56 -0400
commit598da346f59503442ba0b4badfd9ac8b58af4a89 (patch)
tree6f850061b9e89a93c30c8a6d7a699ffdc291e2ab /src
parent44cb9d396b909c84ef7ad3338e0a12cfcc082748 (diff)
MEM WB stage
Diffstat (limited to 'src')
-rw-r--r--src/sim/controller.cc5
-rw-r--r--src/sim/ex.cc8
-rw-r--r--src/sim/id.cc11
-rw-r--r--src/sim/instrDTO.cc5
-rw-r--r--src/sim/mm.cc22
-rw-r--r--src/sim/stage.cc10
-rw-r--r--src/sim/wb.cc30
7 files changed, 79 insertions, 12 deletions
diff --git a/src/sim/controller.cc b/src/sim/controller.cc
index 06591af..89ff4e7 100644
--- a/src/sim/controller.cc
+++ b/src/sim/controller.cc
@@ -31,10 +31,11 @@ int Controller::get_pc() { return this->pc; }
InstrDTO *Controller::advance(Response p)
{
InstrDTO *r;
-
r = this->next->advance(p);
++this->clock_cycle;
return r;
}
-void Controller::advance_helper() {}
+void Controller::advance_helper() {
+ // TODO: check halt condition and call UI to refresh
+}
diff --git a/src/sim/ex.cc b/src/sim/ex.cc
index 95cce8d..f22adc0 100644
--- a/src/sim/ex.cc
+++ b/src/sim/ex.cc
@@ -282,28 +282,28 @@ EX::EX(Stage *stage) : Stage(stage)
INIT_INSTRUCTION(
BEQ,
{
- s1 = this->pc + s2;
+ (this->get_condition(EQ)) ? s1 = this->pc + s2 : s1 = this->pc;
(void)s3;
}),
INIT_INSTRUCTION(
BGT,
{
- s1 = this->pc + s2;
+ (this->get_condition(GT)) ? s1 = this->pc + s2 : s1 = this->pc;
(void)s3;
}),
INIT_INSTRUCTION(
BUF,
{
- s1 = this->pc + s2;
+ (this->get_condition(UF)) ? s1 = this->pc + s2 : s1 = this->pc;
(void)s3;
}),
INIT_INSTRUCTION(
BOF,
{
- s1 = this->pc + s2;
+ (this->get_condition(OF)) ? s1 = this->pc + s2 : s1 = this->pc;
(void)s3;
}),
diff --git a/src/sim/id.cc b/src/sim/id.cc
index edf74e2..deb69fb 100644
--- a/src/sim/id.cc
+++ b/src/sim/id.cc
@@ -46,38 +46,43 @@ void ID::advance_helper()
{
signed int s1, s2, s3;
Mnemonic m;
+ Type t;
// it may be good to ensure we are not doing
// work that has already been done
if (this->curr_instr) {
s1 = curr_instr->get_instr_bits();
- get_instr_fields(s1, s2, s3, m);
+ get_instr_fields(s1, s2, s3, m ,t);
if (this->status == OK) {
curr_instr->set_s1(s1);
curr_instr->set_s2(s2);
curr_instr->set_s3(s3);
curr_instr->set_mnemonic(m);
+ curr_instr->set_type(t);
}
}
}
-void ID::get_instr_fields(
- signed int &s1, signed int &s2, signed int &s3, Mnemonic &m)
+void ID::get_instr_fields(signed int &s1, signed int &s2, signed int &s3, Mnemonic &m, Type &t)
{
unsigned int type;
this->split_instr(s1, type, m);
switch (type) {
case 0b00:
+ t = R;
this->decode_R_type(s1, s2, s3);
break;
case 0b01:
+ t = I;
this->decode_I_type(s1, s2, s3);
break;
case 0b10:
+ t = J;
this->decode_J_type(s1, s2);
break;
case 0b11:
+ t = INV;
this->status = OK;
}
}
diff --git a/src/sim/instrDTO.cc b/src/sim/instrDTO.cc
index 5a7fe3b..28364b7 100644
--- a/src/sim/instrDTO.cc
+++ b/src/sim/instrDTO.cc
@@ -8,6 +8,7 @@ InstrDTO::InstrDTO()
this->s2 = 0;
this->s3 = 0;
this->mnemonic = NOP;
+ this->type = INV;
}
int InstrDTO::get_time_of(Accessor a) { return this->hist[a]; }
@@ -22,6 +23,8 @@ signed int InstrDTO::get_s3() { return this->s3; }
Mnemonic InstrDTO::get_mnemonic() { return this->mnemonic; }
+Type InstrDTO::get_type() { return this->type; }
+
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; }
@@ -33,3 +36,5 @@ void InstrDTO::set_s2(signed int s) { this->s2 = s; }
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; }
diff --git a/src/sim/mm.cc b/src/sim/mm.cc
index 2b73207..cd85056 100644
--- a/src/sim/mm.cc
+++ b/src/sim/mm.cc
@@ -6,4 +6,24 @@
MM::MM(Stage *stage) : Stage(stage) { this->id = MEM; }
-void MM::advance_helper() {}
+void MM::advance_helper() {
+ Response r;
+ signed int data;
+ if(this->curr_instr){
+ if (this->curr_instr->get_mnemonic() == LOAD) {
+ r = this->storage->read_word(this->id, this->curr_instr->get_s1(), data);
+ if(r == OK){
+ this->status = OK;
+ this->curr_instr->set_s2(data);
+ }
+ } else if (this->curr_instr->get_mnemonic() == STORE) {
+ r = this->storage->write_word(this->id, this->curr_instr->get_s2(), this->curr_instr->get_s1());
+ if(r == OK){
+ this->status = OK;
+ }
+ } else {
+ // Mem has no work so just forward the instruction to WB
+ this->status = OK;
+ }
+ }
+}
diff --git a/src/sim/stage.cc b/src/sim/stage.cc
index 5b81e4c..26b6ee6 100644
--- a/src/sim/stage.cc
+++ b/src/sim/stage.cc
@@ -35,7 +35,7 @@ InstrDTO *Stage::advance(Response p)
Response n;
this->advance_helper();
- if (this->curr_instr != nullptr && p == OK) {
+ if (this->status == OK && this->curr_instr != nullptr && p == OK) {
// mutual consent
this->curr_instr->set_time_of(this->id, this->clock_cycle);
r = new InstrDTO(*this->curr_instr);
@@ -78,3 +78,11 @@ bool Stage::is_checked_out(signed int r)
return std::find(this->checked_out.begin(), this->checked_out.end(), r) !=
this->checked_out.end();
}
+
+void Stage::squash(){
+ this->curr_instr = nullptr;
+ this->status = OK;
+ if(this->next){
+ this->next->squash();
+ }
+}
diff --git a/src/sim/wb.cc b/src/sim/wb.cc
index 9337aa0..480af05 100644
--- a/src/sim/wb.cc
+++ b/src/sim/wb.cc
@@ -6,4 +6,32 @@
WB::WB(Stage *stage) : Stage(stage) { this->id = WRITE; }
-void WB::advance_helper() {}
+void WB::advance_helper() {
+ if(this -> curr_instr) {
+ if(this->curr_instr->get_type() == R || this->curr_instr->get_type() == I){
+ if(this->checked_out.size() > 0) {
+ signed int reg = this->checked_out.front();
+ this->checked_out.pop_front();
+ if(reg >= GPR_NUM){
+ // TODO: handle vector instructions
+ } else {
+ this->gprs[reg] = this->curr_instr->get_s1();
+ }
+ }
+ } else if (this->curr_instr->get_type() == J) {
+ // TODO:handle push pop
+ // branch taken
+ if(this->pc != this->curr_instr->get_s1()) {
+ if(this->curr_instr->get_mnemonic() == JAL){
+ // set link register to next instruction
+ this->gprs[1] = this->pc + 1;
+ }
+ this->pc = this->curr_instr->get_s1();
+ //clear pending registers and squash pipeline
+ this->checked_out = {};
+ this->next->squash();
+ }
+ }
+ }
+ this->status = OK;
+}