From 1ff419b22dc95653accba636d2e986c1069e2207 Mon Sep 17 00:00:00 2001 From: ZhuangYumin Date: Thu, 1 Aug 2024 04:13:59 +0000 Subject: [PATCH] can halt --- include/alu.h | 5 ++++- include/cpu.h | 9 ++++++--- include/csu.h | 37 ++++++++++++++++++++++++++++++------- include/loadstorequeue.h | 18 ++++++++++++++++++ include/memory.h | 13 +++++++++++-- include/registerfile.h | 21 +++++++++++++++++++-- include/reservestation.h | 7 +++++++ include/wire.h | 1 + src/main.cpp | 3 ++- 9 files changed, 98 insertions(+), 16 deletions(-) diff --git a/include/alu.h b/include/alu.h index 994fc6f..5e6d57d 100644 --- a/include/alu.h +++ b/include/alu.h @@ -24,7 +24,8 @@ struct ALU : public dark::Module { } void work() { std::cerr << "ALU: cur request_full_id=" << std::hex << std::setw(8) << std::setfill('0') << std::uppercase - << static_cast(request_full_id) << std::endl; + << static_cast(request_full_id) << " request_ROB_index=" << std::dec + << static_cast(request_ROB_index) << std::endl; switch (static_cast(request_full_id)) { case 0: { alu_status <= 0b01; @@ -66,6 +67,8 @@ struct ALU : public dark::Module { alu_status <= 0b10; result_ROB_index <= request_ROB_index; result <= static_cast(request_PC) + 4; + std::cerr << "alu: jalr: imm=" << std::hex << static_cast(imm) << std::endl; + std::cerr << "alu: jalr: operand1=" << std::hex << static_cast(operand1) << std::endl; completed_alu_resulting_PC <= ((static_cast(operand1) + static_cast(imm)) & 0xfffffffe); return; } diff --git a/include/cpu.h b/include/cpu.h index 480f945..3acd9e1 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -1,4 +1,5 @@ #pragma once +#include "concept.h" #include "module.h" #include "wire.h" #include @@ -64,11 +65,13 @@ public: auto func = shuffle ? &CPU::run_once_shuffle : &CPU::run_once; reset_signal=true; while (max_cycles == 0 || cycles < max_cycles) { - std::cerr<<"clock: "<*func)(); reset_signal=false; - uint32_t halt_signal_value = max_size_t(halt_signal); - if(halt_signal_value &(1<<9)) { + halt_signal.sync(); + uint32_t halt_signal_value = static_cast(halt_signal); + std::cerr<<"simulator received halt_signal_value="< a0; dark::Wire<1> reset; // data from load store queue dark::Wire<6> load_store_queue_emptyspace_receiver; @@ -262,7 +263,8 @@ struct CentralScheduleUnit } ROB_next_remain_space++; if (record.instruction == 0x0ff00513) { - halt_signal <= 0b100000000; + halt_signal <= (0b100000000 | static_cast(a0)); + std::cerr << "halting with code " << std::dec << int(halt_signal.peek()) << std::endl; } } } @@ -281,23 +283,28 @@ struct CentralScheduleUnit record.resulting_register_value <= res_data; if (!bool(record.resulting_PC_ready)) { record.resulting_PC <= res_PC; - if (res_PC != static_cast(record.resulting_PC)) { + if (res_PC != static_cast(record.resulting_PC) && + (static_cast(record.instruction) & 0x7F) != 0b1100111) { record.PC_mismatch_mark <= 1; } record.resulting_PC_ready <= 1; if ((static_cast(record.instruction) & 0x7F) == 0b1100111) { has_predicted_PC <= 1; - predicted_PC <= record.resulting_PC; + predicted_PC <= res_PC; + std::cerr << "The jalr instruction is committed, now predicted_PC is " << std::hex << std::setw(8) + << std::setfill('0') << std::uppercase << predicted_PC.peek() << std::endl; } } record.state <= 3; } } }; + std::cerr << "csu is listening data from memory" << std::endl; if (static_cast(mem_status_receiver) == 0b10) { process_data(static_cast(completed_memins_ROB_index), static_cast(completed_memins_read_data), 0); } + std::cerr << "csu is listening data from alu" << std::endl; if (static_cast(alu_status_receiver) == 0b10) { process_data(static_cast(completed_aluins_ROB_index), static_cast(completed_aluins_result), @@ -383,7 +390,7 @@ struct CentralScheduleUnit break; case 0b1100111: // jalr - std::cerr<<"encounter jalr"<(this->decoded_rs1); uint8_t found_rs1 = 0; uint32_t rs1_v; uint8_t rs2 = static_cast(this->decoded_rs2); uint8_t found_rs2 = 0; uint32_t rs2_v; - for (uint32_t ptr = static_cast(ROB_head); ptr != static_cast(ROB_tail); + for (uint32_t ptr = static_cast(ROB_head); + ptr != static_cast(ROB_tail) && (ptr + 1) % kROBSize != static_cast(ROB_tail); ptr = (ptr + 1) % kROBSize) { if (ROB_records[ptr].state.peek() == 3) { - if (static_cast(ROB_records[ptr].resulting_register_idx) == rs1) { + if (bool(ROB_records[ptr].has_resulting_register) && + static_cast(ROB_records[ptr].resulting_register_idx) == rs1) { rs1_v = ROB_records[ptr].resulting_register_value.peek(); found_rs1 = 1; + std::cerr << "matching rs1=" << std::dec << int(rs1) << " ptr=" << std::dec << ptr << " rs1_v=" << std::hex + << std::setw(8) << std::setfill('0') << rs1_v << std::endl; } - if (static_cast(ROB_records[ptr].resulting_register_idx) == rs2) { + if (bool(ROB_records[ptr].has_resulting_register) && + static_cast(ROB_records[ptr].resulting_register_idx) == rs2) { rs2_v = ROB_records[ptr].resulting_register_value.peek(); found_rs2 = 1; } + } else { + if (bool(ROB_records[ptr].has_resulting_register) && + static_cast(ROB_records[ptr].resulting_register_idx) == rs1) { + found_rs1 = 0; + std::cerr << "dematching rs1=" << std::dec << int(rs1) << " ptr=" << std::dec << ptr << std::endl; + } + if (bool(ROB_records[ptr].has_resulting_register) && + static_cast(ROB_records[ptr].resulting_register_idx) == rs2) { + found_rs2 = 0; + } } } this->rs1_is_in_ROB <= found_rs1; diff --git a/include/loadstorequeue.h b/include/loadstorequeue.h index 611ffdb..5bef6fb 100644 --- a/include/loadstorequeue.h +++ b/include/loadstorequeue.h @@ -124,6 +124,16 @@ struct LoadStoreQueue : public dark::Module(full_ins_id) << std::endl; + std::cerr << "\tins_ROB_index: " << std::dec << static_cast(issue_ROB_index) << std::endl; + std::cerr << "\tins_self_PC: " << std::hex << std::setw(8) << std::setfill('0') + << static_cast(issuing_PC) << std::endl; + std::cerr << "\tins_imm: " << std::hex << static_cast(decoded_imm) << std::endl; + std::cerr << "\thas_decoded_rs1: " << std::hex << std::setw(8) << std::setfill('0') + << static_cast(has_decoded_rs1) << std::endl; + std::cerr << "\thas_decoded_rs2: " << std::hex << std::setw(8) << std::setfill('0') + << static_cast(has_decoded_rs2) << std::endl; // LSQ_queue[cur_queue_tail].Q1 <= decoded_rs1; // temporarily, no use // LSQ_queue[cur_queue_tail].Q2 <= decoded_rs2; // temporarily, no use } else @@ -134,10 +144,13 @@ struct LoadStoreQueue : public dark::Module(alu_status_receiver) == 0b10) { process_listend_data(static_cast(completed_aluins_ROB_index), static_cast(completed_aluins_result)); } + std::cerr << "Load Store Queue is listening data from memory" << std::endl; if (static_cast(mem_data_sign) == 0b10) { process_listend_data(static_cast(completed_memins_ROB_index), static_cast(completed_memins_read_data)); diff --git a/include/memory.h b/include/memory.h index c89d796..b08ca55 100644 --- a/include/memory.h +++ b/include/memory.h @@ -116,6 +116,8 @@ struct Memory : dark::Module { } } completed_memins_read_data <= tmp; + std::cerr << "memory read: " << std::hex << std::setfill('0') << std::setw(2) << tmp << " from " << std::hex + << static_cast(cur_opt_addr) << std::endl; break; } case 2: { @@ -127,10 +129,15 @@ struct Memory : dark::Module { } } completed_memins_read_data <= tmp; + std::cerr << "memory read: " << std::hex << std::setfill('0') << std::setw(4) << tmp << " from " << std::hex + << static_cast(cur_opt_addr) << std::endl; break; } case 4: completed_memins_read_data <= *reinterpret_cast(&memory_data[max_size_t(cur_opt_addr)]); + std::cerr << "memory read: " << std::hex << std::setfill('0') << std::setw(8) + << *reinterpret_cast(&memory_data[max_size_t(cur_opt_addr)]) << " from " << std::hex + << static_cast(cur_opt_addr) << std::endl; break; default: throw std::runtime_error("Invalid bytes"); @@ -181,11 +188,12 @@ struct Memory : dark::Module { playback[cur_opt_ROB_index].changes[3].addr <= cur_opt_addr + 3; playback[cur_opt_ROB_index].changes[3].before <= memory_data[max_size_t(cur_opt_addr) + 3]; *reinterpret_cast(&memory_data[max_size_t(cur_opt_addr)]) = max_size_t(cur_opt_data); + std::cerr << "Memory executing sw" << std::endl; break; default: throw std::runtime_error("Invalid bytes"); } - data_sign <= 1; // free + data_sign <= 2; // free return; } } @@ -201,6 +209,7 @@ struct Memory : dark::Module { cur_opt_data <= data_input; cur_opt_type <= rw_type; cur_opt_bytes <= opt_bytes; + std::cerr << "Memory is accepting a request" << std::endl; } max_size_t FetchInstruction(max_size_t addr) { // assume we have a super nb instruction fetch method that can fetch // an instruction immediately @@ -228,7 +237,7 @@ struct Memory : dark::Module { 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; + // << (int)buf[i] << std::endl; } fin.clear(); } while (!fin.eof()); diff --git a/include/registerfile.h b/include/registerfile.h index 3933b0a..d6c62e0 100644 --- a/include/registerfile.h +++ b/include/registerfile.h @@ -1,4 +1,5 @@ #pragma once +#include #include "concept.h" #ifndef REGISTERFILE_H #include @@ -43,6 +44,7 @@ struct RegisterFile : public dark::Module(decoded_rs1) == 0) { + rs1_deps <= 0; + rs1_value <= 0; + rs1_nodep <= 1; + } else if ((!bool(is_committing)) || (commit_reg_index != decoded_rs1)) { rs1_deps <= register_deps[static_cast(decoded_rs1)].peek(); rs1_value <= registers[static_cast(decoded_rs1)].peek(); rs1_nodep <= register_nodep[static_cast(decoded_rs1)].peek(); @@ -75,9 +82,16 @@ struct RegisterFile : public dark::Module_M_holds = false; } + friend class CPU; template _Fn> static auto _M_new_func(_Fn &&fn) { diff --git a/src/main.cpp b/src/main.cpp index 22f6171..2b7980b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -35,6 +35,7 @@ int main(int argc, char **argv) { // alu.reset.assign([&]() { return cpu.GetResetSignal(); }); rf.reset.assign([&]() { return cpu.GetResetSignal(); }); rs.reset.assign([&]() { return cpu.GetResetSignal(); }); + csu.a0.assign([&]() { return rf.ReturnExitCodeImmediately(); }); // now connect the wires, see the comment and docs for help // csu <-> memory RWConnect(csu.force_clear_announcer, memory.force_clear_receiver); @@ -169,6 +170,6 @@ int main(int argc, char **argv) { RWConnect(rf.rs2_deps, rs.rs2_deps); RWConnect(rf.rs2_value, rs.rs2_value); // now start running - std::cout << cpu.run(100, false) << std::endl; + std::cout << uint32_t(cpu.run(1000, false)) << std::endl; return 0; } \ No newline at end of file