diff --git a/include/csu.h b/include/csu.h index cfe5210..be512af 100644 --- a/include/csu.h +++ b/include/csu.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include "concept.h" #ifndef CSU_H #include @@ -57,24 +58,27 @@ struct CentralScheduleUnit_Output { 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; + // dark::Register<1> cache_hit; + // dark::Register<5> cache_hit_ROB_index; + // dark::Register<32> cache_hit_data; dark::Register<1> is_committing; + dark::Register<1> commit_has_resulting_register; dark::Register<5> commit_reg_index; dark::Register<32> commit_reg_value; dark::Register<5> commit_ins_ROB_index; }; struct ROBRecordType { - dark::Register<4> state; + dark::Register<4> state; // 0: no entry; 1: just issued; 2: waiting; 3: ready to commit dark::Register<32> instruction; + dark::Register<1> has_resulting_register; 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; + dark::Register<1> PC_mismatch_mark; + // 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> predicted_PC; @@ -167,7 +171,7 @@ struct CentralScheduleUnit } uint8_t funct3 = ins >> 12 & 0x7; full_ins_id = opcode | (funct3 << 7); - } else if(opcode==0b0110111) { + } else if (opcode == 0b0110111) { // U-type has_decoded_rd = 1; has_decoded_rs1 = 0; @@ -175,19 +179,20 @@ struct CentralScheduleUnit decoded_rd = ins >> 7 & 0x1F; decoded_imm = ins >> 12; full_ins_id = opcode; - } else if(opcode==0b1101111) { + } else if (opcode == 0b1101111) { // J-type has_decoded_rd = 1; has_decoded_rs1 = 0; has_decoded_rs2 = 0; decoded_rd = ins >> 7 & 0x1F; - decoded_imm = (ins & 0xFF000) | (((ins >> 20) & 1)<<11) | (((ins >> 21) & 0x3FF)<<1) | ((ins >> 31) << 20); + decoded_imm = (ins & 0xFF000) | (((ins >> 20) & 1) << 11) | (((ins >> 21) & 0x3FF) << 1) | ((ins >> 31) << 20); uint32_t sign_bit = ins >> 31; if (sign_bit) { decoded_imm = static_cast(decoded_imm) | 0xFFE00000; } full_ins_id = opcode; - } else throw std::runtime_error("Unknown instruction in Decode"); + } else + throw std::runtime_error("Unknown instruction in Decode"); return std::make_tuple(full_ins_id, decoded_rd, has_decoded_rd, decoded_rs1, has_decoded_rs1, decoded_rs2, has_decoded_rs2, decoded_imm, decoded_shamt); } @@ -207,12 +212,225 @@ struct CentralScheduleUnit ROB_head <= 0; ROB_tail <= 0; ROB_remain_space <= kROBSize; + for (auto &record : ROB_records) { + record.state <= 0; + record.PC_mismatch_mark <= 0; + } + has_instruction_issued_last_cycle <= 0; + is_issuing <= 0; + return; + } + if (bool(force_clear_announcer)) { + force_clear_announcer <= 0; + ROB_head <= 0; + ROB_tail <= 0; + ROB_remain_space <= kROBSize; + for (auto &record : ROB_records) { + record.state <= 0; + record.PC_mismatch_mark <= 0; + } + predicted_PC <= actual_PC; + has_predicted_PC <= 1; + has_instruction_issued_last_cycle <= 0; + is_issuing <= 0; + return; } // STEP1: try to commit and see if we need to rollback - // process memory access request from LSQ + uint32_t ROB_next_remain_space = static_cast(ROB_remain_space); + { + uint32_t i = -1; + for (auto &record : ROB_records) { + ++i; + if (static_cast(record.state) != 3) continue; + ROB_head <= (static_cast(ROB_head) + 1) % kROBSize; + is_committing <= 1; + commit_has_resulting_register <= record.has_resulting_register; + commit_reg_index <= record.resulting_register_idx; + commit_reg_value <= record.resulting_register_value; + commit_ins_ROB_index <= i; + actual_PC <= static_cast(record.resulting_PC); + if (static_cast(record.PC_mismatch_mark) == 1) { + force_clear_announcer <= 1; + } + ROB_next_remain_space++; + break; + } + } + if (force_clear_announcer.peek()) { + ROB_remain_space <= ROB_next_remain_space; + return; + } // listen to the data from Memory and ALU + auto process_data = [&](uint32_t res_ROB_index, uint32_t res_data, uint32_t res_PC) { + uint32_t i = -1; + for (auto &record : ROB_records) { + ++i; + if (static_cast(record.state) != 2) continue; + if (i == res_ROB_index) { + 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)) { + 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; + } + } + record.state <= 3; + } + } + }; + if (static_cast(mem_status_receiver) == 0b10) { + process_data(static_cast(completed_memins_ROB_index), + static_cast(completed_memins_read_data), 0); + } + if (static_cast(alu_status_receiver) == 0b10) { + process_data(static_cast(completed_aluins_ROB_index), + static_cast(completed_aluins_result), + static_cast(completed_alu_resulting_PC)); + } // try to issue and check if we need to stall + if (bool(has_predicted_PC)) { // currently not in stall state + uint32_t instruction = instruction_fetcher(static_cast(predicted_PC)); + auto decoded_tuple = Decode(instruction); + uint32_t full_ins_id = static_cast(std::get<0>(decoded_tuple)); + uint8_t decoded_rd = static_cast(std::get<1>(decoded_tuple)); + uint8_t has_decoded_rd = static_cast(std::get<2>(decoded_tuple)); + uint8_t decoded_rs1 = static_cast(std::get<3>(decoded_tuple)); + uint8_t has_decoded_rs1 = static_cast(std::get<4>(decoded_tuple)); + uint8_t decoded_rs2 = static_cast(std::get<5>(decoded_tuple)); + uint8_t has_decoded_rs2 = static_cast(std::get<6>(decoded_tuple)); + uint32_t decoded_imm = static_cast(std::get<7>(decoded_tuple)); + uint8_t decoded_shamt = static_cast(std::get<8>(decoded_tuple)); + if ((full_ins_id & 0x7F) == 0b0000011 || (full_ins_id & 0x7F) == 0b0100011) { + // memory instruction + int32_t actual_remain_space = static_cast(load_store_queue_emptyspace_receiver) - + static_cast(has_instruction_issued_last_cycle); + if (ROB_next_remain_space > 0 && actual_remain_space > 0) { + // can issue + is_issuing <= 1; + has_instruction_issued_last_cycle <= 1; + uint32_t tail = static_cast(ROB_tail); + ROB_tail <= (tail + 1) % kROBSize; + ROB_next_remain_space--; + predicted_PC <= static_cast(predicted_PC) + 4; + ROB_records[tail].state <= 1; + ROB_records[tail].instruction <= instruction; + ROB_records[tail].has_resulting_register <= has_decoded_rd; + ROB_records[tail].resulting_register_idx <= decoded_rd; + ROB_records[tail].resulting_PC_ready <= 1; + ROB_records[tail].resulting_PC <= static_cast(predicted_PC) + 4; + ROB_records[tail].PC_mismatch_mark <= 0; + this->issue_type <= 1; + this->issue_ROB_index <= tail; + this->full_ins_id <= full_ins_id; + this->full_ins <= instruction; + this->issuing_PC <= static_cast(predicted_PC); + this->decoded_rd <= decoded_rd; + this->has_decoded_rd <= has_decoded_rd; + this->decoded_rs1 <= decoded_rs1; + this->has_decoded_rs1 <= has_decoded_rs1; + this->decoded_rs2 <= decoded_rs2; + this->has_decoded_rs2 <= has_decoded_rs2; + this->decoded_imm <= decoded_imm; + this->decoded_shamt <= decoded_shamt; + } else { + has_instruction_issued_last_cycle <= 0; + is_issuing <= 0; + } + } else { + // alu instruction + int32_t actual_remain_space = static_cast(reservestation_emptyspace_receiver) - + static_cast(has_instruction_issued_last_cycle); + if (ROB_next_remain_space > 0 && actual_remain_space > 0) { + // can issue + is_issuing <= 1; + has_instruction_issued_last_cycle <= 1; + uint32_t tail = static_cast(ROB_tail); + ROB_tail <= (tail + 1) % kROBSize; + ROB_next_remain_space--; + ROB_records[tail].state <= 1; + ROB_records[tail].instruction <= instruction; + ROB_records[tail].has_resulting_register <= has_decoded_rd; + ROB_records[tail].resulting_register_idx <= decoded_rd; + if ((full_ins_id & 0x7F) == 0b1100011 || ((full_ins_id & 0x7F) == 0b1100111) || + ((full_ins_id & 0x7F) == 0b1101111)) { + switch (full_ins_id & 0x7F) { + case 0b1101111: + // jal + ROB_records[tail].resulting_PC_ready <= 1; + ROB_records[tail].resulting_PC <= static_cast(predicted_PC) + decoded_imm; + break; + case 0b1100111: + // jalr + ROB_records[tail].resulting_PC_ready <= 0; + has_predicted_PC <= 0; + break; + case 0b1100011: + // branch + ROB_records[tail].resulting_PC_ready <= 0; + ROB_records[tail].resulting_PC <= static_cast(predicted_PC) + decoded_imm; // just guess + break; + } + } else { + ROB_records[tail].resulting_PC_ready <= 1; + ROB_records[tail].resulting_PC <= static_cast(predicted_PC) + 4; + } + predicted_PC <= ROB_records[tail].resulting_PC.peek(); + ROB_records[tail].PC_mismatch_mark <= 0; + this->issue_type <= 0; + this->issue_ROB_index <= tail; + this->full_ins_id <= full_ins_id; + this->full_ins <= instruction; + this->issuing_PC <= static_cast(predicted_PC); + this->decoded_rd <= decoded_rd; + this->has_decoded_rd <= has_decoded_rd; + this->decoded_rs1 <= decoded_rs1; + this->has_decoded_rs1 <= has_decoded_rs1; + this->decoded_rs2 <= decoded_rs2; + this->has_decoded_rs2 <= has_decoded_rs2; + this->decoded_imm <= decoded_imm; + this->decoded_shamt <= decoded_shamt; + } else { + has_instruction_issued_last_cycle <= 0; + is_issuing <= 0; + } + } + } else { + has_instruction_issued_last_cycle <= 0; + is_issuing <= 0; + } // provide the potentially missing data for instruction issued last cycle + if (bool(has_instruction_issued_last_cycle)) { + uint8_t rs1 = static_cast(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); + ptr = (ptr + 1) % kROBSize) { + if (ROB_records[ptr].state.peek() == 3) { + if (static_cast(ROB_records[ptr].resulting_register_idx) == rs1) { + rs1_v = ROB_records[ptr].resulting_register_value.peek(); + found_rs1 = 1; + } + if (static_cast(ROB_records[ptr].resulting_register_idx) == rs2) { + rs2_v = ROB_records[ptr].resulting_register_value.peek(); + found_rs2 = 1; + } + } + } + this->rs1_is_in_ROB <= found_rs1; + this->rs1_in_ROB_value <= rs1_v; + this->rs2_is_in_ROB <= found_rs2; + this->rs2_in_ROB_value <= rs2_v; + } + // other data + ROB_remain_space <= ROB_next_remain_space; } }; } // namespace ZYM diff --git a/include/loadstorequeue.h b/include/loadstorequeue.h index 952cf86..7e90f58 100644 --- a/include/loadstorequeue.h +++ b/include/loadstorequeue.h @@ -43,9 +43,9 @@ struct LoadStoreQueue_Input { dark::Wire<5> completed_memins_ROB_index; dark::Wire<32> completed_memins_read_data; // receive status signal from L0 cache - dark::Wire<1> cache_hit; - dark::Wire<5> cache_hit_ROB_index; - dark::Wire<32> cache_hit_data; + // dark::Wire<1> cache_hit; + // dark::Wire<5> cache_hit_ROB_index; + // dark::Wire<32> cache_hit_data; }; struct LoadStoreQueue_Output { // request signal, Memory and the L0 cache in ROB will listen to this @@ -159,7 +159,7 @@ struct LoadStoreQueue : public dark::Module void { uint32_t ptr = static_cast(LSQ_head); while (ptr != static_cast(LSQ_tail)) { @@ -196,9 +196,9 @@ struct LoadStoreQueue : public dark::Module(completed_memins_ROB_index), static_cast(completed_memins_read_data)); } - if (static_cast(cache_hit) == 1) { - process_listend_data(static_cast(cache_hit_ROB_index), static_cast(cache_hit_data)); - } + // if (static_cast(cache_hit) == 1) { + // process_listend_data(static_cast(cache_hit_ROB_index), static_cast(cache_hit_data)); + // } if (should_monitor_V1) { LSQ_queue[last_idx].D1 <= 0; LSQ_queue[last_idx].Q1 <= rs1_deps; diff --git a/include/memory.h b/include/memory.h index 7a83a7e..dcd2d78 100644 --- a/include/memory.h +++ b/include/memory.h @@ -4,6 +4,7 @@ #ifndef MEMORY_H #include #include +#include #include #include "tools.h" using dark::max_size_t; @@ -16,22 +17,56 @@ struct Memory_Input { dark::Wire<32> address_input; dark::Wire<32> data_input; dark::Wire<5> request_ROB_index; + dark::Wire<1> is_committing; + dark::Wire<5> commit_ins_ROB_index; }; struct Memory_Output { dark::Register<2> data_sign; dark::Register<5> completed_memins_ROB_index; dark::Register<32> completed_memins_read_data; }; +struct Change { + dark::Register<1> this_byte_changed; + dark::Register<32> addr; + dark::Register<8> before; +}; +struct OperationPlayback { + dark::Register<1> has_uncommitted_write; + dark::Register<32> timestamp; + std::array changes; +}; struct Memory_Private { dark::Register<3> status; dark::Register<32> cur_opt_addr; dark::Register<32> cur_opt_data; dark::Register<2> cur_opt_type; dark::Register<2> cur_opt_bytes; + std::array playback; + dark::Register<32> cur_timestamp; }; struct Memory : dark::Module { private: std::vector memory_data; + void Undo() { + std::set>> undo_list; // (timestamp, (addr, before)) + for (int i = 0; i < 32; i++) { + if (bool(playback[i].has_uncommitted_write)) { + for (int j = 0; j < 4; j++) { + if (bool(playback[i].changes[j].this_byte_changed)) { + undo_list.insert(std::make_pair(static_cast(playback[i].timestamp), + std::make_pair(static_cast(playback[i].changes[j].addr), + static_cast(playback[i].changes[j].before)))); + } + } + } + } + size_t sz = undo_list.size(); + auto it = undo_list.end(); + for (int i = 0; i < sz; i++) { + it--; + memory_data[it->second.first] = it->second.second; + } + } public: Memory() { memory_data.resize(1 << 20, 0); } @@ -40,13 +75,22 @@ struct Memory : dark::Module { // do some initialization status <= 0; data_sign <= 1; + cur_timestamp <= 0; + for (int i = 0; i < 32; i++) playback[i].has_uncommitted_write <= 0; return; } if (bool(force_clear_receiver)) { status <= 0; data_sign <= 1; + Undo(); + cur_timestamp <= 0; + for (int i = 0; i < 32; i++) playback[i].has_uncommitted_write <= 0; return; } + if (bool(is_committing)) { + playback[static_cast(commit_ins_ROB_index)].has_uncommitted_write <= 0; + } + cur_timestamp <= static_cast(cur_timestamp) + 1; max_size_t request_type_signal = max_size_t(request_type_input); uint8_t rw_type = request_type_signal & 3; // 0b00->none,0b01->read,0b10->write,0b11->invalid uint8_t opt_bytes = (request_type_signal >> 2) & 3; // 0->1, 1->2, 2->4 @@ -91,24 +135,59 @@ struct Memory : dark::Module { default: throw std::runtime_error("Invalid bytes"); } + data_sign <= 2; // has data and free + return; } else { size_t len = 1 << max_size_t(cur_opt_bytes); + uint32_t cur_opt_ROB_index = static_cast(completed_memins_ROB_index); switch (len) { case 1: + playback[cur_opt_ROB_index].has_uncommitted_write <= 1; + playback[cur_opt_ROB_index].timestamp <= cur_timestamp; + playback[cur_opt_ROB_index].changes[0].this_byte_changed <= 1; + playback[cur_opt_ROB_index].changes[0].addr <= cur_opt_addr; + playback[cur_opt_ROB_index].changes[0].before <= memory_data[max_size_t(cur_opt_addr)]; + playback[cur_opt_ROB_index].changes[1].this_byte_changed <= 0; + playback[cur_opt_ROB_index].changes[2].this_byte_changed <= 0; + playback[cur_opt_ROB_index].changes[3].this_byte_changed <= 0; memory_data[max_size_t(cur_opt_addr)] = max_size_t(cur_opt_data) & 0xff; break; case 2: + playback[cur_opt_ROB_index].has_uncommitted_write <= 1; + playback[cur_opt_ROB_index].timestamp <= cur_timestamp; + playback[cur_opt_ROB_index].changes[0].this_byte_changed <= 1; + playback[cur_opt_ROB_index].changes[0].addr <= cur_opt_addr; + playback[cur_opt_ROB_index].changes[0].before <= memory_data[max_size_t(cur_opt_addr)]; + playback[cur_opt_ROB_index].changes[1].this_byte_changed <= 1; + playback[cur_opt_ROB_index].changes[1].addr <= cur_opt_addr + 1; + playback[cur_opt_ROB_index].changes[1].before <= memory_data[max_size_t(cur_opt_addr) + 1]; + playback[cur_opt_ROB_index].changes[2].this_byte_changed <= 0; + playback[cur_opt_ROB_index].changes[3].this_byte_changed <= 0; *reinterpret_cast(&memory_data[max_size_t(cur_opt_addr)]) = max_size_t(cur_opt_data) & 0xffff; break; case 4: + playback[cur_opt_ROB_index].has_uncommitted_write <= 1; + playback[cur_opt_ROB_index].timestamp <= cur_timestamp; + playback[cur_opt_ROB_index].changes[0].this_byte_changed <= 1; + playback[cur_opt_ROB_index].changes[0].addr <= cur_opt_addr; + playback[cur_opt_ROB_index].changes[0].before <= memory_data[max_size_t(cur_opt_addr)]; + playback[cur_opt_ROB_index].changes[1].this_byte_changed <= 1; + playback[cur_opt_ROB_index].changes[1].addr <= cur_opt_addr + 1; + playback[cur_opt_ROB_index].changes[1].before <= memory_data[max_size_t(cur_opt_addr) + 1]; + playback[cur_opt_ROB_index].changes[2].this_byte_changed <= 1; + playback[cur_opt_ROB_index].changes[2].addr <= cur_opt_addr + 2; + playback[cur_opt_ROB_index].changes[2].before <= memory_data[max_size_t(cur_opt_addr) + 2]; + playback[cur_opt_ROB_index].changes[3].this_byte_changed <= 1; + 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); break; default: throw std::runtime_error("Invalid bytes"); } + data_sign <= 1; // free + return; } - data_sign <= 2; // has data and free - return; } // now the memory is not busy if (request_type_signal == 0) { diff --git a/include/registerfile.h b/include/registerfile.h index 1ee3672..3933b0a 100644 --- a/include/registerfile.h +++ b/include/registerfile.h @@ -8,7 +8,7 @@ const static size_t kTotalRegisters = 32; struct RegisterFile_Input { // receive control signal from CSU dark::Wire<1> reset; - dark::Wire<1> force_clear_receiver; + // dark::Wire<1> force_clear_receiver; dark::Wire<1> is_issuing; dark::Wire<1> issue_type; dark::Wire<5> issue_ROB_index; @@ -21,6 +21,7 @@ struct RegisterFile_Input { dark::Wire<5> decoded_rs2; dark::Wire<1> has_decoded_rs2; dark::Wire<1> is_committing; + dark::Wire<1> has_resulting_register; dark::Wire<5> commit_ins_ROB_index; dark::Wire<5> commit_reg_index; dark::Wire<32> commit_reg_value; @@ -44,47 +45,49 @@ struct RegisterFile : public dark::Module(commit_reg_index)] <= commit_reg_value; - if(register_deps[static_cast(commit_reg_index)] == commit_ins_ROB_index) { - register_nodep[static_cast(commit_reg_index)] <= 1; + if (bool(is_committing)) { + if (bool(has_resulting_register)) { + registers[static_cast(commit_reg_index)] <= commit_reg_value; + if (register_deps[static_cast(commit_reg_index)] == commit_ins_ROB_index) { + register_nodep[static_cast(commit_reg_index)] <= 1; + } } } - if(bool(is_issuing)) { - if(bool(has_decoded_rs1)) { - if((!bool(is_committing))||(commit_reg_index != decoded_rs1)) { - rs1_deps <= register_deps[static_cast(decoded_rs1)]; - rs1_value <= registers[static_cast(decoded_rs1)]; - rs1_nodep <= register_nodep[static_cast(decoded_rs1)]; + if (bool(is_issuing)) { + if (bool(has_decoded_rs1)) { + 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(); } else { rs1_deps <= 0; rs1_value <= commit_reg_value; rs1_nodep <= 1; } } - if(bool(has_decoded_rs2)) { - if((!bool(is_committing))||(commit_reg_index != decoded_rs2)) { - rs2_deps <= register_deps[static_cast(decoded_rs2)]; - rs2_value <= registers[static_cast(decoded_rs2)]; - rs2_nodep <= register_nodep[static_cast(decoded_rs2)]; + if (bool(has_decoded_rs2)) { + if ((!bool(is_committing)) || (commit_reg_index != decoded_rs2)) { + rs2_deps <= register_deps[static_cast(decoded_rs2)].peek(); + rs2_value <= registers[static_cast(decoded_rs2)].peek(); + rs2_nodep <= register_nodep[static_cast(decoded_rs2)].peek(); } else { rs2_deps <= 0; rs2_value <= commit_reg_value; rs2_nodep <= 1; } } - if(bool(has_decoded_rd)) { + if (bool(has_decoded_rd)) { register_deps[static_cast(decoded_rd)] <= static_cast(issue_ROB_index); register_nodep[static_cast(decoded_rd)] <= 0; } diff --git a/include/reservestation.h b/include/reservestation.h index 6e7ac3d..89293d1 100644 --- a/include/reservestation.h +++ b/include/reservestation.h @@ -42,9 +42,9 @@ struct ReserveStation_Input { 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; + // 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: @@ -156,7 +156,7 @@ struct ReserveStation : public dark::Module(completed_memins_ROB_index), static_cast(completed_memins_read_data)); } - if (static_cast(cache_hit) == 1) { - process_listend_data(static_cast(cache_hit_ROB_index), static_cast(cache_hit_data)); + // if (static_cast(cache_hit) == 1) { + // process_listend_data(static_cast(cache_hit_ROB_index), static_cast(cache_hit_data)); + // } + if (should_monitor_V1) { + RS_records[last_idx].Q1 <= rs1_deps; + RS_records[last_idx].D1 <= 0; + } + if (should_monitor_V2) { + RS_records[last_idx].Q2 <= rs2_deps; + RS_records[last_idx].D2 <= 0; } // TODO: now, we can check if we can execute the instruction, memory and L0 cache will listen to this if (bool(has_accepted_ins_last_cycle)) RS_records[last_idx].state <= 2; diff --git a/src/main.cpp b/src/main.cpp index fb658de..2b6b1af 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -37,6 +37,8 @@ int main(int argc, char **argv) { // now connect the wires, see the comment and docs for help // csu <-> memory RWConnect(csu.force_clear_announcer, memory.force_clear_receiver); + RWConnect(csu.is_committing, memory.is_committing); + RWConnect(csu.commit_ins_ROB_index, memory.commit_ins_ROB_index); 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); @@ -59,9 +61,9 @@ int main(int argc, char **argv) { 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(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.mem_request_full_ins_id, csu.mem_request_full_ins_id); RWConnect(lsq.request_type_output, csu.mem_request_type_input); RWConnect(lsq.request_ROB_index, csu.mem_request_ROB_index); @@ -74,7 +76,7 @@ int main(int argc, char **argv) { 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.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); @@ -91,6 +93,7 @@ int main(int argc, char **argv) { // RWConnect(rf.rs2_nodep, csu.rs2_nodep); // RWConnect(rf.rs2_deps, csu.rs2_deps); RWConnect(csu.is_committing, rf.is_committing); + RWConnect(csu.commit_has_resulting_register, rf.has_resulting_register); RWConnect(csu.commit_reg_index, rf.commit_reg_index); RWConnect(csu.commit_reg_value, rf.commit_reg_value); RWConnect(csu.commit_ins_ROB_index, rf.commit_ins_ROB_index); @@ -114,9 +117,9 @@ int main(int argc, char **argv) { 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(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);