diff options
author | Siddarth Suresh <155843085+SiddarthSuresh98@users.noreply.github.com> | 2025-03-29 22:14:42 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-29 22:14:42 -0400 |
commit | d20623d031cf909d8892c2db38cf2e2e02bc6a9b (patch) | |
tree | 56ef4ae4325a5b803c484a3e5c8d87b89572cedf /inc | |
parent | caeff52f029920e027d18bc01149425560801f82 (diff) | |
parent | 1250c3765f59801d060152d5f6eed0a9faa11b50 (diff) |
Merge pull request #37 from bdunahu/bdunahu
Instr, InstrDTO gets/sets, other structures required for decode
-- tests as we move forward
-- base classes
-- decode stage implemented
Diffstat (limited to 'inc')
-rw-r--r-- | inc/accessor.h | 3 | ||||
-rw-r--r-- | inc/controller.h | 2 | ||||
-rw-r--r-- | inc/definitions.h | 32 | ||||
-rw-r--r-- | inc/ex.h | 9 | ||||
-rw-r--r-- | inc/id.h | 78 | ||||
-rw-r--r-- | inc/if.h | 18 | ||||
-rw-r--r-- | inc/instr.h | 56 | ||||
-rw-r--r-- | inc/instrDTO.h | 69 | ||||
-rw-r--r-- | inc/mm.h | 9 | ||||
-rw-r--r-- | inc/response.h | 1 | ||||
-rw-r--r-- | inc/stage.h | 58 | ||||
-rw-r--r-- | inc/storage.h | 2 | ||||
-rw-r--r-- | inc/utils.h | 2 | ||||
-rw-r--r-- | inc/wb.h | 9 |
14 files changed, 315 insertions, 33 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, diff --git a/inc/controller.h b/inc/controller.h index 4b102ce..ac83a78 100644 --- a/inc/controller.h +++ b/inc/controller.h @@ -36,7 +36,7 @@ class Controller : public Stage * @return the pc. */ int get_pc(); - Response advance(InstrDTO &i) override; + Response advance(InstrDTO &i, Response p) override; }; #endif /* CONTROLLER_H_INCLUDED */ diff --git a/inc/definitions.h b/inc/definitions.h index ff2f7c6..3238a8b 100644 --- a/inc/definitions.h +++ b/inc/definitions.h @@ -11,6 +11,10 @@ * The total number of words in a line */ #define LINE_SIZE static_cast<int>(pow(2, 2)) +/** + * Number of bits in a word + */ +#define WORD_SPEC 32 /** * The number of bits to specify a memory word @@ -28,7 +32,8 @@ * The total number of lines in l1 cache */ #define L1_CACHE_WORD_SPEC 7 -#define L1_CACHE_LINE_SPEC static_cast<unsigned int>(L1_CACHE_WORD_SPEC - LINE_SPEC) +#define L1_CACHE_LINE_SPEC \ + static_cast<unsigned int>(L1_CACHE_WORD_SPEC - LINE_SPEC) #define L1_CACHE_LINES static_cast<int>(pow(2, L1_CACHE_LINE_SPEC)) /** @@ -47,6 +52,31 @@ #define GPR_NUM 16 /** + * The number of vector registers + */ +#define V_NUM 8 + +/** + * The number of bits to specify an instruction type + */ +#define TYPE_SIZE 2 + +/** + * The number of bits to specify a register + */ +#define REG_SIZE 5 + +/** + * The number of bits to specify an R-Type opcode. + */ +#define R_OPCODE_SIZE 5 + +/** + * The number of bits to specify an opcode. + */ +#define OPCODE_SIZE 4 + +/** * Return the N least-significant bits from integer K using a bit mask * @param the integer to be parsed * @param the number of bits to be parsed @@ -7,9 +7,14 @@ 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; + Response advance(InstrDTO &next_instr, Response p) override; }; #endif /* EX_H_INCLUDED */ @@ -1,5 +1,6 @@ #ifndef ID_H #define ID_H +#include "instr.h" #include "instrDTO.h" #include "response.h" #include "stage.h" @@ -7,9 +8,80 @@ 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; + Response advance(InstrDTO &next_instr, Response p) override; + + /* The following methods are made public so that they may be tested, and are + * not to be called from outside classes during standard execution. + */ + + /** + * Parse an instruction into a type, opcode, and fields. If the type is + * invalid, only the type field will be set. + * + * This method is marked public so it may be tested, and is not used outside + * of this class during normal execution. + * + * @param the resulting first field, which varies per type. To call this + * function properly, this field must contain the full instruction bytes on + * function entry. + * @param the resulting second field, which varies per type. + * @param the resulting third field, which varies per type. + * @param the resulting mnemonic. + */ + void get_instr_fields( + signed int &s1, signed int &s2, signed int &s3, Mnemonic &m); + /** + * Facilitates register checkout and data hazard management. + * It does this by checking that the register passed in is not currently + * checked out. If true, then replaces r with the value of the register and + * returns OK. If false, returns STALLED. + * + * @param the registers number, to be dereferenced. + * @return OK if `r` is not checked out, STALLED otherwise. + */ + Response read_guard(signed int &r); + /** + * Facilitates register checkout and data hazard management. + * Checks out a register and returns it. + * + * @param the registers number, to be dereferenced and checked out. + */ + void write_guard(signed int &r); + + private: + /** + * Decodes `curr_instr` and sets status to BLOCKED if a data hazard occurs. + */ + void advance_helper(); + /** + * Helper for `get_instr_fields` + * Attempts to parse and dereference instruction arguments. Uses read and + * write guards to prevent RAW conflicts. + * + * @param the resulting first field. To call this function properly, this + * field must contain the section of the instruction to be parsed. + * @param the resulting second field. + * @param the resulting third field. + */ + void decode_R_type(signed int &s1, signed int &s2, signed int &s3); + void decode_I_type(signed int &s1, signed int &s2, signed int &s3); + void decode_J_type(signed int &s1, signed int &s2); + /** + * Helper for `get_instr_fields`. + * Given a raw instruction, returns the mnemonic and type. + * This operation will destroy the original arguments. + * @param the raw bits to parse. + * @param the resulting mnemonic. + * @param the resulting type. + */ + void split_instr(signed int &raw, unsigned int &type, Mnemonic &m); }; -#endif /* ID_D_INCLUDED */ +#endif /* ID_H_INCLUDED */ @@ -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,24 @@ class IF : public Stage { public: - using Stage::Stage; + /** + * Constructor. + * @param The next stage in the pipeline. + * @return A newly allocated IF object. + */ + IF(Stage *next); - Response advance(InstrDTO &i) override; + Response advance(InstrDTO &next_instr, Response p) override; private: /** - * The name this pipeline stages uses to access storage. + * Performs a fetch only if a current fetch is not pending. Pending means + * that a fetch has completed successfully, but the caller stage in the + * pipeline is not ready to receive it. In this case, `curr_instr` is not + * the nullptr. + * @return STALLED if we are waiting on the storage devices, OK otherwise. */ - const Accessor id = FETCH; + void advance_helper(); }; #endif /* IF_H_INCLUDED */ diff --git a/inc/instr.h b/inc/instr.h new file mode 100644 index 0000000..08b4fd0 --- /dev/null +++ b/inc/instr.h @@ -0,0 +1,56 @@ +#ifndef INSTR_H +#define INSTR_H +#include <functional> +#include <iostream> +#include <unordered_map> + +enum Mnemonic { + ADD, + SUB, + MUL, + QUOT, + REM, + SFTR, + SFTL, + AND, + OR, + NOT, + XOR, + ADDV, + SUBV, + MULV, + DIVV, + CMP, + CEV, + LOAD, + LOADV, + ADDI, + SUBI, + SFTRI, + SFTLI, + ANDI, + ORI, + XORI, + STORE, + STOREV, + JMP, + JRL, + JAL, + BEQ, + BGT, + BUF, + BOF, + PUSH, + POP, + NOP, +}; + +namespace instr +{ +// clang-format off + extern const std::unordered_map<unsigned int, Mnemonic> mnemonic_map; + extern const std::unordered_map<Mnemonic, 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..77a223e 100644 --- a/inc/instrDTO.h +++ b/inc/instrDTO.h @@ -1,5 +1,10 @@ #ifndef INSTRDTO_H #define INSTRDTO_H +#include "accessor.h" +#include "instr.h" +#include <functional> +#include <string> +#include <unordered_map> class InstrDTO { @@ -11,29 +16,81 @@ class InstrDTO ~InstrDTO() = default; /** - * @return if_cycle + * @return hist entry for Accessor */ - int get_if_cycle(); + int get_time_of(Accessor); + /** + * @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 mnemonic of the instruction + */ + Mnemonic get_mnemonic(); /** - * @param if_cycle + * @param set hist key */ - void set_if_cycle(int); + void set_time_of(Accessor, 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); + /** + * @param the mnemonic of the instruction + */ + void set_mnemonic(Mnemonic); private: /** - * The current clock cycle. + * The clock cycle each stage finished an operation. + */ + std::unordered_map<Accessor, int> hist; + /** + * The raw bits encoding the instruction. */ - int if_cycle; 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 mnemonic of the operation. + */ + Mnemonic mnemonic; }; #endif /* INSTRDTO_H_INCLUDED */ @@ -7,9 +7,14 @@ 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; + Response advance(InstrDTO &next_instr, Response p) override; }; #endif /* MM_H_INCLUDED */ diff --git a/inc/response.h b/inc/response.h index 6cd6678..05e9352 100644 --- a/inc/response.h +++ b/inc/response.h @@ -6,6 +6,7 @@ enum Response { OK, WAIT, BLOCKED, + STALLED, }; std::ostream &operator<<(std::ostream &os, Response r); diff --git a/inc/stage.h b/inc/stage.h index ac810a9..19e3896 100644 --- a/inc/stage.h +++ b/inc/stage.h @@ -1,10 +1,13 @@ #ifndef STAGE_H #define STAGE_H +#include "accessor.h" #include "definitions.h" #include "instrDTO.h" #include "response.h" #include "storage.h" #include <array> +#include <deque> +#include <memory> class Stage { @@ -15,29 +18,47 @@ class Stage * @return A newly allocated stage object. */ Stage(Stage *next); - virtual ~Stage() = default; + virtual ~Stage(); /** * Advances this stage by a single clock cycle. - * @param a DTO object containing various information about an instruction - * moving through the pipeline. - * @return a response, indicating whether this pipeline stage is stalled, + * @param a DTO object containing the next instruction to be processed. + * @param a response, indicating whether or not the parent pipe stage is + * ready to accept a new instruction object next cycle. + * @return a response, indicating whether this pipeline stage is stalling, * busy, or done. */ - virtual Response advance(InstrDTO &i) = 0; + virtual Response advance(InstrDTO &next_instr, Response p) = 0; protected: /** + * Helper for `check_out`. + * Returns true if r are not checked out, false otherwise. + * @param a list of register numbers. + * @return true if registers are not in checked_out, false otherwise. + */ + bool is_checked_out(signed int r); + /** + * Returns the value of the register corresponding to `v`. + * @param the register number. + * @return the value in the associated register. + */ + signed int dereference_register(signed int v); + /** + * 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. + * The shared pool of general-purpose vector registers. */ - static int pc; + static std::array<signed int, V_NUM> vrs; /** - * A pointer to the next stage in the pipeline. + * The address of the currently executing instruction. */ - Stage *next; + static unsigned int pc; /** * A pointer to the top-level storage device. */ @@ -50,6 +71,23 @@ class Stage * The current clock cycle. */ static int clock_cycle; + // TODO fix this comment after writeback stage + /** + * The set of registers currently checked out. + */ + static std::deque<signed int> checked_out; + /** + * A pointer to the next stage in the pipeline. + */ + Stage *next; + /** + * A pointer to the current instruction this stage is processing. + */ + std::unique_ptr<InstrDTO> curr_instr; + /** + * The current status of this stage. + */ + Response status; }; #endif /* STAGE_H_INCLUDED */ diff --git a/inc/storage.h b/inc/storage.h index ff1fbcb..d6fa094 100644 --- a/inc/storage.h +++ b/inc/storage.h @@ -80,7 +80,7 @@ class Storage /** * The accessor currently being serviced. */ - enum Accessor requester; + Accessor requester; /** * The number of cycles until the current request is completed. */ diff --git a/inc/utils.h b/inc/utils.h index df8d374..a375b68 100644 --- a/inc/utils.h +++ b/inc/utils.h @@ -10,7 +10,7 @@ * @param the resulting index * @param the resulting offset */ -void get_bit_fields(int address, int *tag, int *index, int *offset); +void get_cache_fields(int address, int *tag, int *index, int *offset); /** * Formats a string using snprintf. @@ -7,9 +7,14 @@ 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; + Response advance(InstrDTO &next_instr, Response p) override; }; #endif /* WB_H_INCLUDED */ |