diff --git a/README.md b/README.md index 51070a0..65f58d2 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +For design and description, see # RISC-V Simulator Template A template which enables you to write verilog-like C++ code. diff --git a/design.md b/design.md deleted file mode 100644 index f652421..0000000 --- a/design.md +++ /dev/null @@ -1 +0,0 @@ -- step1: 完成一个RV32I interpreter(无需支持I-type的指令) \ No newline at end of file diff --git a/include/alu.h b/include/alu.h index e69de29..bd1f341 100644 --- a/include/alu.h +++ b/include/alu.h @@ -0,0 +1,4 @@ +#pragma once +#ifndef ALU_H +#include "tools.h" +#endif \ No newline at end of file diff --git a/include/bus.h b/include/bus.h deleted file mode 100644 index e69de29..0000000 diff --git a/include/cpu.h b/include/cpu.h index 91fd2b5..40b3645 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -14,10 +14,10 @@ private: std::vector> mod_owned; std::vector modules; bool reset_signal = false; - dark::Wire<1> halt_signal; public: unsigned long long cycles = 0; + dark::Wire<9> halt_signal; private: void sync_all() { @@ -60,13 +60,18 @@ public: bool GetResetSignal(){ return reset_signal; } - void run(unsigned long long max_cycles = 0, bool shuffle = false) { + uint8_t run(unsigned long long max_cycles = 0, bool shuffle = false) { auto func = shuffle ? &CPU::run_once_shuffle : &CPU::run_once; reset_signal=true; while (max_cycles == 0 || cycles < max_cycles) { (this->*func)(); reset_signal=false; + uint32_t halt_signal_value = max_size_t(halt_signal); + if(halt_signal_value &(1<<9)) { + return halt_signal_value&0xff; + } } + return 255; } }; diff --git a/include/csu.h b/include/csu.h index 6319e6b..4de7d96 100644 --- a/include/csu.h +++ b/include/csu.h @@ -1,24 +1,62 @@ #pragma once #ifndef CSU_H +#include +#include #include "tools.h" namespace ZYM { const int kROBSize = 32; const int kTotalRegister = 32; struct CentralScheduleUnit_Input { dark::Wire<1> reset; + // data from load store queue + dark::Wire<6> load_store_queue_emptyspace_receiver; + // data from reservation station + dark::Wire<6> reservestation_emptyspace_receiver; + // data from Memory Station + dark::Wire<2> completed_memins_type; + dark::Wire<5> completed_memins_ROB_index; + dark::Wire<32> completed_memins_read_data; + // data from alu + dark::Wire<5> completed_aluins_ROB_index; + dark::Wire<32> completed_aluins_result; }; struct CentralScheduleUnit_Output { dark::Register<1> ready; dark::Register<1> force_clear_announcer; + dark::Register<9> halt_signal; // The highest bit is the marker, and the rest is the exit code +}; +struct ROBRecordType { + dark::Register<4> state; + dark::Register<32> instruction; + dark::Register<5> resulting_register_idx; + dark::Register<32> resulting_register_value; + dark::Register<1> resulting_PC_ready; + dark::Register<32> resulting_PC; + dark::Register<4> mem_request_type; // see memory.h + dark::Register<32> mem_request_addr; + dark::Register<32> mem_request_data; }; struct CentralScheduleUnit_Private { - dark::Register<32> predicated_PC; + dark::Register<32> predicted_PC; + dark::Register<1> has_predicted_PC; // jalr may force the CPU to stall + dark::Register<32> actual_PC; + std::array ROB_records; + dark::Register<5> ROB_head; + dark::Register<5> ROB_tail; + dark::Register<6> ROB_size; }; struct CentralScheduleUnit : public dark::Module { private: public: CentralScheduleUnit() { ; } + void work() override final { + if (bool(reset)) { + predicted_PC <= 0; + actual_PC <= 0; + has_predicted_PC <= 1; + } + } }; } // namespace ZYM #endif \ No newline at end of file diff --git a/include/loadstorequeue.h b/include/loadstorequeue.h index e69de29..9d171ad 100644 --- a/include/loadstorequeue.h +++ b/include/loadstorequeue.h @@ -0,0 +1,4 @@ +#pragma once +#ifndef LOADSTOREQUEUE_H +#include "tools.h" +#endif \ No newline at end of file diff --git a/include/memory.h b/include/memory.h index f37ac50..adb5ac1 100644 --- a/include/memory.h +++ b/include/memory.h @@ -39,7 +39,7 @@ struct Memory : dark::Module { ready <= 1; return; } - if(bool(force_clear_signal)) { + if(bool(force_clear_receiver)) { status <= 0; ready <= 1; return; diff --git a/include/reservestation.h b/include/reservestation.h index e69de29..ca521dc 100644 --- a/include/reservestation.h +++ b/include/reservestation.h @@ -0,0 +1,4 @@ +#pragma once +#ifndef RESERVATIONSTATION_H +#include "tools.h" +#endif \ No newline at end of file diff --git a/include/tools.h b/include/tools.h index bf4a42f..71c58f2 100644 --- a/include/tools.h +++ b/include/tools.h @@ -7,8 +7,7 @@ #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 index 9bbf183..4318f03 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,10 +1,20 @@ -#include "tools.h" +#include +#include "alu.h" #include "csu.h" +#include "loadstorequeue.h" +#include "memory.h" +#include "registerfile.h" +#include "reservestation.h" +#include "tools.h" int main(int argc, char **argv) { dark::CPU cpu; + ZYM::CentralScheduleUnit csu; ZYM::Memory memory; + cpu.add_module(&csu); cpu.add_module(&memory); + cpu.halt_signal.assign([&]() -> auto & { return csu.halt_signal; }); memory.reset = [&]() { return cpu.GetResetSignal(); }; memory.LoadProgram(std::cin); + std::cout << cpu.run(0, true) << std::endl; return 0; } \ No newline at end of file