diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/sim/id.cc | 95 | ||||
-rw-r--r-- | src/sim/stage.cc | 52 |
2 files changed, 87 insertions, 60 deletions
diff --git a/src/sim/id.cc b/src/sim/id.cc index 83a8751..c04b31f 100644 --- a/src/sim/id.cc +++ b/src/sim/id.cc @@ -5,52 +5,85 @@ #include "logger.h" #include "response.h" #include "stage.h" +#include <algorithm> ID::ID(Stage *stage) : Stage(stage) { this->id = DCDE; } Response ID::advance(InstrDTO &next_instr, Response p) { Response r; - r = OK; - // signed int s1, s2, s3; - // Mnemonic m; + signed int s1, s2, s3; + Mnemonic m; - // s1 = next_instr.get_instr_bits(); + s1 = next_instr.get_instr_bits(); - // get_instr_fields(s1, s2, s3, m); + get_instr_fields(s1, s2, s3, m); return r; } +void ID::decode_R_type(signed int &s1, signed int &s2, signed int &s3) +{ + unsigned int s0b, s1b, s2b; + Response r1, r2; + + s0b = REG_SIZE; + s1b = s0b + REG_SIZE; + s2b = s1b + REG_SIZE; + s3 = GET_MID_BITS(s1, s1b, s2b); + s2 = GET_MID_BITS(s1, s0b, s1b); + s1 = GET_LS_BITS(s1, s0b); + + r1 = this->read_guard(s1); + r2 = this->read_guard(s2); + this->write_guard(s3); + + this->status = std::max(r1, r2); +} +void ID::decode_I_type(signed int &s1, signed int &s2, signed int &s3) +{ + unsigned int s0b, s1b, s2b; + + 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); + + this->status = this->read_guard(s1); + this->write_guard(s2); +} + +void ID::decode_J_type(signed int &s1, signed int &s2) +{ + unsigned int s0b, s1b; + + s0b = REG_SIZE; + s1b = WORD_SPEC; + s2 = GET_MID_BITS(s1, s0b, s1b); + s1 = GET_LS_BITS(s1, s0b); + + this->status = this->read_guard(*&s1); +} + // TODO this function is ugly void ID::get_instr_fields( signed int &s1, signed int &s2, signed int &s3, Mnemonic &m) { - unsigned int type, s0b, s1b, s2b; + unsigned int type; this->split_instr(s1, type, m); - // define the parsing bounds - s0b = REG_SIZE; switch (type) { case 0b00: - // R-TYPE - s1b = s0b + REG_SIZE; - s2b = s1b + REG_SIZE; + this->decode_R_type(s1, s2, s3); break; case 0b01: - // I-TYPE - s1b = s0b + REG_SIZE; - s2b = WORD_SPEC; + this->decode_I_type(s1, s2, s3); break; case 0b10: - // J-TYPE - s1b = WORD_SPEC; + this->decode_J_type(s1, s2); + break; } - - if (type != 0b10) - s3 = GET_MID_BITS(s1, s1b, s2b); - - s2 = GET_MID_BITS(s1, s0b, s1b); - s1 = GET_LS_BITS(s1, s0b); } void ID::split_instr(signed int &raw, unsigned int &type, Mnemonic &m) @@ -68,3 +101,21 @@ void ID::split_instr(signed int &raw, unsigned int &type, Mnemonic &m) raw = (unsigned int)raw >> (TYPE_SIZE + opcode_size); } + +Response ID::read_guard(signed int &v) +{ + Response r; + if (this->is_checked_out(v)) + r = BLOCKED; + else { + r = OK; + v = this->dereference_register(v); + } + return r; +} + +void ID::write_guard(signed int &v) +{ + this->checked_out.push_back(v); + v = this->dereference_register(v); +} diff --git a/src/sim/stage.cc b/src/sim/stage.cc index 48ee494..a8f3f9e 100644 --- a/src/sim/stage.cc +++ b/src/sim/stage.cc @@ -1,9 +1,7 @@ #include "stage.h" #include "utils.h" #include <array> -#include <set> - -static Logger *global_log = Logger::getInstance(); +#include <deque> Stage::Stage(Stage *next) { @@ -16,51 +14,29 @@ Stage::~Stage() { delete this->next; }; std::array<int, GPR_NUM> Stage::gprs; std::array<int, V_NUM> Stage::vrs; -std::set<unsigned int> Stage::checked_out; +std::deque<signed int> Stage::checked_out; unsigned int Stage::pc; Storage *Stage::storage; bool Stage::is_pipelined; int Stage::clock_cycle; -Response Stage::check_out(unsigned int &v) -{ - Response r; - if (this->is_checked_out(v)) - r = BLOCKED; - else { - r = OK; - v = this->check_out_register(v); - } - return r; -} - -bool Stage::is_checked_out(unsigned int r) -{ - return this->checked_out.find(r) != this->checked_out.end(); -} - -signed int Stage::check_out_register(unsigned int v) +signed int Stage::dereference_register(signed int v) { signed int r; - this->checked_out.insert(v); - r = this->dereference_register(v); - return r; -} - -signed int Stage::dereference_register(unsigned int v) -{ - signed int r; - - if (v >= GPR_NUM + V_NUM) { - global_log->log( - ERROR, string_format( - "instruction tried to access register %d, which does " - "not exist", - v)); - exit(EXIT_FAILURE); + 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)); } r = (v >= GPR_NUM) ? this->vrs[v % GPR_NUM] : this->gprs[v]; return r; } + +bool Stage::is_checked_out(signed int r) +{ + return std::find(this->checked_out.begin(), this->checked_out.end(), r) != + this->checked_out.end(); +} |