From c62ed9d3ce24aa10b2ec3c1feec46cd94c5041aa Mon Sep 17 00:00:00 2001 From: ZhuangYumin Date: Mon, 29 Jul 2024 03:38:03 +0000 Subject: [PATCH] finish design, ready to write --- CMakeLists.txt | 6 ++ include/alu.h | 0 include/bus.h | 0 include/cpu.h | 12 +++- include/csu.h | 24 +++++++ include/debug.h | 7 ++ include/loadstorequeue.h | 0 include/memory.h | 136 +++++++++++++++++++++++++++++++++++++++ include/registerfile.h | 4 ++ include/reservestation.h | 0 include/tools.h | 2 + src/main.cpp | 10 +++ 12 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 include/alu.h create mode 100644 include/bus.h create mode 100644 include/csu.h create mode 100644 include/loadstorequeue.h create mode 100644 include/memory.h create mode 100644 include/registerfile.h create mode 100644 include/reservestation.h create mode 100644 src/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 61b9497..a39803b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,12 @@ set_target_properties(interpreter RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" ) +add_executable(code src/main.cpp) +set_target_properties(code + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" +) + # Enable sanitizer for debug builds if(CMAKE_BUILD_TYPE STREQUAL "Debug") if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") diff --git a/include/alu.h b/include/alu.h new file mode 100644 index 0000000..e69de29 diff --git a/include/bus.h b/include/bus.h new file mode 100644 index 0000000..e69de29 diff --git a/include/cpu.h b/include/cpu.h index 732d4b8..91fd2b5 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -1,16 +1,20 @@ #pragma once #include "module.h" +#include "wire.h" #include #include #include #include + namespace dark { class CPU { private: std::vector> mod_owned; std::vector modules; + bool reset_signal = false; + dark::Wire<1> halt_signal; public: unsigned long long cycles = 0; @@ -53,10 +57,16 @@ public: module->work(); sync_all(); } + bool GetResetSignal(){ + return reset_signal; + } void run(unsigned long long max_cycles = 0, bool shuffle = false) { auto func = shuffle ? &CPU::run_once_shuffle : &CPU::run_once; - while (max_cycles == 0 || cycles < max_cycles) + reset_signal=true; + while (max_cycles == 0 || cycles < max_cycles) { (this->*func)(); + reset_signal=false; + } } }; diff --git a/include/csu.h b/include/csu.h new file mode 100644 index 0000000..6319e6b --- /dev/null +++ b/include/csu.h @@ -0,0 +1,24 @@ +#pragma once +#ifndef CSU_H +#include "tools.h" +namespace ZYM { +const int kROBSize = 32; +const int kTotalRegister = 32; +struct CentralScheduleUnit_Input { + dark::Wire<1> reset; +}; +struct CentralScheduleUnit_Output { + dark::Register<1> ready; + dark::Register<1> force_clear_announcer; +}; +struct CentralScheduleUnit_Private { + dark::Register<32> predicated_PC; +}; +struct CentralScheduleUnit + : public dark::Module { + private: + public: + CentralScheduleUnit() { ; } +}; +} // namespace ZYM +#endif \ No newline at end of file diff --git a/include/debug.h b/include/debug.h index dad80be..f4a169c 100644 --- a/include/debug.h +++ b/include/debug.h @@ -5,6 +5,13 @@ #endif #include +#ifdef _DEBUG +#define DEBUG_CERR std::cerr +#else +#define DEBUG_CERR if(0) std::cerr +#endif +#include +#include namespace dark::debug { /** diff --git a/include/loadstorequeue.h b/include/loadstorequeue.h new file mode 100644 index 0000000..e69de29 diff --git a/include/memory.h b/include/memory.h new file mode 100644 index 0000000..f37ac50 --- /dev/null +++ b/include/memory.h @@ -0,0 +1,136 @@ +#pragma once +#include +#include "concept.h" +#ifndef MEMORY_H +#include +#include +#include +#include "tools.h" +using dark::max_size_t; +namespace ZYM { +struct Memory_Input { + dark::Wire<4> request_type_input; + dark::Wire<32> address_input; + dark::Wire<32> data_input; + dark::Wire<1> reset; + dark::Wire<1> force_clear_receiver; +}; +struct Memory_Output { + dark::Register<1> ready; + dark::Register<32> data_output; +}; +struct Memory_Private { + dark::Register<3> status; + dark::Register<32> cur_opt_addr; + dark::Register<32> cur_opt_data; + dark::Register<2> cur_opt_type; + dark::Register<2> cur_opt_bytes; +}; +struct Memory : dark::Module { + private: + std::vector memory_data; + + public: + Memory() { memory_data.resize(1 << 20, 0); } + void work() override final { + if (bool(reset)) { + // do some initialization + status <= 0; + ready <= 1; + return; + } + if(bool(force_clear_signal)) { + status <= 0; + ready <= 1; + return; + } + max_size_t request_type_signal = max_size_t(request_type_input); + uint8_t rw_type = request_type_signal & 3; // 0b00->none,0b01->read,0b10->write,0b11->invalid + uint8_t opt_bytes = (request_type_signal >> 2) & 3; // 0->1, 1->2, 2->4 + if (rw_type == 3) throw std::runtime_error("Invalid request type"); + uint32_t current_status = max_size_t(status); + if (current_status > 0) { + // in working status + if (request_type_signal > 0) throw std::runtime_error("Memory is busy"); + if (current_status == 1) { + status <= 2; + return; + } + status <= 0; + ready <= 1; + if(max_size_t(cur_opt_type) == 0b01) { + size_t len=1<(&memory_data[max_size_t(cur_opt_addr)]); + break; + case 4: + data_output <= *reinterpret_cast(&memory_data[max_size_t(cur_opt_addr)]); + break; + default: + throw std::runtime_error("Invalid bytes"); + } + } else { + size_t len=1<(&memory_data[max_size_t(cur_opt_addr)]) = max_size_t(cur_opt_data)&0xffff; + break; + case 4: + *reinterpret_cast(&memory_data[max_size_t(cur_opt_addr)]) = max_size_t(cur_opt_data); + break; + default: + throw std::runtime_error("Invalid bytes"); + } + } + return; + } + // now the memory is not busy + if (request_type_signal == 0) return; + status <= 1; + ready <= 0; + cur_opt_addr <= address_input; + cur_opt_data <= data_input; + cur_opt_type <= rw_type; + cur_opt_bytes <= opt_bytes; + } + max_size_t FetchInstruction(max_size_t addr) { // assume we have a super nb instruction fetch method that can fetch + // an instruction immediately + max_size_t res; + res = *reinterpret_cast(&memory_data[addr]); + return res; + } + void LoadProgram(std::istream &fin) { + fin >> std::hex; + std::string rubbish_bin; + do { + while (!fin.eof() && fin.get() != '@') + ; + if (fin.eof()) break; + int addr, tmp; + std::vector buf; + fin >> addr; + DEBUG_CERR << "begin:" << std::hex << addr << std::endl; + while (fin >> tmp) { + buf.push_back(tmp); + } + if (memory_data.size() < addr + buf.size()) { + memory_data.resize(addr + buf.size()); + } + for (int i = 0; i < buf.size(); i++) { + memory_data[addr + i] = buf[i]; + DEBUG_CERR << std::hex << addr + i << ' ' << std::uppercase << std::setw(2) << std::setfill('0') << std::hex + << (int)buf[i] << std::endl; + } + fin.clear(); + } while (!fin.eof()); + } +}; +} // namespace ZYM +#endif // MEMORY_H \ No newline at end of file diff --git a/include/registerfile.h b/include/registerfile.h new file mode 100644 index 0000000..7e6048c --- /dev/null +++ b/include/registerfile.h @@ -0,0 +1,4 @@ +#pragma once +#ifndef REGISTERFILE_H +#include "tools.h" +#endif \ No newline at end of file diff --git a/include/reservestation.h b/include/reservestation.h new file mode 100644 index 0000000..e69de29 diff --git a/include/tools.h b/include/tools.h index 7e190cb..bf4a42f 100644 --- a/include/tools.h +++ b/include/tools.h @@ -7,6 +7,8 @@ #include "wire.h" #include "module.h" #include "cpu.h" +#include "memory.h" +#include "bus.h" using dark::Bit; using dark::sign_extend; diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..9bbf183 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,10 @@ +#include "tools.h" +#include "csu.h" +int main(int argc, char **argv) { + dark::CPU cpu; + ZYM::Memory memory; + cpu.add_module(&memory); + memory.reset = [&]() { return cpu.GetResetSignal(); }; + memory.LoadProgram(std::cin); + return 0; +} \ No newline at end of file