summaryrefslogtreecommitdiff
path: root/inc
diff options
context:
space:
mode:
authorSiddarth Suresh <155843085+SiddarthSuresh98@users.noreply.github.com>2025-03-29 22:14:42 -0400
committerGitHub <noreply@github.com>2025-03-29 22:14:42 -0400
commitd20623d031cf909d8892c2db38cf2e2e02bc6a9b (patch)
tree56ef4ae4325a5b803c484a3e5c8d87b89572cedf /inc
parentcaeff52f029920e027d18bc01149425560801f82 (diff)
parent1250c3765f59801d060152d5f6eed0a9faa11b50 (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.h3
-rw-r--r--inc/controller.h2
-rw-r--r--inc/definitions.h32
-rw-r--r--inc/ex.h9
-rw-r--r--inc/id.h78
-rw-r--r--inc/if.h18
-rw-r--r--inc/instr.h56
-rw-r--r--inc/instrDTO.h69
-rw-r--r--inc/mm.h9
-rw-r--r--inc/response.h1
-rw-r--r--inc/stage.h58
-rw-r--r--inc/storage.h2
-rw-r--r--inc/utils.h2
-rw-r--r--inc/wb.h9
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
diff --git a/inc/ex.h b/inc/ex.h
index f9b2f78..e67980d 100644
--- a/inc/ex.h
+++ b/inc/ex.h
@@ -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 */
diff --git a/inc/id.h b/inc/id.h
index de8f677..49637ce 100644
--- a/inc/id.h
+++ b/inc/id.h
@@ -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 */
diff --git a/inc/if.h b/inc/if.h
index 437fa8d..3fafe53 100644
--- a/inc/if.h
+++ b/inc/if.h
@@ -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 */
diff --git a/inc/mm.h b/inc/mm.h
index 5e2b029..0d2ce82 100644
--- a/inc/mm.h
+++ b/inc/mm.h
@@ -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.
diff --git a/inc/wb.h b/inc/wb.h
index b1d65f7..9a708a6 100644
--- a/inc/wb.h
+++ b/inc/wb.h
@@ -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 */