// Simulator for the RISC-V[ECTOR] mini-ISA // Copyright (C) 2025 Siddarth Suresh // Copyright (C) 2025 bdunahu // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef ID_H #define ID_H #include "instr.h" #include "instrDTO.h" #include "response.h" #include "stage.h" class ID : public Stage { public: using Stage::advance; using Stage::Stage; /* The following methods are made public so that they may be tested, and are * not to be called from outside classes during standard execution. */ Response set_vlen(); private: /** * 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 advance_helper() override; /** * 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 instr_bits); void decode_R_type(signed int &s1); void decode_I_type(signed int &s1); void decode_J_type(signed int &s1); /** * 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); /** * Facilitates register checkout and data hazard management. * Checks out a register and returns it. * * @param the registers number, to be dereferenced and checked out. */ template T write_guard(int v) { T r; // these registers shouldn't be written. if (v != 0 && v != 16) { // keep track in the instrDTO for displaying to user and writeback // keep track in checked_out so we can still access this // information! this->checked_out.push_back(v); this->curr_instr->checked_out = v; } r = this->dereference_register(v); return r; } /** * 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 sets `result' with the value of the register * and returns OK. If false, returns STALLED. * * @param the registers number * @param the dereferenced register value * @return OK if `reg` is not checked out, STALLED otherwise. */ template Response read_guard(int reg, T &result) { Response response; if (this->is_checked_out(reg)) response = STALLED; else { response = OK; result = this->dereference_register(reg); } return response; } }; #endif /* ID_H_INCLUDED */