diff options
author | bd <bdunahu@operationnull.com> | 2025-03-27 20:30:18 -0400 |
---|---|---|
committer | bd <bdunahu@operationnull.com> | 2025-03-27 20:30:18 -0400 |
commit | eaa87e9fcd90c00d6261cbdb854efb7a09467f1d (patch) | |
tree | e7f4cc05a30e5589f8bd70ddc49f420369adbb3c | |
parent | 8d37d15ebd1221e3b1698abb3b051d9d0c044c93 (diff) |
Instr, InstrDTO gets/sets, other structures required for decode
-rw-r--r-- | inc/accessor.h | 3 | ||||
-rw-r--r-- | inc/ex.h | 7 | ||||
-rw-r--r-- | inc/id.h | 7 | ||||
-rw-r--r-- | inc/if.h | 14 | ||||
-rw-r--r-- | inc/instr.h | 14 | ||||
-rw-r--r-- | inc/instrDTO.h | 60 | ||||
-rw-r--r-- | inc/mm.h | 7 | ||||
-rw-r--r-- | inc/stage.h | 9 | ||||
-rw-r--r-- | inc/wb.h | 7 | ||||
-rw-r--r-- | src/sim/controller.cc | 4 | ||||
-rw-r--r-- | src/sim/ex.cc | 11 | ||||
-rw-r--r-- | src/sim/id.cc | 11 | ||||
-rw-r--r-- | src/sim/if.cc | 3 | ||||
-rw-r--r-- | src/sim/instr.cc | 30 | ||||
-rw-r--r-- | src/sim/instrDTO.cc | 20 | ||||
-rw-r--r-- | src/sim/mm.cc | 8 | ||||
-rw-r--r-- | src/sim/stage.cc | 2 | ||||
-rw-r--r-- | src/sim/wb.cc | 11 | ||||
-rw-r--r-- | src/utils/accessor.cc | 4 |
19 files changed, 190 insertions, 42 deletions
diff --git a/inc/accessor.h b/inc/accessor.h index fb4999d..eb56785 100644 --- a/inc/accessor.h +++ b/inc/accessor.h @@ -4,7 +4,10 @@ enum Accessor { IDLE, + WRITE, MEM, + EXEC, + DCDE, FETCH, L1CACHE, SIDE, @@ -7,7 +7,12 @@ class EX : public Stage { public: - using Stage::Stage; + /** + * Constructor. + * @param The next stage in the pipeline. + * @return A newly allocated EX object. + */ + EX(Stage *next); Response advance(InstrDTO &i) override; }; @@ -7,7 +7,12 @@ class ID : public Stage { public: - using Stage::Stage; + /** + * Constructor. + * @param The next stage in the pipeline. + * @return A newly allocated ID object. + */ + ID(Stage *next); Response advance(InstrDTO &i) override; }; @@ -1,5 +1,6 @@ #ifndef IF_H #define IF_H +#include "accessor.h" #include "instrDTO.h" #include "response.h" #include "stage.h" @@ -7,15 +8,14 @@ class IF : public Stage { public: - using Stage::Stage; - - Response advance(InstrDTO &i) override; - - private: /** - * The name this pipeline stages uses to access storage. + * Constructor. + * @param The next stage in the pipeline. + * @return A newly allocated IF object. */ - const Accessor id = FETCH; + IF(Stage *next); + + Response advance(InstrDTO &i) override; }; #endif /* IF_H_INCLUDED */ diff --git a/inc/instr.h b/inc/instr.h new file mode 100644 index 0000000..ce08685 --- /dev/null +++ b/inc/instr.h @@ -0,0 +1,14 @@ +#ifndef INSTR_H +#define INSTR_H + +#include <functional> +#include <map> + +namespace instr +{ +// clang-format off +extern const std::map<int,std::map<int,std::function<void(signed int &s1, signed int &s2, signed int &s3)>>> instr_map; +// clang-format on +} // namespace instr + +#endif /* INSTR_H_INCLUDED */ diff --git a/inc/instrDTO.h b/inc/instrDTO.h index 86cec05..7f2c688 100644 --- a/inc/instrDTO.h +++ b/inc/instrDTO.h @@ -1,5 +1,7 @@ #ifndef INSTRDTO_H #define INSTRDTO_H +#include <string> +#include <functional> class InstrDTO { @@ -15,25 +17,81 @@ class InstrDTO */ int get_if_cycle(); /** + * @return id_cycle + */ + int get_id_cycle(); + /** * @return instr_bits */ signed int get_instr_bits(); + /** + * @return s1 + */ + signed int get_s1(); + /** + * @return s2 + */ + signed int get_s2(); + /** + * @return s3 + */ + signed int get_s3(); + /** + * @return the string representation of oper. + */ + std::string get_oper_name(); /** * @param if_cycle */ void set_if_cycle(int); /** + * @param id_cycle + */ + void set_id_cycle(int); + /** * @param instr_bits */ void set_instr_bits(signed int); + /** + * @param s1 + */ + void set_s1(signed int); + /** + * @param s2 + */ + void set_s2(signed int); + /** + * @param s3 + */ + void set_s3(signed int); private: /** - * The current clock cycle. + * The clock cycle this instruction finished being fetched. */ int if_cycle; + /** + * The clock cycle this instruction finished being identified. + */ + int id_cycle; + /** + * The raw bits encoding the instruction. + */ signed int instr_bits; + /** + * Slots in this instruction, for storing temporary registers, immediates, + * or other. + * Some instruction types may use these differently. + * The `oper` function is in charge of knowing how to parse these. + */ + signed int s1; + signed int s2; + signed int s3; + /** + * The operation to be conducted during the execute phase. + */ + std::function<void()> instr; }; #endif /* INSTRDTO_H_INCLUDED */ @@ -7,7 +7,12 @@ class MM : public Stage { public: - using Stage::Stage; + /** + * Constructor. + * @param The next stage in the pipeline. + * @return A newly allocated MM object. + */ + MM(Stage *next); Response advance(InstrDTO &i) override; }; diff --git a/inc/stage.h b/inc/stage.h index ac810a9..04de475 100644 --- a/inc/stage.h +++ b/inc/stage.h @@ -4,6 +4,7 @@ #include "instrDTO.h" #include "response.h" #include "storage.h" +#include "accessor.h" #include <array> class Stage @@ -27,13 +28,17 @@ class Stage protected: /** + * The name of the pipeline stage. + */ + Accessor id; + /** * The shared pool of general-purpose integer registers. */ - static std::array<int, GPR_NUM> gprs; + static std::array<signed int, GPR_NUM> gprs; /** * The address of the currently executing instruction. */ - static int pc; + static unsigned int pc; /** * A pointer to the next stage in the pipeline. */ @@ -7,7 +7,12 @@ class WB : public Stage { public: - using Stage::Stage; + /** + * Constructor. + * @param The next stage in the pipeline. + * @return A newly allocated WB object. + */ + WB(Stage *next); Response advance(InstrDTO &i) override; }; diff --git a/src/sim/controller.cc b/src/sim/controller.cc index 6d46dc4..45aa9a0 100644 --- a/src/sim/controller.cc +++ b/src/sim/controller.cc @@ -10,6 +10,8 @@ Controller::Controller(Stage *stage, Storage *storage, bool is_pipelined) this->is_pipelined = is_pipelined; this->pc = 0x0; this->gprs = {0}; + // grant side-door access + this->id = SIDE; } void Controller::run_for(int number) @@ -30,7 +32,7 @@ int Controller::get_pc() { return this->pc; } Response Controller::advance(InstrDTO &i) { Response r; - + r = this->next->advance(i); ++this->clock_cycle; return r; diff --git a/src/sim/ex.cc b/src/sim/ex.cc index 1de61d0..46f5417 100644 --- a/src/sim/ex.cc +++ b/src/sim/ex.cc @@ -1,12 +1,9 @@ #include "ex.h" +#include "accessor.h" #include "instrDTO.h" -#include "logger.h" #include "response.h" +#include "stage.h" -static Logger *global_log = Logger::getInstance(); +EX::EX(Stage *stage) : Stage(stage) { this->id = EXEC; } -Response EX::advance(InstrDTO &i) -{ - global_log->log(INFO, "hello from execute!"); - return OK; -} +Response EX::advance(InstrDTO &i) { return OK; } diff --git a/src/sim/id.cc b/src/sim/id.cc index df55fe2..87dce0c 100644 --- a/src/sim/id.cc +++ b/src/sim/id.cc @@ -1,12 +1,9 @@ #include "id.h" +#include "accessor.h" #include "instrDTO.h" -#include "logger.h" #include "response.h" +#include "stage.h" -static Logger *global_log = Logger::getInstance(); +ID::ID(Stage *stage) : Stage(stage) { this->id = DCDE; } -Response ID::advance(InstrDTO &i) -{ - global_log->log(INFO, "hello from decode!"); - return OK; -} +Response ID::advance(InstrDTO &i) { return OK; } diff --git a/src/sim/if.cc b/src/sim/if.cc index deed8e1..f5a2bb9 100644 --- a/src/sim/if.cc +++ b/src/sim/if.cc @@ -2,6 +2,9 @@ #include "accessor.h" #include "instrDTO.h" #include "response.h" +#include "stage.h" + +IF::IF(Stage *stage) : Stage(stage) { this->id = FETCH; } Response IF::advance(InstrDTO &i) { diff --git a/src/sim/instr.cc b/src/sim/instr.cc new file mode 100644 index 0000000..608b871 --- /dev/null +++ b/src/sim/instr.cc @@ -0,0 +1,30 @@ +#include "instr.h" +#include <functional> +#include <map> + +// clang-format off +#define INIT_INSTRUCTION(type, opcode, body) \ + {type, {{opcode, [](signed int &s1, signed int &s2, signed int &s3) { \ + body; \ + }}}} +// clang-format on + +namespace instr +{ +// clang-format off +const std::map<int, std::map<int, std::function<void(signed int &s1, signed int &s2, signed int &s3)>>> + // clang-format on + instr_map = { + + /* R type instructions */ + // TODO these need to be WRAPPED with a function that sets overflow. + // future note to self, if these are more than 2 lines each, you're + // doing it wrong + INIT_INSTRUCTION(0b00, 0b00001, s3 = s1 + s2), + INIT_INSTRUCTION(0b00, 0b00010, s3 = s1 - s2), + + /* I type instructions */ + + /* J type instructions */ +}; +} // namespace instr diff --git a/src/sim/instrDTO.cc b/src/sim/instrDTO.cc index 6427b1a..4e24d4e 100644 --- a/src/sim/instrDTO.cc +++ b/src/sim/instrDTO.cc @@ -3,13 +3,33 @@ InstrDTO::InstrDTO() { this->if_cycle = 0; + this->id_cycle = 0; this->instr_bits = 0; + this->s1 = 0; + this->s2 = 0; + this->s3 = 0; } int InstrDTO::get_if_cycle() { return this->if_cycle; } +int InstrDTO::get_id_cycle() { return this->id_cycle; } + signed int InstrDTO::get_instr_bits() { return this->instr_bits; } +signed int InstrDTO::get_s1() { return this->s1; } + +signed int InstrDTO::get_s2() { return this->s2; } + +signed int InstrDTO::get_s3() { return this->s3; } + void InstrDTO::set_if_cycle(int cycle) { this->if_cycle = cycle; } +void InstrDTO::set_id_cycle(int cycle) { this->id_cycle = cycle; } + void InstrDTO::set_instr_bits(signed int instr) { this->instr_bits = instr; } + +void InstrDTO::set_s1(signed int s) { this->s1 = s; } + +void InstrDTO::set_s2(signed int s) { this->s2 = s; } + +void InstrDTO::set_s3(signed int s) { this->s3 = s; } diff --git a/src/sim/mm.cc b/src/sim/mm.cc index 28243e7..c5357f9 100644 --- a/src/sim/mm.cc +++ b/src/sim/mm.cc @@ -1,12 +1,12 @@ #include "mm.h" -#include "logger.h" -#include "response.h" +#include "accessor.h" #include "instrDTO.h" +#include "response.h" +#include "stage.h" -static Logger *global_log = Logger::getInstance(); +MM::MM(Stage *stage) : Stage(stage) { this->id = MEM; } Response MM::advance(InstrDTO &i) { - global_log->log(INFO, "hello from memory!"); return OK; } diff --git a/src/sim/stage.cc b/src/sim/stage.cc index 0d48774..6599298 100644 --- a/src/sim/stage.cc +++ b/src/sim/stage.cc @@ -5,7 +5,7 @@ Stage::Stage(Stage *next) { } std::array<int, GPR_NUM> Stage::gprs; -int Stage::pc; +unsigned int Stage::pc; Storage *Stage::storage; bool Stage::is_pipelined; int Stage::clock_cycle; diff --git a/src/sim/wb.cc b/src/sim/wb.cc index 9585fd3..218ed9a 100644 --- a/src/sim/wb.cc +++ b/src/sim/wb.cc @@ -1,12 +1,9 @@ #include "wb.h" +#include "accessor.h" #include "instrDTO.h" -#include "logger.h" #include "response.h" +#include "stage.h" -static Logger *global_log = Logger::getInstance(); +WB::WB(Stage *stage) : Stage(stage) { this->id = WRITE; } -Response WB::advance(InstrDTO &i) -{ - global_log->log(INFO, "hello from write back!"); - return OK; -} +Response WB::advance(InstrDTO &i) { return OK; } diff --git a/src/utils/accessor.cc b/src/utils/accessor.cc index 86484c5..99347ed 100644 --- a/src/utils/accessor.cc +++ b/src/utils/accessor.cc @@ -3,6 +3,8 @@ std::ostream &operator<<(std::ostream &os, Accessor a) { - const std::string nameA[] = {"IDLE", "MEM", "FETCH", "L1CACHE", "SIDE"}; + const std::string nameA[] = { + "IDLE", "WRITE", "MEM", "EXEC", "DCDE", "FETCH", "L1CACHE", "SIDE", + }; return os << nameA[a]; } |