From 2c94ea91b1c5a0d7c0ebb0ab229950f7c849909a Mon Sep 17 00:00:00 2001 From: bd Date: Thu, 17 Apr 2025 15:30:26 -0400 Subject: The pipeline says some things and there are numbers --- gui/worker.cc | 66 +++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 29 deletions(-) (limited to 'gui/worker.cc') diff --git a/gui/worker.cc b/gui/worker.cc index 9202b89..061e0da 100644 --- a/gui/worker.cc +++ b/gui/worker.cc @@ -19,35 +19,43 @@ void Worker::doWork() emit cache_storage(this->c->view(0, 7)); emit register_storage(this->ct->get_gprs()); - signed int b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, - b15, b16, b17, b18, b19, b20; std::vector p; - // I-TYPE / / / / - b0 = 0b00000010000000000001000000001101; - b1 = 0b00000000000000010010100000001101; - b2 = 0b00000000000000000010100010101001; - b3 = 0b00000000000000100010100000001101; - b4 = 0b00000000000000010010100010101001; - b5 = 0b00000000000000110010100000001101; - b6 = 0b00000000000000100010100010101001; - b7 = 0b00000000000001000010100000001101; - b8 = 0b00000000000000110010100010101001; - b9 = 0b00000000000000000010100000001101; - b10 = 0b00000000000000110011000000001101; - b11 = 0b00000000000000000011100000001010; - b12 = 0b00000000000100100101000100000100; - b13 = 0b00000000000000000100100111000101; - b14 = 0b00000000000000010100101000000101; - b15 = 0b00000000000011101000001110000100; - b16 = 0b00000000000000000011101001101001; - b17 = 0b00000000000000010010100101001101; - b18 = 0b00000000000000000101001101000000; - b19 = 0b11111111111111111100100000010110; - // b20 = 0b00000000000000000000000000010000; - - p = {b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, - b11, b12, b13, b14, b15, b16, b17, b18, b19}; + p.push_back(0b00000000000000000010100010001101); + p.push_back(0b11111111111101010011000000001101); + p.push_back(0b00000000000000000000000110100010); + p.push_back(0b00000000000000000011000000001110); + p.push_back(0b00000000000000000000000110100110); + p.push_back(0b00000000001000100011000000101001); + p.push_back(0b00000000000000000000000101100010); + p.push_back(0b00000000000000000010100010001101); + p.push_back(0b00000000000001000001000010010001); + p.push_back(0b11111111111010010011000000001101); + p.push_back(0b11111111111111000011000101101001); + p.push_back(0b00000000000001000010100111000101); + p.push_back(0b11111111111111000010100110000101); + p.push_back(0b00000000000011000111001100000100); + p.push_back(0b00000000000000000000000110100010); + p.push_back(0b00000000000000001010100000001110); + p.push_back(0b00000000000000000000000110100110); + p.push_back(0b00000000000001000011000101101001); + p.push_back(0b00000000000000000001000101001101); + p.push_back(0b00000000000000000000000101100110); + p.push_back(0b00000000000000000000000000101010); + p.push_back(0b00000000000000000000000101100010); + p.push_back(0b00000000000000000010100010001101); + p.push_back(0b00000000000001000001000010010001); + p.push_back(0b00000000010011000011000000001101); + p.push_back(0b11111111111111000011000101101001); + p.push_back(0b00000000000001000010100111000101); + p.push_back(0b11111111111111000010100110000101); + p.push_back(0b00000000000011000111001100000100); + p.push_back(0b00000000000001000011000101101001); + p.push_back(0b00000000000000000001000101001101); + p.push_back(0b00000000000000000000000101100110); + p.push_back(0b00000000000000000000000000101010); + p.push_back(0b00000000000000000000000000010000); + p.push_back(0b00000000000000000000000000000000); this->d->load(p); } @@ -69,7 +77,7 @@ void Worker::refreshDram() void Worker::refreshCache() { qDebug() << "Refreshing Dram"; - emit cache_storage(this->c->view(0, 7)); + emit cache_storage(this->c->view(24, 31)); } void Worker::refreshRegisters() @@ -98,7 +106,7 @@ void Worker::runStep() qDebug() << "Running for 1 step "; this->ct->advance(WAIT); emit dram_storage(this->d->view(0, 256)); - emit cache_storage(this->c->view(0, 7)); + emit cache_storage(this->c->view(24, 8)); emit register_storage(this->ct->get_gprs()); emit clock_cycles(this->ct->get_clock_cycle(), this->ct->get_pc()); emit if_info(this->if_stage->stage_info()); -- cgit v1.2.3 From f6f2f32b6dbd1b1e60052cb67f40864c3b5bd74b Mon Sep 17 00:00:00 2001 From: bd Date: Thu, 17 Apr 2025 16:28:36 -0400 Subject: Functioning PUSH/POP --- gui/worker.cc | 76 +++++++++++++++++++++++++++++++++++------------------------ src/sim/ex.cc | 2 -- src/sim/id.cc | 2 -- src/sim/wb.cc | 9 +++---- 4 files changed, 50 insertions(+), 39 deletions(-) (limited to 'gui/worker.cc') diff --git a/gui/worker.cc b/gui/worker.cc index 061e0da..08503c9 100644 --- a/gui/worker.cc +++ b/gui/worker.cc @@ -21,41 +21,55 @@ void Worker::doWork() std::vector p; - p.push_back(0b00000000000000000010100010001101); - p.push_back(0b11111111111101010011000000001101); - p.push_back(0b00000000000000000000000110100010); - p.push_back(0b00000000000000000011000000001110); - p.push_back(0b00000000000000000000000110100110); - p.push_back(0b00000000001000100011000000101001); + p.push_back(0b00000000000000010010100000001101); p.push_back(0b00000000000000000000000101100010); - p.push_back(0b00000000000000000010100010001101); - p.push_back(0b00000000000001000001000010010001); - p.push_back(0b11111111111010010011000000001101); - p.push_back(0b11111111111111000011000101101001); - p.push_back(0b00000000000001000010100111000101); - p.push_back(0b11111111111111000010100110000101); - p.push_back(0b00000000000011000111001100000100); - p.push_back(0b00000000000000000000000110100010); - p.push_back(0b00000000000000001010100000001110); - p.push_back(0b00000000000000000000000110100110); - p.push_back(0b00000000000001000011000101101001); - p.push_back(0b00000000000000000001000101001101); - p.push_back(0b00000000000000000000000101100110); - p.push_back(0b00000000000000000000000000101010); + p.push_back(0b00000000000000010010100101001101); + p.push_back(0b00000000000000000000000101100010); + p.push_back(0b00000000000000010010100101001101); + p.push_back(0b00000000000000000000000101100010); + p.push_back(0b00000000000000010010100101001101); p.push_back(0b00000000000000000000000101100010); - p.push_back(0b00000000000000000010100010001101); - p.push_back(0b00000000000001000001000010010001); - p.push_back(0b00000000010011000011000000001101); - p.push_back(0b11111111111111000011000101101001); - p.push_back(0b00000000000001000010100111000101); - p.push_back(0b11111111111111000010100110000101); - p.push_back(0b00000000000011000111001100000100); - p.push_back(0b00000000000001000011000101101001); - p.push_back(0b00000000000000000001000101001101); p.push_back(0b00000000000000000000000101100110); - p.push_back(0b00000000000000000000000000101010); + p.push_back(0b00000000000000000000000110100110); + p.push_back(0b00000000000000000000000111100110); + p.push_back(0b00000000000000000000001000100110); p.push_back(0b00000000000000000000000000010000); - p.push_back(0b00000000000000000000000000000000); + + // p.push_back(0b00000000000000000010100010001101); + // p.push_back(0b11111111111101010011000000001101); + // p.push_back(0b00000000000000000000000110100010); + // p.push_back(0b00000000000000000011000000001110); + // p.push_back(0b00000000000000000000000110100110); + // p.push_back(0b00000000001000100011000000101001); + // p.push_back(0b00000000000000000000000101100010); + // p.push_back(0b00000000000000000010100010001101); + // p.push_back(0b00000000000000010001000010010001); + // p.push_back(0b11111111111010010011000000001101); + // p.push_back(0b11111111111111000011000101101001); + // p.push_back(0b00000000000001000010100111000101); + // p.push_back(0b11111111111111000010100110000101); + // p.push_back(0b00000000000011000111001100000100); + // p.push_back(0b00000000000000000000000110100010); + // p.push_back(0b00000000000000001010100000001110); + // p.push_back(0b00000000000000000000000110100110); + // p.push_back(0b00000000000001000011000101101001); + // p.push_back(0b00000000000000000001000101001101); + // p.push_back(0b00000000000000000000000101100110); + // p.push_back(0b00000000000000000000000000101010); + // p.push_back(0b00000000000000000000000101100010); + // p.push_back(0b00000000000000000010100010001101); + // p.push_back(0b00000000000000010001000010010001); + // p.push_back(0b00000000010011000011000000001101); + // p.push_back(0b11111111111111000011000101101001); + // p.push_back(0b00000000000001000010100111000101); + // p.push_back(0b11111111111111000010100110000101); + // p.push_back(0b00000000000011000111001100000100); + // p.push_back(0b00000000000001000011000101101001); + // p.push_back(0b00000000000000000001000101001101); + // p.push_back(0b00000000000000000000000101100110); + // p.push_back(0b00000000000000000000000000101010); + // p.push_back(0b00000000000000000000000000010000); + // p.push_back(0b00000000000000000000000000000000); this->d->load(p); } diff --git a/src/sim/ex.cc b/src/sim/ex.cc index c676781..a32105f 100644 --- a/src/sim/ex.cc +++ b/src/sim/ex.cc @@ -340,9 +340,7 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( PUSH, { - std::cout << "adding " << s1 << " and " << s3; s1 = s1 + s3; - std::cout << " for " << s1 << std::endl; (void)pc; (void)s2; (void)this; diff --git a/src/sim/id.cc b/src/sim/id.cc index de412d4..d10d695 100644 --- a/src/sim/id.cc +++ b/src/sim/id.cc @@ -198,8 +198,6 @@ void ID::decode_J_type( this->status = this->read_guard(*&s1); } - std::cout << m << ":" << this->status << std::endl; - } std::vector ID::stage_info() diff --git a/src/sim/wb.cc b/src/sim/wb.cc index 08e5ed3..c62468c 100644 --- a/src/sim/wb.cc +++ b/src/sim/wb.cc @@ -28,16 +28,17 @@ void WB::write_handler() throw std::runtime_error("instruction tried to pop a register out of " "an empty queue during writeback."); - this->checked_out.pop_front(); - reg = this->curr_instr->get_checked_out(); - this->store_register(reg, this->curr_instr->get_s1()); - 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() -- cgit v1.2.3 From c7c531ce16fe66bf9f3bcb04ea9294d50a41e348 Mon Sep 17 00:00:00 2001 From: bd Date: Thu, 17 Apr 2025 17:20:48 -0400 Subject: HALT instruction... but it voids future stages' instructions --- gui/worker.cc | 4 +++- inc/ex.h | 19 ++++++++++++++++++- src/sim/controller.cc | 7 ++++++- src/sim/ex.cc | 16 ++++++++++++++-- 4 files changed, 41 insertions(+), 5 deletions(-) (limited to 'gui/worker.cc') diff --git a/gui/worker.cc b/gui/worker.cc index 08503c9..defec46 100644 --- a/gui/worker.cc +++ b/gui/worker.cc @@ -33,6 +33,8 @@ void Worker::doWork() p.push_back(0b00000000000000000000000110100110); p.push_back(0b00000000000000000000000111100110); p.push_back(0b00000000000000000000001000100110); + p.push_back(0b00000000000000000000000000101110); + p.push_back(0b00000000000000000000000000101110); p.push_back(0b00000000000000000000000000010000); // p.push_back(0b00000000000000000010100010001101); @@ -118,7 +120,7 @@ void Worker::runSteps(int steps) void Worker::runStep() { qDebug() << "Running for 1 step "; - this->ct->advance(WAIT); + this->ct->run_for(1); emit dram_storage(this->d->view(0, 256)); emit cache_storage(this->c->view(24, 8)); emit register_storage(this->ct->get_gprs()); diff --git a/inc/ex.h b/inc/ex.h index e4c9d2b..f63539c 100644 --- a/inc/ex.h +++ b/inc/ex.h @@ -3,8 +3,16 @@ #include "instrDTO.h" #include "response.h" #include "stage.h" +#include #include +class HaltException : public std::exception +{ + const char *what() const noexcept override { + return ""; + } +}; + class EX : public Stage { public: @@ -18,6 +26,14 @@ class EX : public Stage private: void advance_helper(); + /** + * Wrapper for division functions, which detects HALT instructinos (division + * by 0). + * @param the numerator + * @param the denominator + * @param if the modulo operator should instead be used + */ + void handle_divide(signed int &s1, signed int s2, bool is_mod); /** * Maps each mnemonic to a function which carries out the instruction's base * logic. @@ -25,7 +41,8 @@ class EX : public Stage */ std::unordered_map< Mnemonic, - std::function> + std::function> instr_map; }; diff --git a/src/sim/controller.cc b/src/sim/controller.cc index 9256151..9ae6d16 100644 --- a/src/sim/controller.cc +++ b/src/sim/controller.cc @@ -1,4 +1,5 @@ #include "controller.h" +#include "ex.h" #include "response.h" #include "storage.h" @@ -20,7 +21,11 @@ void Controller::run_for(int number) { int i; for (i = 0; i < number; ++i) { - this->advance(WAIT); + try { + this->advance(WAIT); + } catch (HaltException &e) { + break; + } } } diff --git a/src/sim/ex.cc b/src/sim/ex.cc index a32105f..762e847 100644 --- a/src/sim/ex.cc +++ b/src/sim/ex.cc @@ -49,15 +49,15 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( QUOT, { - s1 = s1 / s2; + this->handle_divide(s1, s2, false); (void)pc; (void)s3; - (void)this; }), INIT_INSTRUCTION( REM, { + this->handle_divide(s1, s2, true); s1 = s1 % s2; (void)pc; (void)s3; @@ -385,3 +385,15 @@ void EX::advance_helper() this->curr_instr->set_s1(s1); this->status = OK; } + +void EX::handle_divide(signed int &s1, signed int s2, bool is_mod) +{ + if (s2 == 0) { + // handle everything here + this->curr_instr->set_s1(MAX_INT); + this->status = OK; + throw HaltException(); + } else { + s1 = (is_mod) ? s1 / s2 : s1 % s2; + } +} -- cgit v1.2.3 From 984ce6eef2e439955ff991f90c2b654be7c6c3f3 Mon Sep 17 00:00:00 2001 From: bd Date: Thu, 17 Apr 2025 19:56:53 -0400 Subject: Add option to turn off pipeline --- gui/worker.cc | 2 +- inc/controller.h | 6 +----- inc/stage.h | 6 +++++- src/sim/controller.cc | 8 ++++---- src/sim/if.cc | 3 ++- src/sim/stage.cc | 1 + tests/id.cc | 3 ++- tests/if.cc | 2 -- 8 files changed, 16 insertions(+), 15 deletions(-) (limited to 'gui/worker.cc') diff --git a/gui/worker.cc b/gui/worker.cc index defec46..a912e06 100644 --- a/gui/worker.cc +++ b/gui/worker.cc @@ -12,7 +12,7 @@ void Worker::doWork() this->ex_stage = new EX(id_stage); this->mm_stage = new MM(ex_stage); this->wb_stage = new WB(mm_stage); - this->ct = new Controller(wb_stage, this->c, true); + this->ct = new Controller(wb_stage, this->c, false); emit clock_cycles(this->ct->get_clock_cycle(), this->ct->get_pc()); emit dram_storage(this->d->view(0, 32)); diff --git a/inc/controller.h b/inc/controller.h index f56b1b4..778c5bc 100644 --- a/inc/controller.h +++ b/inc/controller.h @@ -19,7 +19,7 @@ class Controller : public Stage */ Controller(Stage *stage, Storage *storage, bool is_pipelined); InstrDTO *advance(Response p) override; - + /** * Direct the simulator to run for `number` clock cycles. * @param the number of clock cycles to run for. @@ -38,10 +38,6 @@ class Controller : public Stage */ int get_pc(); - void set_gprs(int index, int value); - - void set_pipelined(bool value); - private: void advance_helper() override; }; diff --git a/inc/stage.h b/inc/stage.h index 1cedac6..996c21c 100644 --- a/inc/stage.h +++ b/inc/stage.h @@ -118,6 +118,11 @@ class Stage * A flag indicating whether pipelining should be used. */ static bool is_pipelined; + /** + * A flag which tells fetch when the pipe is empty. Only used when the pipe + * is turned off. + */ + static bool is_empty; /** * The current clock cycle. */ @@ -134,7 +139,6 @@ class Stage * The current status of this stage. */ Response status; - }; #endif /* STAGE_H_INCLUDED */ diff --git a/src/sim/controller.cc b/src/sim/controller.cc index 9ae6d16..db6106c 100644 --- a/src/sim/controller.cc +++ b/src/sim/controller.cc @@ -9,6 +9,7 @@ Controller::Controller(Stage *stage, Storage *storage, bool is_pipelined) 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}; @@ -33,10 +34,6 @@ int Controller::get_clock_cycle() { return this->clock_cycle; } std::array Controller::get_gprs() { return this->gprs; } -void Controller::set_gprs(int index, int value) { this->gprs[index] = value; } - -void Controller::set_pipelined(bool value) { this->is_pipelined = value; } - int Controller::get_pc() { return this->pc; } InstrDTO *Controller::advance(Response p) @@ -45,6 +42,9 @@ InstrDTO *Controller::advance(Response p) r = this->next->advance(p); ++this->clock_cycle; + if (r) + this->is_empty = true; + return r; } diff --git a/src/sim/if.cc b/src/sim/if.cc index 1223149..bab2608 100644 --- a/src/sim/if.cc +++ b/src/sim/if.cc @@ -37,13 +37,14 @@ void IF::advance_helper() int i; signed int bits; - if (this->curr_instr == nullptr) { + 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/stage.cc b/src/sim/stage.cc index 7df1dba..9528e4b 100644 --- a/src/sim/stage.cc +++ b/src/sim/stage.cc @@ -17,6 +17,7 @@ std::deque 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; } diff --git a/tests/id.cc b/tests/id.cc index 6dcb124..321c013 100644 --- a/tests/id.cc +++ b/tests/id.cc @@ -184,8 +184,9 @@ TEST_CASE_METHOD(IDFixture, "Parse arbitrary j-type # two", "[id]") t = this->encode_J_type(0xBBCCF, 0b10101, 0b0011, 0b10); i = this->decode_bits(t); + t = 0xFFFBBCCF; CHECK(i->get_s1() == 0x00000000); // registers are empty - CHECK(i->get_s2() == 0xFFFBBCCF); + CHECK(i->get_s2() == t); CHECK(i->get_mnemonic() == JAL); delete i; diff --git a/tests/if.cc b/tests/if.cc index 01070ef..8b30d0e 100644 --- a/tests/if.cc +++ b/tests/if.cc @@ -73,9 +73,7 @@ class IFFixture TEST_CASE_METHOD(IFFixture, "fetch returns single instuction", "[if_pipe]") { InstrDTO *i; - int expected_cycles; - expected_cycles = this->m_delay + this->c_delay + 2; i = this->fetch_through(); REQUIRE(i->get_instr_bits() == this->p[0]); -- cgit v1.2.3