diff --git a/src/MemoryTypes/State/Bus.cpp b/src/MemoryTypes/State/Bus.cpp new file mode 100644 index 0000000..5ba5b31 --- /dev/null +++ b/src/MemoryTypes/State/Bus.cpp @@ -0,0 +1,54 @@ +#include "MemoryTypes/State/Bus.h" + +#include + +NVM::State::Bus::Bus() : bank(nullptr), currentState(BUS_STATE::NO_OP) {} + +void NVM::State::Bus::setBank(StateBank* b) { bank = b; } + +bool NVM::State::Bus::read(const Address& address, const RowData& data) { + if (currentState != BUS_STATE::NO_OP) return except(); + currentState = BUS_STATE::READ; + if (bank) return bank->read(address, data); + return false; +} + +bool NVM::State::Bus::write(const Address& address, const RowData& data) { + if (currentState != BUS_STATE::NO_OP) return except(); + currentState = BUS_STATE::WRITE; + if (bank) return bank->write(address, data); + return false; +} + +bool NVM::State::Bus::activate(const Address& address) { + if (currentState != BUS_STATE::NO_OP) return except(); + if (bank) return bank->activate(address); + return false; +} + +bool NVM::State::Bus::precharge(const Address& address) { + if (currentState != BUS_STATE::NO_OP) return except(); + if (bank) return bank->precharge(address); + return false; +} + +bool NVM::State::Bus::refresh() { + if (currentState != BUS_STATE::NO_OP) return except(); + if (bank) return bank->refresh(); + return false; +} + +bool NVM::State::Bus::sendData() { + if (currentState != BUS_STATE::NO_OP) return except(); + return true; +} + +void NVM::State::Bus::cycle() { + commandHistory.push_back(currentState); + currentState = BUS_STATE::NO_OP; + if (bank) bank->cycle(); +} + +void NVM::State::Bus::printCycles() const { + for (const auto state : commandHistory) std::cout << state << '\n'; +} diff --git a/src/MemoryTypes/State/Bus.h b/src/MemoryTypes/State/Bus.h new file mode 100644 index 0000000..b147daa --- /dev/null +++ b/src/MemoryTypes/State/Bus.h @@ -0,0 +1,69 @@ +#pragma once + +#include "MemoryTypes/State/Commandable.h" +#include "MemoryTypes/State/StateBank.h" + +namespace NVM::State { + +class Bus : public Commandable { + public: + Bus(); + + void setBank(StateBank* b); + + /* + * Performs a READ command. + */ + bool read(const Address& address, const RowData& data); + + /* + * Performs a WRITE command. + */ + bool write(const Address& address, const RowData& data); + + /* + * Performs an ACTIVATE command. + */ + bool activate(const Address& address); + + /* + * Performs a PRECHARGE command. + */ + bool precharge(const Address& address); + + /* + * Performs a REFRESH command. + */ + bool refresh(); + + bool sendData(); + + void cycle(); + + void printCycles() const; + + private: + StateBank* bank; + + enum class BUS_STATE { READ, WRITE, NO_OP }; + + BUS_STATE currentState; + std::vector commandHistory; + + friend std::ostream& operator<<(std::ostream& out, const BUS_STATE state) { + switch (state) { + case BUS_STATE::NO_OP: + out << "no_op"; + break; + case BUS_STATE::READ: + out << "read"; + break; + case BUS_STATE::WRITE: + out << "write"; + break; + } + return out; + } +}; + +} // namespace NVM::State \ No newline at end of file diff --git a/src/MemoryTypes/State/CMakeLists.txt b/src/MemoryTypes/State/CMakeLists.txt index fce10cf..7fc76f3 100644 --- a/src/MemoryTypes/State/CMakeLists.txt +++ b/src/MemoryTypes/State/CMakeLists.txt @@ -3,7 +3,8 @@ set(STATE_SOURCES StateBank.cpp ReadingState.cpp WritingState.cpp - ClosedState.cpp) + ClosedState.cpp + Bus.cpp) add_library(RTSim_MemoryType_State ${STATE_SOURCES}) target_include_directories(RTSim_MemoryType_State PUBLIC ${RTSIM_DIR}/include PRIVATE ${RTSIM_DIR}/src) diff --git a/src/MemoryTypes/State/README b/src/MemoryTypes/State/README index 6da631e..7d81ddb 100644 --- a/src/MemoryTypes/State/README +++ b/src/MemoryTypes/State/README @@ -4,4 +4,12 @@ It is based on DRAM. 1_30_2024 -- How should stats be handled? \ No newline at end of file +- How should stats be handled? + +For now, each state will keep track of its own stats, and the result will be added to the device when switching states. For example, the Reading state adds 1 read to the stats, so it returns a StatBlock containing 1 'read'. + +1_31_2024 + +- How should the bus be handled? + +The bus (or buses in general) require 2-way communication. Commands go in, responses come out. The state of the bus at each cycle is crucial to verification. What design pattern allows for 2-way communication across a medium? Mediator. Any device using a bus can simply keep a reference to the bus. If 2 devices try to drive the bus in the same cycle, we can throw an exception. \ No newline at end of file diff --git a/src/MemoryTypes/State/StateSystem.cpp b/src/MemoryTypes/State/StateSystem.cpp index dcf7bf2..eead7d2 100644 --- a/src/MemoryTypes/State/StateSystem.cpp +++ b/src/MemoryTypes/State/StateSystem.cpp @@ -4,12 +4,14 @@ using namespace NVM::State; using NVM::Address; using NVM::RowData; +NVM::State::StateSystem::StateSystem() { bus.setBank(&bank); } + bool StateSystem::read(const Address& address, const RowData& data) { - return bank.read(address, data); + return bus.read(address, data); } bool StateSystem::write(const Address& address, const RowData& data) { - return bank.write(address, data); + return bus.write(address, data); } bool StateSystem::rowClone(const Address& srcAddress, @@ -25,10 +27,11 @@ bool StateSystem::pim(std::vector
operands, const Address& destAddress, bool StateSystem::isEmpty() const { return true; } void StateSystem::cycle(unsigned int cycles) { - for (int i = 0; i < cycles; i++) bank.cycle(); + for (int i = 0; i < cycles; i++) bus.cycle(); } void StateSystem::printStats(std::ostream& statStream) { auto stats = bank.getStats(); stats.log(statStream); -} \ No newline at end of file + bus.printCycles(); +} diff --git a/src/MemoryTypes/State/StateSystem.h b/src/MemoryTypes/State/StateSystem.h index 9e41f74..439dd78 100644 --- a/src/MemoryTypes/State/StateSystem.h +++ b/src/MemoryTypes/State/StateSystem.h @@ -1,12 +1,15 @@ #pragma once #include "Memory/MemorySystem.h" +#include "MemoryTypes/State/Bus.h" #include "MemoryTypes/State/StateBank.h" namespace NVM::State { class StateSystem : public Memory::MemorySystem { public: + StateSystem(); + bool read(const Address& address, const RowData& data); bool write(const Address& address, const RowData& data); @@ -25,6 +28,7 @@ class StateSystem : public Memory::MemorySystem { private: StateBank bank; + Bus bus; }; } // namespace NVM::State \ No newline at end of file