summaryrefslogtreecommitdiff
path: root/src/sim/stage.cc
diff options
context:
space:
mode:
authorbd <bdunaisky@umass.edu>2025-04-02 04:05:18 +0000
committerGitHub <noreply@github.com>2025-04-02 04:05:18 +0000
commit9fb95d655393777dde5929182f94de36f903821d (patch)
tree4462f35895737460a01fab891a15f87aba2efb70 /src/sim/stage.cc
parent24f0bd8af57381ab3112b5774d4ad23ac80f0718 (diff)
parent3eeb345d673bee6d62b04fc8a8a95ab822dc1e45 (diff)
Merge pull request #46 from bdunahu/bdunahu
Ensure all stages only do work if they are not 'OK'
Diffstat (limited to 'src/sim/stage.cc')
-rw-r--r--src/sim/stage.cc59
1 files changed, 40 insertions, 19 deletions
diff --git a/src/sim/stage.cc b/src/sim/stage.cc
index be69d77..2857e1f 100644
--- a/src/sim/stage.cc
+++ b/src/sim/stage.cc
@@ -7,8 +7,7 @@ Stage::Stage(Stage *next)
{
this->next = next;
this->curr_instr = nullptr;
- this->status = OK;
- this->checked_out = {};
+ this->status = WAIT;
}
Stage::~Stage() { delete this->next; };
@@ -21,32 +20,36 @@ Storage *Stage::storage;
bool Stage::is_pipelined;
int Stage::clock_cycle;
-bool Stage::get_condition(CC c) {
- return (this->gprs[3] >> c) & 1;
-}
-
-void Stage::set_pc(unsigned int pc) {
- this->pc = pc;
-}
+bool Stage::get_condition(CC c) { return (this->gprs[3] >> c) & 1; }
InstrDTO *Stage::advance(Response p)
{
InstrDTO *r = nullptr;
+ InstrDTO *s = nullptr;
Response n;
- this->advance_helper();
- if (this->status == OK && this->curr_instr != nullptr && p == OK) {
+ // 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;
+ 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;
- this->status = STALLED;
+ this->status = WAIT;
}
- n = (p != OK || this->status != OK) ? STALLED : OK;
- // the power of consent
- this->curr_instr = this->next->advance(n);
+ n = (p != WAIT || this->status != WAIT) ? STALLED : WAIT;
+ s = this->next->advance(n);
+ if (s)
+ this->curr_instr = s;
return r;
}
@@ -73,16 +76,34 @@ signed int Stage::dereference_register(signed int v)
return r;
}
+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));
+ }
+
+ if (v >= GPR_NUM)
+ this->vrs[v % GPR_NUM] = d;
+ else
+ this->gprs[v] = d;
+}
+
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->set_mnemonic(NOP);
- this->status = OK;
- if(this->next){
+void Stage::squash()
+{
+ if (curr_instr) {
+ this->curr_instr->set_mnemonic(NOP);
+ this->status = OK;
+ }
+ if (this->next) {
this->next->squash();
}
}