ready to write CSU
This commit is contained in:
@ -1,3 +1,4 @@
|
||||
For design and description, see <https://www.wolai.com/zymbox/qsUPoFaTyy88NWHKrjFKtW>
|
||||
# RISC-V Simulator Template
|
||||
|
||||
A template which enables you to write verilog-like C++ code.
|
||||
|
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#ifndef ALU_H
|
||||
#include "tools.h"
|
||||
#endif
|
@ -14,10 +14,10 @@ private:
|
||||
std::vector<std::unique_ptr<ModuleBase>> mod_owned;
|
||||
std::vector<ModuleBase *> 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;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,24 +1,62 @@
|
||||
#pragma once
|
||||
#ifndef CSU_H
|
||||
#include <functional>
|
||||
#include <array>
|
||||
#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<ROBRecordType, kROBSize> ROB_records;
|
||||
dark::Register<5> ROB_head;
|
||||
dark::Register<5> ROB_tail;
|
||||
dark::Register<6> ROB_size;
|
||||
};
|
||||
struct CentralScheduleUnit
|
||||
: public dark::Module<CentralScheduleUnit_Input, CentralScheduleUnit_Output, CentralScheduleUnit_Private> {
|
||||
private:
|
||||
public:
|
||||
CentralScheduleUnit() { ; }
|
||||
void work() override final {
|
||||
if (bool(reset)) {
|
||||
predicted_PC <= 0;
|
||||
actual_PC <= 0;
|
||||
has_predicted_PC <= 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace ZYM
|
||||
#endif
|
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#ifndef LOADSTOREQUEUE_H
|
||||
#include "tools.h"
|
||||
#endif
|
@ -39,7 +39,7 @@ struct Memory : dark::Module<Memory_Input, Memory_Output, Memory_Private> {
|
||||
ready <= 1;
|
||||
return;
|
||||
}
|
||||
if(bool(force_clear_signal)) {
|
||||
if(bool(force_clear_receiver)) {
|
||||
status <= 0;
|
||||
ready <= 1;
|
||||
return;
|
||||
|
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#ifndef RESERVATIONSTATION_H
|
||||
#include "tools.h"
|
||||
#endif
|
@ -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;
|
||||
|
12
src/main.cpp
12
src/main.cpp
@ -1,10 +1,20 @@
|
||||
#include "tools.h"
|
||||
#include <iostream>
|
||||
#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;
|
||||
}
|
Reference in New Issue
Block a user