ready to write CSU

This commit is contained in:
2024-07-29 08:05:51 +00:00
parent c62ed9d3ce
commit f8b4896b7c
11 changed files with 72 additions and 8 deletions

View File

@ -1,3 +1,4 @@
For design and description, see <https://www.wolai.com/zymbox/qsUPoFaTyy88NWHKrjFKtW>
# RISC-V Simulator Template # RISC-V Simulator Template
A template which enables you to write verilog-like C++ code. A template which enables you to write verilog-like C++ code.

View File

@ -1 +0,0 @@
- step1: 完成一个RV32I interpreter无需支持I-type的指令

View File

@ -0,0 +1,4 @@
#pragma once
#ifndef ALU_H
#include "tools.h"
#endif

View File

View File

@ -14,10 +14,10 @@ private:
std::vector<std::unique_ptr<ModuleBase>> mod_owned; std::vector<std::unique_ptr<ModuleBase>> mod_owned;
std::vector<ModuleBase *> modules; std::vector<ModuleBase *> modules;
bool reset_signal = false; bool reset_signal = false;
dark::Wire<1> halt_signal;
public: public:
unsigned long long cycles = 0; unsigned long long cycles = 0;
dark::Wire<9> halt_signal;
private: private:
void sync_all() { void sync_all() {
@ -60,13 +60,18 @@ public:
bool GetResetSignal(){ bool GetResetSignal(){
return reset_signal; 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; auto func = shuffle ? &CPU::run_once_shuffle : &CPU::run_once;
reset_signal=true; reset_signal=true;
while (max_cycles == 0 || cycles < max_cycles) { while (max_cycles == 0 || cycles < max_cycles) {
(this->*func)(); (this->*func)();
reset_signal=false; 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;
} }
}; };

View File

@ -1,24 +1,62 @@
#pragma once #pragma once
#ifndef CSU_H #ifndef CSU_H
#include <functional>
#include <array>
#include "tools.h" #include "tools.h"
namespace ZYM { namespace ZYM {
const int kROBSize = 32; const int kROBSize = 32;
const int kTotalRegister = 32; const int kTotalRegister = 32;
struct CentralScheduleUnit_Input { struct CentralScheduleUnit_Input {
dark::Wire<1> reset; 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 { struct CentralScheduleUnit_Output {
dark::Register<1> ready; dark::Register<1> ready;
dark::Register<1> force_clear_announcer; 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 { 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<ROBRecordType, kROBSize> ROB_records;
dark::Register<5> ROB_head;
dark::Register<5> ROB_tail;
dark::Register<6> ROB_size;
}; };
struct CentralScheduleUnit struct CentralScheduleUnit
: public dark::Module<CentralScheduleUnit_Input, CentralScheduleUnit_Output, CentralScheduleUnit_Private> { : public dark::Module<CentralScheduleUnit_Input, CentralScheduleUnit_Output, CentralScheduleUnit_Private> {
private: private:
public: public:
CentralScheduleUnit() { ; } CentralScheduleUnit() { ; }
void work() override final {
if (bool(reset)) {
predicted_PC <= 0;
actual_PC <= 0;
has_predicted_PC <= 1;
}
}
}; };
} // namespace ZYM } // namespace ZYM
#endif #endif

View File

@ -0,0 +1,4 @@
#pragma once
#ifndef LOADSTOREQUEUE_H
#include "tools.h"
#endif

View File

@ -39,7 +39,7 @@ struct Memory : dark::Module<Memory_Input, Memory_Output, Memory_Private> {
ready <= 1; ready <= 1;
return; return;
} }
if(bool(force_clear_signal)) { if(bool(force_clear_receiver)) {
status <= 0; status <= 0;
ready <= 1; ready <= 1;
return; return;

View File

@ -0,0 +1,4 @@
#pragma once
#ifndef RESERVATIONSTATION_H
#include "tools.h"
#endif

View File

@ -7,8 +7,7 @@
#include "wire.h" #include "wire.h"
#include "module.h" #include "module.h"
#include "cpu.h" #include "cpu.h"
#include "memory.h"
#include "bus.h"
using dark::Bit; using dark::Bit;
using dark::sign_extend; using dark::sign_extend;

View File

@ -1,10 +1,20 @@
#include "tools.h" #include <iostream>
#include "alu.h"
#include "csu.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) { int main(int argc, char **argv) {
dark::CPU cpu; dark::CPU cpu;
ZYM::CentralScheduleUnit csu;
ZYM::Memory memory; ZYM::Memory memory;
cpu.add_module(&csu);
cpu.add_module(&memory); cpu.add_module(&memory);
cpu.halt_signal.assign([&]() -> auto & { return csu.halt_signal; });
memory.reset = [&]() { return cpu.GetResetSignal(); }; memory.reset = [&]() { return cpu.GetResetSignal(); };
memory.LoadProgram(std::cin); memory.LoadProgram(std::cin);
std::cout << cpu.run(0, true) << std::endl;
return 0; return 0;
} }