diff options
Diffstat (limited to 'src/sim')
-rw-r--r-- | src/sim/controller.cc | 71 | ||||
-rw-r--r-- | src/sim/dum.cc | 44 | ||||
-rw-r--r-- | src/sim/ex.cc | 454 | ||||
-rw-r--r-- | src/sim/id.cc | 231 | ||||
-rw-r--r-- | src/sim/if.cc | 68 | ||||
-rw-r--r-- | src/sim/instr.cc | 40 | ||||
-rw-r--r-- | src/sim/instrDTO.cc | 71 | ||||
-rw-r--r-- | src/sim/mm.cc | 63 | ||||
-rw-r--r-- | src/sim/stage.cc | 136 | ||||
-rw-r--r-- | src/sim/wb.cc | 78 |
10 files changed, 0 insertions, 1256 deletions
diff --git a/src/sim/controller.cc b/src/sim/controller.cc deleted file mode 100644 index 59fbbb7..0000000 --- a/src/sim/controller.cc +++ /dev/null @@ -1,71 +0,0 @@ -// 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 <https://www.gnu.org/licenses/>. - -#include "controller.h" -#include "ex.h" -#include "response.h" -#include "storage.h" - -Controller::Controller(Stage *stage, Storage *storage, bool is_pipelined) - : Stage(stage) -{ - this->clock_cycle = 1; - this->storage = storage; - this->is_pipelined = is_pipelined; - this->is_empty = true; - this->pc = 0x0; - this->checked_out = {}; - this->gprs = {0}; - this->gprs.at(2) = MEM_WORDS; // set the stack pointer - // grant side-door access - this->id = SIDE; -} - -void Controller::run_for(int number) -{ - int i; - for (i = 0; i < number; ++i) { - try { - this->advance(WAIT); - } catch (HaltException &e) { - break; - } - } -} - -int Controller::get_clock_cycle() { return this->clock_cycle; } - -std::array<int, GPR_NUM> Controller::get_gprs() { return this->gprs; } - -int Controller::get_pc() { return this->pc; } - -InstrDTO *Controller::advance(Response p) -{ - InstrDTO *r; - r = this->next->advance(p); - ++this->clock_cycle; - - if (r) - this->is_empty = true; - - return r; -} - -void Controller::advance_helper() -{ - // TODO: check halt condition and call UI to refresh -} diff --git a/src/sim/dum.cc b/src/sim/dum.cc deleted file mode 100644 index 744c110..0000000 --- a/src/sim/dum.cc +++ /dev/null @@ -1,44 +0,0 @@ -// 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 <https://www.gnu.org/licenses/>. - -#include "dum.h" -#include "accessor.h" -#include "instrDTO.h" -#include "response.h" -#include "stage.h" - -DUM::DUM(Stage *stage) : Stage(stage) { this->id = IDLE; } - -InstrDTO *DUM::advance(Response p) -{ - InstrDTO *r = nullptr; - - if (this->curr_instr && p == WAIT) { - r = new InstrDTO(*this->curr_instr); - delete this->curr_instr; - curr_instr = nullptr; - } - - return r; -} - -void DUM::advance_helper() {} - -void DUM::set_curr_instr(InstrDTO *d) -{ - this->curr_instr = d; -} diff --git a/src/sim/ex.cc b/src/sim/ex.cc deleted file mode 100644 index d345ecf..0000000 --- a/src/sim/ex.cc +++ /dev/null @@ -1,454 +0,0 @@ -// 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 <https://www.gnu.org/licenses/>. - -#include "ex.h" -#include "accessor.h" -#include "instrDTO.h" -#include "pipe_spec.h" -#include "response.h" -#include "stage.h" -#include <unordered_map> - -// clang-format off -#define INIT_INSTRUCTION(mnemonic, body) \ - {mnemonic, [this](signed int &s1, signed int s2, signed int s3, unsigned int pc) { \ - body; \ - }} -// clang-format on - -EX::EX(Stage *stage) : Stage(stage) -{ - this->id = EXEC; - instr_map = { - - /* R type instructions */ - INIT_INSTRUCTION( - ADD, - { - this->set_condition(OF, ADDITION_OF_GUARD(s1, s2)); - this->set_condition(UF, ADDITION_UF_GUARD(s1, s2)); - s1 = s1 + s2; - (void)pc; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - SUB, - { - this->set_condition(OF, SUBTRACTION_OF_GUARD(s1, s2)); - this->set_condition(UF, SUBTRACTION_UF_GUARD(s1, s2)); - s1 = s1 - s2; - (void)pc; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - MUL, - { - this->set_condition(OF, MULTIPLICATION_OF_GUARD(s1, s2)); - this->set_condition(UF, MULTIPLICATION_UF_GUARD(s1, s2)); - s1 = s1 * s2; - (void)pc; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - QUOT, - { - this->handle_divide(s1, s2, false); - (void)pc; - (void)s3; - }), - - INIT_INSTRUCTION( - REM, - { - this->handle_divide(s1, s2, true); - (void)pc; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - SFTR, - { - s1 = s1 >> s2; - (void)pc; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - SFTL, - { - s1 = s1 << s2; - (void)pc; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - AND, - { - this->set_condition(OF, false); - this->set_condition(UF, false); - s1 = s1 & s2; - (void)pc; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - OR, - { - this->set_condition(OF, false); - this->set_condition(UF, false); - s1 = s1 | s2; - (void)pc; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - NOT, - { - this->set_condition(OF, false); - this->set_condition(UF, false); - s1 = ~s1; - (void)pc; - (void)s3; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - XOR, - { - this->set_condition(OF, false); - this->set_condition(UF, false); - s1 = s1 ^ s2; - (void)pc; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - ADDV, - { - (void)pc; - (void)s3; - (void)s2; - (void)s1; - (void)this; - }), - - INIT_INSTRUCTION( - SUBV, - { - (void)pc; - (void)s3; - (void)s2; - (void)s1; - (void)this; - }), - - INIT_INSTRUCTION( - MULV, - { - (void)pc; - (void)s3; - (void)s2; - (void)s1; - (void)this; - }), - - INIT_INSTRUCTION( - DIVV, - { - (void)pc; - (void)s3; - (void)s2; - (void)s1; - (void)this; - }), - - INIT_INSTRUCTION( - CMP, - { - (s1 > s2) ? this->set_condition(GT, true) - : this->set_condition(GT, false); - (s1 == s2) ? this->set_condition(EQ, true) - : this->set_condition(EQ, false); - (void)pc; - (void)s3; - }), - - INIT_INSTRUCTION( - CEV, - { - (void)pc; - (void)s3; - (void)s2; - (void)s1; - (void)this; - }), - - /* I type instructions */ - INIT_INSTRUCTION( - LOAD, - { - s1 = s1 + s3; - (void)pc; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - LOADV, - { - (void)pc; - (void)s3; - (void)s2; - (void)s1; - (void)this; - }), - - INIT_INSTRUCTION( - ADDI, - { - this->set_condition(OF, ADDITION_OF_GUARD(s1, s3)); - this->set_condition(UF, ADDITION_UF_GUARD(s1, s3)); - s1 = s1 + s3; - (void)pc; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - SUBI, - { - this->set_condition(OF, SUBTRACTION_OF_GUARD(s1, s3)); - this->set_condition(UF, SUBTRACTION_UF_GUARD(s1, s3)); - s1 = s1 - s3; - (void)pc; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - SFTRI, - { - s1 = s1 >> s3; - (void)pc; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - SFTLI, - { - s1 = s1 << s3; - (void)pc; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - ANDI, - { - this->set_condition(OF, false); - this->set_condition(UF, false); - s1 = s1 & s3; - (void)pc; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - ORI, - { - this->set_condition(OF, false); - this->set_condition(UF, false); - s1 = s1 | s3; - (void)pc; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - XORI, - { - this->set_condition(OF, false); - this->set_condition(UF, false); - s1 = s1 ^ s3; - (void)pc; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - STORE, - { - s1 = s1 + s3; - (void)pc; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - STOREV, - { - (void)pc; - (void)s3; - (void)s2; - (void)s1; - (void)this; - }), - - /* J type instructions */ - INIT_INSTRUCTION( - JMP, - { - s1 = s1 + s2; - (void)pc; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - JRL, - { - s1 = pc + s2; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - JAL, - { - s1 = s1 + s2; - (void)pc; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - BEQ, - { - (this->get_condition(EQ)) ? s1 = pc + s2 : s1 = -1; - (void)s3; - }), - - INIT_INSTRUCTION( - BGT, - { - (this->get_condition(GT)) ? s1 = pc + s2 : s1 = -1; - (void)s3; - }), - - INIT_INSTRUCTION( - BUF, - { - (this->get_condition(UF)) ? s1 = pc + s2 : s1 = -1; - (void)s3; - }), - - INIT_INSTRUCTION( - BOF, - { - (this->get_condition(OF)) ? s1 = pc + s2 : s1 = -1; - (void)s3; - }), - - INIT_INSTRUCTION( - PUSH, - { - s1 = s1 + s3; - (void)pc; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - POP, - { - s1 = s1 + s3; - (void)pc; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - RET, - { - (void)pc; - (void)s3; - (void)s2; - (void)s1; - (void)this; - }), - - /* NOP */ - INIT_INSTRUCTION( - NOP, - { - (void)pc; - (void)s3; - (void)s2; - (void)s1; - (void)this; - }), - }; -} - -void EX::advance_helper() -{ - signed int s1, s2, s3; - unsigned int pc; - Mnemonic m; - - m = this->curr_instr->get_mnemonic(); - s1 = this->curr_instr->get_s1(); - s2 = this->curr_instr->get_s2(); - s3 = this->curr_instr->get_s3(); - pc = this->curr_instr->get_pc(); - - this->instr_map[m](s1, s2, s3, pc); - - this->curr_instr->set_s1(s1); - this->status = OK; -} - -void EX::handle_divide(signed int &s1, signed int s2, bool is_mod) -{ - this->set_condition(OF, DIVISION_OF_GUARD(s1, s2)); - this->set_condition(UF, false); - if (s2 == 0) { - // handle everything here - this->curr_instr->set_s1(MAX_INT); - this->status = OK; - throw HaltException(); - } else if ((s1 == -(MAX_INT)-1) && s2 == -1) { - // undefined in C++ - s1 = -(MAX_INT)-1; - } else { - s1 = (is_mod) ? (s1 % s2) : (s1 / s2); - } -} diff --git a/src/sim/id.cc b/src/sim/id.cc deleted file mode 100644 index cdbaba9..0000000 --- a/src/sim/id.cc +++ /dev/null @@ -1,231 +0,0 @@ -// 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 <https://www.gnu.org/licenses/>. - -#include "id.h" -#include "accessor.h" -#include "instr.h" -#include "instrDTO.h" -#include "logger.h" -#include "response.h" -#include "stage.h" - -ID::ID(Stage *stage) : Stage(stage) { this->id = DCDE; } - -void ID::split_instr(signed int &raw, unsigned int &type, Mnemonic &m) -{ - unsigned int opcode, opcode_size; - - type = GET_LS_BITS(raw, TYPE_SIZE); - opcode_size = (type == 0b0) ? R_OPCODE_SIZE : OPCODE_SIZE; - opcode = GET_MID_BITS(raw, TYPE_SIZE, TYPE_SIZE + opcode_size); - try { - m = instr::mnemonic_map.at((opcode << TYPE_SIZE) + type); - } catch (std::out_of_range const &) { - m = NOP; - } - - raw = (unsigned int)raw >> (TYPE_SIZE + opcode_size); -} - -Response ID::read_guard(signed int &v) -{ - Response r; - if (this->is_checked_out(v)) - r = STALLED; - else { - r = OK; - v = this->dereference_register(v); - } - return r; -} - -void ID::write_guard(signed int &v) -{ - // zero register shouldn't be written. - if (v != 0) { - // 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->set_checked_out(v); - } - v = this->dereference_register(v); -} - -void ID::advance_helper() -{ - signed int s1, s2, s3; - Mnemonic m; - Type t; - - if (curr_instr->get_mnemonic() == NOP) - this->status = OK; - else { - s1 = curr_instr->get_instr_bits(); - get_instr_fields(s1, s2, s3, m, t); - if (this->status == OK) { - curr_instr->set_s1(s1); - curr_instr->set_s2(s2); - curr_instr->set_s3(s3); - curr_instr->set_mnemonic(m); - curr_instr->set_type(t); - } - } -} - -void ID::get_instr_fields( - signed int &s1, signed int &s2, signed int &s3, Mnemonic &m, Type &t) -{ - unsigned int type; - this->split_instr(s1, type, m); - - switch (type) { - case 0b00: - t = R; - this->decode_R_type(s1, s2, s3, m); - break; - case 0b01: - t = I; - this->decode_I_type(s1, s2, s3, m); - break; - case 0b10: - t = J; - this->decode_J_type(s1, s2, s3, m); - break; - case 0b11: - t = INV; - this->status = OK; - } -} - -void ID::decode_R_type( - signed int &s1, signed int &s2, signed int &s3, Mnemonic &m) -{ - 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->status = (r1 == OK && r2 == OK) ? OK : STALLED; - - switch (m) { - case CMP: - case CEV: - break; - default: - if (this->status == OK) - this->write_guard(s3); - } -} - -void ID::decode_I_type( - signed int &s1, signed int &s2, signed int &s3, Mnemonic &m) -{ - unsigned int s0b, s1b, s2b; - Response r1, r2; - - s0b = REG_SIZE; - s1b = s0b + REG_SIZE; - s2b = WORD_SPEC - LINE_SPEC - OPCODE_SIZE; - s3 = GET_BITS_SIGN_EXTEND(s1, s1b, s2b); - - switch (m) { - case STORE: - case STOREV: - s2 = GET_MID_BITS(s1, s0b, s1b); - s1 = GET_LS_BITS(s1, s0b); - - // both operands are read values - r1 = this->read_guard(s1); - r2 = this->read_guard(s2); - this->status = (r1 == OK && r2 == OK) ? OK : STALLED; - return; - case LOAD: - case LOADV: - s2 = GET_LS_BITS(s1, s0b); - s1 = GET_MID_BITS(s1, s0b, s1b); - break; - default: - s2 = GET_MID_BITS(s1, s0b, s1b); - s1 = GET_LS_BITS(s1, s0b); - } - - r1 = this->read_guard(s1); - if (r1 == OK) - this->write_guard(s2); - this->status = r1; -} - -void ID::decode_J_type( - signed int &s1, signed int &s2, signed int &s3, Mnemonic &m) -{ - Response r1, r2; - unsigned int s0b, s1b; - - s0b = REG_SIZE; - s1b = WORD_SPEC - LINE_SPEC - OPCODE_SIZE; - s3 = 0; - s2 = GET_BITS_SIGN_EXTEND(s1, s0b, s1b); - s1 = GET_LS_BITS(s1, s0b); - - switch (m) { - case PUSH: - s2 = s1; // source - s3 = 2; // stack pointer - s1 = -1; // increment amount - r1 = this->read_guard(s2); - r2 = (this->is_checked_out(s3)) ? STALLED : OK; // we read the stack pointer - if (r1 == OK && r2 == OK) { - this->write_guard(s3); // we write the stack pointer - } - this->status = (r1 == OK && r2 == OK) ? OK : STALLED; - break; - case POP: - s2 = s1; // destination - s3 = 2; // stack pointer - s1 = 1; // increment amount - r1 = (this->is_checked_out(s3)) ? STALLED : OK; // we read the stack pointer - if (r1 == OK) { - this->write_guard(s2); - this->write_guard(s3); // we write the stack pointer - } - this->status = r1; - break; - case RET: - s1 = 1; // link register - [[fallthrough]]; - default: - this->status = this->read_guard(s1); - } - -} - -std::vector<int> ID::stage_info() -{ - std::vector<int> info; - if (this->curr_instr) { - info.push_back(this->curr_instr->is_squashed()); - info.push_back(this->curr_instr->get_instr_bits()); - } - return info; -} diff --git a/src/sim/if.cc b/src/sim/if.cc deleted file mode 100644 index e8e7272..0000000 --- a/src/sim/if.cc +++ /dev/null @@ -1,68 +0,0 @@ -// 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 <https://www.gnu.org/licenses/>. - -#include "if.h" -#include "accessor.h" -#include "instrDTO.h" -#include "response.h" -#include "stage.h" - -IF::IF(Stage *stage) : Stage(stage) { this->id = FETCH; } - -InstrDTO *IF::advance(Response p) -{ - InstrDTO *r = nullptr; - - this->advance_helper(); - if (this->curr_instr != nullptr && p == WAIT) { - // don't increment PC if the PC was just set by wb - if (this->curr_instr->is_squashed() != 1) - ++this->pc; - r = new InstrDTO(*this->curr_instr); - delete curr_instr; - curr_instr = nullptr; - } - - return r; -} - -std::vector<int> IF::stage_info() { - std::vector<int> info; - if(this->curr_instr){ - info.push_back(this->curr_instr->is_squashed()); - info.push_back(this->curr_instr->get_instr_bits()); - } - return info; -} - -void IF::advance_helper() -{ - Response r; - int i; - signed int bits; - - if (this->curr_instr == nullptr && (this->is_pipelined || this->is_empty)) { - i = this->storage->read_word(this, this->pc, bits); - r = i ? OK : STALLED; - if (r == OK) { - this->curr_instr = new InstrDTO(); - this->curr_instr->set_instr_bits(bits); - this->curr_instr->set_pc(this->pc); - this->is_empty = false; - } - } -} diff --git a/src/sim/instr.cc b/src/sim/instr.cc deleted file mode 100644 index 9bd951b..0000000 --- a/src/sim/instr.cc +++ /dev/null @@ -1,40 +0,0 @@ -// 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 <https://www.gnu.org/licenses/>. - -#include "instr.h" -#include <functional> -#include <map> -#include <unordered_map> - -namespace instr -{ -const std::unordered_map<unsigned int, Mnemonic> mnemonic_map = { - {0b0000100, ADD}, {0b0001000, SUB}, {0b0001100, MUL}, - {0b0010000, QUOT}, {0b0010100, REM}, {0b0011000, SFTR}, - {0b0011100, SFTL}, {0b0100000, AND}, {0b0100100, OR}, - {0b0101000, NOT}, {0b0101100, XOR}, {0b0110000, ADDV}, - {0b0110100, SUBV}, {0b0111000, MULV}, {0b0111100, DIVV}, - {0b1000000, CMP}, {0b1000100, CEV}, {0b000101, LOAD}, - {0b001001, LOADV}, {0b0001101, ADDI}, {0b0010001, SUBI}, - {0b0010101, SFTRI}, {0b0011001, SFTLI}, {0b0011101, ANDI}, - {0b0100001, ORI}, {0b0100101, XORI}, {0b0101001, STORE}, - {0b0101101, STOREV}, {0b0000110, JMP}, {0b0001010, JRL}, - {0b0001110, JAL}, {0b0010010, BEQ}, {0b0010110, BGT}, - {0b0011010, BUF}, {0b0011110, BOF}, {0b0100010, PUSH}, - {0b0100110, POP}, {0b0101010, RET}, -}; -} // namespace instr diff --git a/src/sim/instrDTO.cc b/src/sim/instrDTO.cc deleted file mode 100644 index 00b6d5f..0000000 --- a/src/sim/instrDTO.cc +++ /dev/null @@ -1,71 +0,0 @@ -// 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 <https://www.gnu.org/licenses/>. - -#include "instrDTO.h" -#include "accessor.h" - -InstrDTO::InstrDTO() -{ - this->instr_bits = 0; - this->checked_out = -1; - this->s1 = 0; - this->s2 = 0; - this->s3 = 0; - this->mnemonic = ADD; - this->type = INV; - this->pc = 0; - this->squashed = 0; -} - -signed int InstrDTO::get_instr_bits() { return this->instr_bits; } - -signed int InstrDTO::get_checked_out() { return this->checked_out; } - -signed int InstrDTO::get_s1() { return this->s1; } - -signed int InstrDTO::get_s2() { return this->s2; } - -signed int InstrDTO::get_s3() { return this->s3; } - -Mnemonic InstrDTO::get_mnemonic() { return this->mnemonic; } - -Type InstrDTO::get_type() { return this->type; } - -unsigned int InstrDTO::get_pc() { return this->pc; } - -int InstrDTO::is_squashed() { return this->squashed; } - -void InstrDTO::set_instr_bits(signed int instr) { this->instr_bits = instr; } - -void InstrDTO::set_checked_out(signed int checked_out) -{ - this->checked_out = checked_out; -} - -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; } - -void InstrDTO::set_mnemonic(Mnemonic m) { this->mnemonic = m; } - -void InstrDTO::set_type(Type t) { this->type = t; } - -void InstrDTO::set_pc(unsigned int pc) { this->pc = pc; } - -void InstrDTO::squash() { this->squashed = 1; } diff --git a/src/sim/mm.cc b/src/sim/mm.cc deleted file mode 100644 index e1057d5..0000000 --- a/src/sim/mm.cc +++ /dev/null @@ -1,63 +0,0 @@ -// 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 <https://www.gnu.org/licenses/>. - -#include "mm.h" -#include "accessor.h" -#include "instrDTO.h" -#include "response.h" -#include "stage.h" - -MM::MM(Stage *stage) : Stage(stage) { this->id = MEM; } - -void MM::advance_helper() -{ - signed int data; - int i; - - switch (this->curr_instr->get_mnemonic()) { - case LOAD: - i = this->storage->read_word(this, this->curr_instr->get_s1(), data); - this->status = i ? OK : STALLED; - if (this->status == OK) { - this->curr_instr->set_s1(data); - } else - this->status = STALLED; - break; - - case PUSH: - case STORE: - i = this->storage->write_word( - this, this->curr_instr->get_s2(), this->curr_instr->get_s1()); - this->status = i ? OK : STALLED; - if (this->status != OK) { - this->status = STALLED; - } - break; - - case POP: - i = this->storage->read_word(this, this->curr_instr->get_s3(), data); - this->status = i ? OK : STALLED; - if (this->status == OK) { - this->curr_instr->set_s3(data); - } else - this->status = STALLED; - break; - - default: - this->status = OK; - } -} diff --git a/src/sim/stage.cc b/src/sim/stage.cc deleted file mode 100644 index 35c6936..0000000 --- a/src/sim/stage.cc +++ /dev/null @@ -1,136 +0,0 @@ -// 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 <https://www.gnu.org/licenses/>. - -#include "stage.h" -#include <array> -#include <deque> - -Stage::Stage(Stage *next) -{ - this->next = next; - this->curr_instr = nullptr; - this->status = WAIT; -} - -Stage::~Stage() { delete this->next; }; - -std::array<int, GPR_NUM> Stage::gprs; -std::array<int, V_NUM> Stage::vrs; -std::deque<signed int> Stage::checked_out; -unsigned int Stage::pc; -Storage *Stage::storage; -bool Stage::is_pipelined; -bool Stage::is_empty; -int Stage::clock_cycle; - -bool Stage::get_condition(CC c) { return (this->gprs[3] >> c) & 1; } - -InstrDTO *Stage::advance(Response p) -{ - InstrDTO *r = nullptr; - InstrDTO *s = nullptr; - Response n; - - // std::cout << "advance: " << this->id << ": " << this->curr_instr << "?: " - // << p << ": " << this->checked_out.size() << ": "; if (curr_instr) - // std::cout << curr_instr->get_mnemonic(); - // for (long unsigned int i = 0; i < this->checked_out.size(); ++i) - // std::cout << this->checked_out[i] << " "; - // std::cout << std::endl; - if (this->curr_instr && this->curr_instr->is_squashed() == 1) - this->status = OK; - if (this->curr_instr && this->status != OK) { - this->advance_helper(); - } - if (this->status == OK && p == WAIT && this->curr_instr) { - // mutual consent - r = new InstrDTO(*this->curr_instr); - delete curr_instr; - curr_instr = nullptr; - this->status = WAIT; - } - - n = (p != WAIT || this->status != WAIT) ? STALLED : WAIT; - s = this->next->advance(n); - if (s) - this->curr_instr = s; - return r; -} - -std::vector<int> Stage::stage_info() -{ - std::vector<int> info; - if (this->curr_instr) { - info.push_back(this->curr_instr->get_mnemonic()); - info.push_back(this->curr_instr->is_squashed()); - info.push_back(this->curr_instr->get_s1()); - info.push_back(this->curr_instr->get_s2()); - info.push_back(this->curr_instr->get_s3()); - } - return info; -} - -void Stage::set_condition(CC c, bool v) -{ - if (v) - this->gprs[3] = this->gprs[3] | 1 << c; - else - this->gprs[3] = this->gprs[3] & ~(1 << c); -} - -signed int Stage::dereference_register(signed int v) -{ - signed int r; - - if (v < 0 || v >= GPR_NUM + V_NUM) { - throw std::out_of_range( - "instruction tried to access register which does not exist"); - } - - r = (v >= GPR_NUM) ? this->vrs[v % GPR_NUM] : this->gprs[v]; - return r; -} - -void Stage::store_register(signed int v, signed int d) -{ - if (v < 0 || v >= GPR_NUM + V_NUM) { - throw std::out_of_range( - "instruction tried to access register which does not exist"); - } - - if (v >= GPR_NUM) - this->vrs[v % GPR_NUM] = d; - else - this->gprs[v] = d; -} - -bool Stage::is_checked_out(signed int r) -{ - return std::find(this->checked_out.begin(), this->checked_out.end(), r) != - this->checked_out.end(); -} - -void Stage::squash() -{ - if (curr_instr) { - this->curr_instr->squash(); - this->status = OK; - } - if (this->next) { - this->next->squash(); - } -} diff --git a/src/sim/wb.cc b/src/sim/wb.cc deleted file mode 100644 index 0348b51..0000000 --- a/src/sim/wb.cc +++ /dev/null @@ -1,78 +0,0 @@ -// 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 <https://www.gnu.org/licenses/>. - -#include "wb.h" -#include "accessor.h" -#include "instrDTO.h" -#include "response.h" -#include "stage.h" -#include <array> -#include <algorithm> - -WB::WB(Stage *stage) : Stage(stage) { this->id = WRITE; } - -void WB::advance_helper() -{ - if (this->curr_instr->get_mnemonic() != NOP && - this->curr_instr->get_type() != INV) { - if (this->curr_instr->get_checked_out() > 0) - this->write_handler(); - else if (this->should_jump()) - this->jump_handler(); - } - this->status = OK; -} - -void WB::write_handler() -{ - signed int reg; - - if (this->checked_out.size() < 1) - throw std::runtime_error("instruction tried to pop a register out of " - "an empty queue during writeback."); - - if (this->curr_instr->get_mnemonic() == POP) { - // POP performs a second register write - reg = this->checked_out.front(); - this->checked_out.pop_front(); - this->store_register(reg, this->curr_instr->get_s3()); - } - - this->checked_out.pop_front(); - reg = this->curr_instr->get_checked_out(); - this->store_register(reg, this->curr_instr->get_s1()); - -} - -void WB::jump_handler() -{ - if (this->curr_instr->get_s1() > 0) { - if (this->curr_instr->get_mnemonic() == JAL) - this->gprs[1] = this->curr_instr->get_pc() + 1;; - this->pc = this->curr_instr->get_s1(); - this->checked_out = {}; - this->next->squash(); - } -} - -bool WB::should_jump() -{ - Type t; - - t = this->curr_instr->get_type(); - return t == J; -} |