diff --git a/include/alu.h b/include/alu.h index 97068b9..e6faa05 100644 --- a/include/alu.h +++ b/include/alu.h @@ -1,6 +1,7 @@ #pragma once #ifndef ALU_H #include "tools.h" +namespace ZYM { struct ALU_Input { dark::Wire<7 + 3 + 1> request_full_id; dark::Wire<32> operand1; @@ -8,16 +9,18 @@ struct ALU_Input { dark::Wire<5> request_ROB_index; }; struct ALU_Output { - dark::Register<1> done; - dark::Register<32> result; + dark::Register<2> alu_status; dark::Register<5> result_ROB_index; + dark::Register<32> result; + dark::Register<32> completed_alu_resulting_PC; }; struct ALU : public dark::Module { ALU() { // Constructor } - void update() { + void work() { // Update function } }; +} #endif \ No newline at end of file diff --git a/include/csu.h b/include/csu.h index 74fc9ed..c017036 100644 --- a/include/csu.h +++ b/include/csu.h @@ -16,6 +16,11 @@ struct CentralScheduleUnit_Input { dark::Wire<2> mem_status_receiver; dark::Wire<5> completed_memins_ROB_index; dark::Wire<32> completed_memins_read_data; + // data from LoadStoreQueue + dark::Wire<4> mem_request_type_input; + dark::Wire<32> mem_address_input; + dark::Wire<32> mem_data_input; + dark::Wire<5> mem_request_ROB_index; // data from alu dark::Wire<2> alu_status_receiver; dark::Wire<5> completed_aluins_ROB_index; @@ -39,10 +44,17 @@ struct CentralScheduleUnit_Output { dark::Register<1> has_decoded_rd; dark::Register<5> decoded_rs1; dark::Register<1> has_decoded_rs1; + dark::Register<1> rs1_is_in_ROB; + dark::Register<32> rs1_in_ROB_value; dark::Register<5> decoded_rs2; dark::Register<1> has_decoded_rs2; + dark::Register<1> rs2_is_in_ROB; + dark::Register<32> rs2_in_ROB_value; dark::Register<32> decoded_imm; dark::Register<6> decoded_shamt; + dark::Register<1> cache_hit; + dark::Register<5> cache_hit_ROB_index; + dark::Register<32> cache_hit_data; }; struct ROBRecordType { dark::Register<4> state; diff --git a/include/loadstorequeue.h b/include/loadstorequeue.h index 5fb0f5a..0e286a2 100644 --- a/include/loadstorequeue.h +++ b/include/loadstorequeue.h @@ -1,6 +1,7 @@ #pragma once #ifndef LOADSTOREQUEUE_H #include "tools.h" +namespace ZYM { struct LoadStoreQueue_Input { // receive control signal from CSU dark::Wire<1> reset; @@ -14,9 +15,24 @@ struct LoadStoreQueue_Input { dark::Wire<1> has_decoded_rd; dark::Wire<5> decoded_rs1; dark::Wire<1> has_decoded_rs1; + dark::Wire<1> rs1_is_in_ROB; + dark::Wire<32> rs1_in_ROB_value; dark::Wire<5> decoded_rs2; dark::Wire<1> has_decoded_rs2; + dark::Wire<1> rs2_is_in_ROB; + dark::Wire<32> rs2_in_ROB_value; dark::Wire<32> decoded_imm; + // receive data from register file + dark::Wire<1> rs1_nodep; + dark::Wire<5> rs1_deps; + dark::Wire<32> rs1_value; + dark::Wire<1> rs2_nodep; + dark::Wire<5> rs2_deps; + dark::Wire<32> rs2_value; + // data from alu + dark::Wire<2> alu_status_receiver; + dark::Wire<5> completed_aluins_ROB_index; + dark::Wire<32> completed_aluins_result; // receive status signal from Memory dark::Wire<2> mem_data_sign; dark::Wire<5> completed_memins_ROB_index; @@ -32,6 +48,7 @@ struct LoadStoreQueue_Output { dark::Register<5> request_ROB_index; dark::Register<32> request_address_output; dark::Register<32> request_data_output; + dark::Register<6> LSQ_remain_space_output; }; struct LoadStoreQueue_Private { dark::Register<5> LSQ_head; @@ -42,8 +59,9 @@ struct LoadStoreQueue: public dark::Module reset; @@ -29,8 +30,9 @@ struct RegisterFile : public dark::Module reset; @@ -14,8 +15,12 @@ struct ReserveStation_Input { dark::Wire<1> has_decoded_rd; dark::Wire<5> decoded_rs1; dark::Wire<1> has_decoded_rs1; + dark::Wire<1> rs1_is_in_ROB; + dark::Wire<32> rs1_in_ROB_value; dark::Wire<5> decoded_rs2; dark::Wire<1> has_decoded_rs2; + dark::Wire<1> rs2_is_in_ROB; + dark::Wire<32> rs2_in_ROB_value; dark::Wire<32> decoded_imm; dark::Wire<6> decoded_shamt; // receive data from register file @@ -25,6 +30,18 @@ struct ReserveStation_Input { dark::Wire<1> rs2_nodep; dark::Wire<5> rs2_deps; dark::Wire<32> rs2_value; + // data from alu + dark::Wire<2> alu_status_receiver; + dark::Wire<5> completed_aluins_ROB_index; + dark::Wire<32> completed_aluins_result; + // data from Memory + dark::Wire<2> mem_status_receiver; + dark::Wire<5> completed_memins_ROB_index; + dark::Wire<32> completed_memins_read_data; + // receive status signal from L0 cache(data from Memory) + dark::Wire<1> cache_hit; + dark::Wire<5> cache_hit_ROB_index; + dark::Wire<32> cache_hit_data; }; struct ReserveStation_Output { // alu will listen for these: @@ -32,6 +49,7 @@ struct ReserveStation_Output { dark::Register<32> operand1; dark::Register<32> operand2; dark::Register<5> request_ROB_index; + dark::Register<6> RS_remain_space_output; }; struct ReserveStation_Private { dark::Register<5> RS_head; @@ -41,8 +59,9 @@ struct ReserveStation : public dark::Module -inline static void DirectWireConnect(dark::Register &src, dark::Wire &dest) { +template +inline static void RWConnect(dark::Register &src, dark::Wire &dest) { dest.assign([&]() -> auto & { return src; }); } int main(int argc, char **argv) { dark::CPU cpu; ZYM::CentralScheduleUnit csu; ZYM::Memory memory; + ZYM::LoadStoreQueue lsq; + ZYM::ALU alu; + ZYM::RegisterFile rf; + ZYM::ReserveStation rs; cpu.add_module(&csu); cpu.add_module(&memory); + cpu.add_module(&lsq); + cpu.add_module(&alu); + cpu.add_module(&rf); + cpu.add_module(&rs); + // some basic siganls cpu.halt_signal.assign([&]() -> auto & { return csu.halt_signal; }); - memory.reset = [&]() { return cpu.GetResetSignal(); }; - memory.LoadProgram(std::cin); csu.SetInstructionFetcher([&](auto addr) { return memory.FetchInstruction(addr); }); + csu.reset.assign([&]() { return cpu.GetResetSignal(); }); + memory.reset.assign([&]() { return cpu.GetResetSignal(); }); + memory.LoadProgram(std::cin); + lsq.reset.assign([&]() { return cpu.GetResetSignal(); }); + // alu.reset.assign([&]() { return cpu.GetResetSignal(); }); + rf.reset.assign([&]() { return cpu.GetResetSignal(); }); + rs.reset.assign([&]() { return cpu.GetResetSignal(); }); + // now connect the wires, see the comment and docs for help + // csu <-> memory + RWConnect(csu.force_clear_announcer, memory.force_clear_receiver); + RWConnect(memory.data_sign, csu.mem_status_receiver); + RWConnect(memory.completed_memins_ROB_index, csu.completed_memins_ROB_index); + RWConnect(memory.completed_memins_read_data, csu.completed_memins_read_data); + // csu <-> lsq + RWConnect(csu.force_clear_announcer, lsq.force_clear_receiver); + RWConnect(csu.is_issuing, lsq.is_issuing); + RWConnect(csu.issue_type, lsq.issue_type); + RWConnect(csu.issue_ROB_index, lsq.issue_ROB_index); + RWConnect(csu.full_ins_id, lsq.full_ins_id); + RWConnect(csu.full_ins, lsq.full_ins); + RWConnect(csu.decoded_rd, lsq.decoded_rd); + RWConnect(csu.has_decoded_rd, lsq.has_decoded_rd); + RWConnect(csu.decoded_rs1, lsq.decoded_rs1); + RWConnect(csu.has_decoded_rs1, lsq.has_decoded_rs1); + RWConnect(csu.rs1_is_in_ROB, lsq.rs1_is_in_ROB); + RWConnect(csu.rs1_in_ROB_value, lsq.rs1_in_ROB_value); + RWConnect(csu.decoded_rs2, lsq.decoded_rs2); + RWConnect(csu.has_decoded_rs2, lsq.has_decoded_rs2); + RWConnect(csu.rs2_is_in_ROB, lsq.rs2_is_in_ROB); + RWConnect(csu.rs2_in_ROB_value, lsq.rs2_in_ROB_value); + RWConnect(csu.decoded_imm, lsq.decoded_imm); + RWConnect(csu.cache_hit, lsq.cache_hit); + RWConnect(csu.cache_hit_ROB_index, lsq.cache_hit_ROB_index); + RWConnect(csu.cache_hit_data, lsq.cache_hit_data); + RWConnect(lsq.request_type_output, csu.mem_request_type_input); + RWConnect(lsq.request_ROB_index, csu.mem_request_ROB_index); + RWConnect(lsq.request_address_output, csu.mem_address_input); + RWConnect(lsq.request_data_output, csu.mem_data_input); + RWConnect(lsq.LSQ_remain_space_output, csu.load_store_queue_emptyspace_receiver); + // csu <-> alu + RWConnect(alu.alu_status, csu.alu_status_receiver); + RWConnect(alu.result_ROB_index, csu.completed_aluins_ROB_index); + RWConnect(alu.result, csu.completed_aluins_result); + RWConnect(alu.completed_alu_resulting_PC, csu.completed_alu_resulting_PC); + // csu <-> register file + RWConnect(csu.force_clear_announcer, rf.force_clear_receiver); + RWConnect(csu.is_issuing, rf.is_issuing); + RWConnect(csu.issue_type, rf.issue_type); + RWConnect(csu.issue_ROB_index, rf.issue_ROB_index); + RWConnect(csu.full_ins_id, rf.full_ins_id); + RWConnect(csu.full_ins, rf.full_ins); + RWConnect(csu.decoded_rd, rf.decoded_rd); + RWConnect(csu.has_decoded_rd, rf.has_decoded_rd); + RWConnect(csu.decoded_rs1, rf.decoded_rs1); + RWConnect(csu.has_decoded_rs1, rf.has_decoded_rs1); + RWConnect(csu.decoded_rs2, rf.decoded_rs2); + RWConnect(csu.has_decoded_rs2, rf.has_decoded_rs2); + RWConnect(rf.rs1_nodep, csu.rs1_nodep); + RWConnect(rf.rs1_deps, csu.rs1_deps); + RWConnect(rf.rs2_nodep, csu.rs2_nodep); + RWConnect(rf.rs2_deps, csu.rs2_deps); + // csu <-> reserve station + RWConnect(csu.force_clear_announcer, rs.force_clear_receiver); + RWConnect(csu.is_issuing, rs.is_issuing); + RWConnect(csu.issue_type, rs.issue_type); + RWConnect(csu.issue_ROB_index, rs.issue_ROB_index); + RWConnect(csu.full_ins_id, rs.full_ins_id); + RWConnect(csu.full_ins, rs.full_ins); + RWConnect(csu.decoded_rd, rs.decoded_rd); + RWConnect(csu.has_decoded_rd, rs.has_decoded_rd); + RWConnect(csu.decoded_rs1, rs.decoded_rs1); + RWConnect(csu.has_decoded_rs1, rs.has_decoded_rs1); + RWConnect(csu.rs1_is_in_ROB, rs.rs1_is_in_ROB); + RWConnect(csu.rs1_in_ROB_value, rs.rs1_in_ROB_value); + RWConnect(csu.decoded_rs2, rs.decoded_rs2); + RWConnect(csu.has_decoded_rs2, rs.has_decoded_rs2); + RWConnect(csu.rs2_is_in_ROB, rs.rs2_is_in_ROB); + RWConnect(csu.rs2_in_ROB_value, rs.rs2_in_ROB_value); + RWConnect(csu.decoded_imm, rs.decoded_imm); + RWConnect(csu.decoded_shamt, rs.decoded_shamt); + RWConnect(csu.cache_hit, rs.cache_hit); + RWConnect(csu.cache_hit_ROB_index, rs.cache_hit_ROB_index); + RWConnect(csu.cache_hit_data, rs.cache_hit_data); + RWConnect(rs.RS_remain_space_output, csu.reservestation_emptyspace_receiver); + // memory <-> lsq + RWConnect(memory.data_sign, lsq.mem_data_sign); + RWConnect(memory.completed_memins_ROB_index, lsq.completed_memins_ROB_index); + RWConnect(memory.completed_memins_read_data, lsq.completed_memins_read_data); + RWConnect(lsq.request_type_output, memory.request_type_input); + RWConnect(lsq.request_ROB_index, memory.request_ROB_index); + RWConnect(lsq.request_address_output, memory.address_input); + RWConnect(lsq.request_data_output, memory.data_input); + // memory <-> alu : no connections + // memory <-> register file : no connections + // memory <-> reserve station : + RWConnect(memory.data_sign, rs.mem_status_receiver); + RWConnect(memory.completed_memins_ROB_index, rs.completed_memins_ROB_index); + RWConnect(memory.completed_memins_read_data, rs.completed_memins_read_data); + // lsq <-> alu : + RWConnect(alu.alu_status, lsq.alu_status_receiver); + RWConnect(alu.result_ROB_index, lsq.completed_aluins_ROB_index); + RWConnect(alu.result, lsq.completed_aluins_result); + // lsq <-> register file + RWConnect(rf.rs1_nodep, lsq.rs1_nodep); + RWConnect(rf.rs1_deps, lsq.rs1_deps); + RWConnect(rf.rs1_value, lsq.rs1_value); + RWConnect(rf.rs2_nodep, lsq.rs2_nodep); + RWConnect(rf.rs2_deps, lsq.rs2_deps); + RWConnect(rf.rs2_value, lsq.rs2_value); + // lsq <-> reserve station : no connections + // alu <-> register file : no connections + // alu <-> reserve station + RWConnect(rs.request_full_id, alu.request_full_id); + RWConnect(rs.operand1, alu.operand1); + RWConnect(rs.operand2, alu.operand2); + RWConnect(rs.request_ROB_index, alu.request_ROB_index); + RWConnect(alu.alu_status, rs.alu_status_receiver); + RWConnect(alu.result_ROB_index, rs.completed_aluins_ROB_index); + RWConnect(alu.result, rs.completed_aluins_result); + // register file <-> reserve station + RWConnect(rf.rs1_nodep, rs.rs1_nodep); + RWConnect(rf.rs1_deps, rs.rs1_deps); + RWConnect(rf.rs1_value, rs.rs1_value); + RWConnect(rf.rs2_nodep, rs.rs2_nodep); + RWConnect(rf.rs2_deps, rs.rs2_deps); + RWConnect(rf.rs2_value, rs.rs2_value); + // now start running std::cout << cpu.run(0, true) << std::endl; return 0; } \ No newline at end of file