diff --git a/src/BASE_ISA.cpp b/src/BASE_ISA.cpp index 7678899..e493d63 100644 --- a/src/BASE_ISA.cpp +++ b/src/BASE_ISA.cpp @@ -92,7 +92,7 @@ bool BASE_ISA::Exec_LUI() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "LUI x" << std::dec << rd << " <- 0x" << std::hex - << imm << std::endl; + << imm << "\n"; } return true; @@ -111,7 +111,7 @@ bool BASE_ISA::Exec_AUIPC() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "AUIPC x" << std::dec << rd << " <- 0x" - << std::hex << imm << " + PC (0x" << new_pc << ")" << std::endl; + << std::hex << imm << " + PC (0x" << new_pc << ")" << "\n"; } return true; @@ -135,7 +135,7 @@ bool BASE_ISA::Exec_JAL() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "JAL: x" << std::dec << rd << " <- 0x" << std::hex << old_pc << std::dec << ". PC + 0x" << std::hex << mem_addr - << " -> PC (0x" << new_pc << ")" << std::endl; + << " -> PC (0x" << new_pc << ")" << "\n"; } return true; @@ -158,7 +158,7 @@ bool BASE_ISA::Exec_JALR() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "JALR: x" << std::dec << rd << " <- 0x" - << std::hex << old_pc + 4 << " PC <- 0x" << new_pc << std::endl; + << std::hex << old_pc + 4 << " PC <- 0x" << new_pc << "\n"; } return true; } @@ -182,7 +182,7 @@ bool BASE_ISA::Exec_BEQ() { log->SC_log(Log::INFO) << "BEQ x" << std::dec << rs1 << "(0x" << std::hex << regs->getValue(rs1) << ") == x" << std::dec << rs2 << "(0x" << std::hex << regs->getValue(rs2) << ")? -> PC (0x" << std::hex - << new_pc << ")" << std::dec << std::endl; + << new_pc << ")" << std::dec << "\n"; } return true; @@ -211,7 +211,7 @@ bool BASE_ISA::Exec_BNE() { log->SC_log(Log::INFO) << "BNE: x" << std::dec << rs1 << "(0x" << std::hex << val1 << ") == x" << std::dec << rs2 << "(0x" << std::hex << val2 << ")? -> PC (0x" << std::hex << new_pc << ")" << std::dec - << std::endl; + << "\n"; } return true; @@ -236,7 +236,7 @@ bool BASE_ISA::Exec_BLT() { << (int32_t) regs->getValue(rs1) << ") < x" << std::dec << rs2 << "(0x" << std::hex << (int32_t) regs->getValue(rs2) << ")? -> PC (0x" << std::hex << new_pc << ")" << std::dec - << std::endl; + << "\n"; } return true; @@ -261,7 +261,7 @@ bool BASE_ISA::Exec_BGE() { << (int32_t) regs->getValue(rs1) << ") > x" << std::dec << rs2 << "(0x" << std::hex << (int32_t) regs->getValue(rs2) << ")? -> PC (0x" << std::hex << new_pc << ")" << std::dec - << std::endl; + << "\n"; } return true; @@ -286,7 +286,7 @@ bool BASE_ISA::Exec_BLTU() { log->SC_log(Log::INFO) << "BLTU x" << std::dec << rs1 << "(0x" << std::hex << regs->getValue(rs1) << ") < x" << std::dec << rs2 << "(0x" << std::hex << regs->getValue(rs2) << ")? -> PC (0x" << std::hex - << new_pc << ")" << std::dec << std::endl; + << new_pc << ")" << std::dec << "\n"; } return true; @@ -310,7 +310,7 @@ bool BASE_ISA::Exec_BGEU() { log->SC_log(Log::INFO) << "BGEU x" << std::dec << rs1 << "(0x" << std::hex << regs->getValue(rs1) << ") > x" << std::dec << rs2 << "(0x" << std::hex << regs->getValue(rs2) << ")? -> PC (0x" << std::hex - << new_pc << ")" << std::dec << std::endl; + << new_pc << ")" << std::dec << "\n"; } return true; @@ -332,7 +332,7 @@ bool BASE_ISA::Exec_LB() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "LB: x" << rs1 << " + " << imm << " (@0x" - << std::hex << mem_addr << std::dec << ") -> x" << rd << std::endl; + << std::hex << mem_addr << std::dec << ") -> x" << rd << "\n"; } return true; @@ -354,7 +354,7 @@ bool BASE_ISA::Exec_LH() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "LH: x" << rs1 << " + " << imm << " (@0x" - << std::hex << mem_addr << std::dec << ") -> x" << rd << std::endl; + << std::hex << mem_addr << std::dec << ") -> x" << rd << "\n"; } return true; @@ -378,7 +378,7 @@ bool BASE_ISA::Exec_LW() { log->SC_log(Log::INFO) << std::dec << "LW: x" << rs1 << "(0x" << std::hex << regs->getValue(rs1) << ") + " << std::dec << imm << " (@0x" << std::hex << mem_addr << std::dec << ") -> x" << rd << std::hex - << " (0x" << data << ")" << std::endl; + << " (0x" << data << ")" << "\n"; } return true; } @@ -399,7 +399,7 @@ bool BASE_ISA::Exec_LBU() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "LBU: x" << rs1 << " + " << imm << " (@0x" - << std::hex << mem_addr << std::dec << ") -> x" << rd << std::endl; + << std::hex << mem_addr << std::dec << ") -> x" << rd << "\n"; } return true; } @@ -421,7 +421,7 @@ bool BASE_ISA::Exec_LHU() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "LHU: x" << std::dec << rs1 << " + " << imm << " (@0x" << std::hex << mem_addr << std::dec << ") -> x" << rd - << "(0x" << std::hex << data << ")" << std::endl; + << "(0x" << std::hex << data << ")" << "\n"; } return true; @@ -445,7 +445,7 @@ bool BASE_ISA::Exec_SB() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "SB: x" << std::dec << rs2 << " -> x" << rs1 << " + 0x" << std::hex << imm << " (@0x" << std::hex << mem_addr - << std::dec << ")" << std::endl; + << std::dec << ")" << "\n"; } return true; @@ -469,7 +469,7 @@ bool BASE_ISA::Exec_SH() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "SH: x" << std::dec << rs2 << " -> x" << rs1 << " + 0x" << std::hex << imm << " (@0x" << std::hex << mem_addr - << std::dec << ")" << std::endl; + << std::dec << ")" << "\n"; } return true; @@ -493,7 +493,7 @@ bool BASE_ISA::Exec_SW() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "SW: x" << std::dec << rs2 << "(0x" << std::hex << data << ") -> x" << std::dec << rs1 << " + 0x" << std::hex << imm - << " (@0x" << std::hex << mem_addr << std::dec << ")" << std::endl; + << " (@0x" << std::hex << mem_addr << std::dec << ")" << "\n"; } return true; } @@ -513,7 +513,7 @@ bool BASE_ISA::Exec_ADDI() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "ADDI: x" << std::dec << rs1 << " + " << imm << " -> x" << std::dec << rd << "(0x" << std::hex << calc << ")" - << std::endl; + << "\n"; } return true; @@ -530,11 +530,11 @@ bool BASE_ISA::Exec_SLTI() { if (regs->getValue(rs1) < imm) { regs->setValue(rd, 1); log->SC_log(Log::INFO) << "SLTI: x" << rs1 << " < " << imm << " => " - << "1 -> x" << rd << std::endl; + << "1 -> x" << rd << "\n"; } else { regs->setValue(rd, 0); log->SC_log(Log::INFO) << "SLTI: x" << rs1 << " < " << imm << " => " - << "0 -> x" << rd << std::endl; + << "0 -> x" << rd << "\n"; } return true; @@ -551,11 +551,11 @@ bool BASE_ISA::Exec_SLTIU() { if ((uint32_t) regs->getValue(rs1) < (uint32_t) imm) { regs->setValue(rd, 1); log->SC_log(Log::INFO) << "SLTIU: x" << rs1 << " < " << imm << " => " - << "1 -> x" << rd << std::endl; + << "1 -> x" << rd << "\n"; } else { regs->setValue(rd, 0); log->SC_log(Log::INFO) << "SLTIU: x" << rs1 << " < " << imm << " => " - << "0 -> x" << rd << std::endl; + << "0 -> x" << rd << "\n"; } return true; @@ -575,7 +575,7 @@ bool BASE_ISA::Exec_XORI() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "XORI: x" << rs1 << " XOR " << imm << "-> x" << rd - << std::endl; + << "\n"; } return true; @@ -595,7 +595,7 @@ bool BASE_ISA::Exec_ORI() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "ORI: x" << rs1 << " OR " << imm << "-> x" << rd - << std::endl; + << "\n"; } return true; @@ -618,7 +618,7 @@ bool BASE_ISA::Exec_ANDI() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "ANDI: x" << rs1 << "(0x" << std::hex << aux << ") AND 0x" << imm << " -> x" << std::dec << rd << "(0x" - << std::hex << calc << ")" << std::endl; + << std::hex << calc << ")" << "\n"; } return true; @@ -634,7 +634,7 @@ bool BASE_ISA::Exec_SLLI() { rs2 = get_shamt(); if (rs2 >= 0x20) { - std::cout << "ILEGAL INSTRUCTION, shamt[5] != 0" << std::endl; + std::cout << "ILEGAL INSTRUCTION, shamt[5] != 0" << "\n"; RaiseException(EXCEPTION_CAUSE_ILLEGAL_INSTRUCTION, m_instr); return false; @@ -647,7 +647,7 @@ bool BASE_ISA::Exec_SLLI() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "SLLI: x" << std::dec << rs1 << " << " << shift - << " -> x" << rd << "(0x" << std::hex << calc << ")" << std::endl; + << " -> x" << rd << "(0x" << std::hex << calc << ")" << "\n"; } return true; @@ -669,7 +669,7 @@ bool BASE_ISA::Exec_SRLI() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "SRLI: x" << std::dec << rs1 << " >> " << shift - << " -> x" << rd << std::endl; + << " -> x" << rd << "\n"; } return true; @@ -691,7 +691,7 @@ bool BASE_ISA::Exec_SRAI() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "SRAI: x" << std::dec << rs1 << " >> " << shift - << " -> x" << rd << std::endl; + << " -> x" << rd << "\n"; } return true; @@ -710,7 +710,7 @@ bool BASE_ISA::Exec_ADD() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "ADD: x" << std::dec << rs1 << " + x" << rs2 - << " -> x" << rd << std::hex << "(0x" << calc << ")" << std::endl; + << " -> x" << rd << std::hex << "(0x" << calc << ")" << "\n"; } return true; @@ -728,7 +728,7 @@ bool BASE_ISA::Exec_SUB() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "SUB: x" << rs1 << " - x" << rs2 << " -> x" << rd - << "(" << calc << ")" << std::endl; + << "(" << calc << ")" << "\n"; } return true; @@ -750,7 +750,7 @@ bool BASE_ISA::Exec_SLL() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "SLL: x" << rs1 << " << " << shift << " -> x" - << rd << std::endl; + << rd << "\n"; } return true; @@ -766,11 +766,11 @@ bool BASE_ISA::Exec_SLT() { if (regs->getValue(rs1) < regs->getValue(rs2)) { regs->setValue(rd, 1); log->SC_log(Log::INFO) << "SLT: x" << rs1 << " < x" << rs2 << " => " - << "1 -> x" << rd << std::endl; + << "1 -> x" << rd << "\n"; } else { regs->setValue(rd, 0); log->SC_log(Log::INFO) << "SLT: x" << rs1 << " < x" << rs2 << " => " - << "0 -> x" << rd << std::endl; + << "0 -> x" << rd << "\n"; } return true; @@ -786,11 +786,11 @@ bool BASE_ISA::Exec_SLTU() { if ((uint32_t) regs->getValue(rs1) < (uint32_t) regs->getValue(rs2)) { regs->setValue(rd, 1); log->SC_log(Log::INFO) << "SLTU: x" << rs1 << " < x" << rs2 << " => " - << "1 -> x" << rd << std::endl; + << "1 -> x" << rd << "\n"; } else { regs->setValue(rd, 0); log->SC_log(Log::INFO) << "SLTU: x" << rs1 << " < x" << rs2 << " => " - << "0 -> x" << rd << std::endl; + << "0 -> x" << rd << "\n"; } return true; @@ -809,7 +809,7 @@ bool BASE_ISA::Exec_XOR() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "XOR: x" << rs1 << " XOR x" << rs2 << "-> x" << rd - << std::endl; + << "\n"; } return true; @@ -831,7 +831,7 @@ bool BASE_ISA::Exec_SRL() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "SRL: x" << rs1 << " >> " << shift << " -> x" - << rd << std::endl; + << rd << "\n"; } return true; @@ -853,7 +853,7 @@ bool BASE_ISA::Exec_SRA() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "SRA: x" << rs1 << " >> " << shift << " -> x" - << rd << std::endl; + << rd << "\n"; } return true; @@ -872,7 +872,7 @@ bool BASE_ISA::Exec_OR() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "OR: x" << rs1 << " OR x" << rs2 << "-> x" << rd - << std::endl; + << "\n"; } return true; @@ -891,32 +891,32 @@ bool BASE_ISA::Exec_AND() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "AND: x" << rs1 << " AND x" << rs2 << "-> x" << rd - << std::endl; + << "\n"; } return true; } bool BASE_ISA::Exec_FENCE() { - log->SC_log(Log::INFO) << "FENCE" << std::endl; + log->SC_log(Log::INFO) << "FENCE" << "\n"; return true; } bool BASE_ISA::Exec_ECALL() { - log->SC_log(Log::INFO) << "ECALL" << std::endl; - std::cout << std::endl << "ECALL Instruction called, stopping simulation" - << std::endl; + log->SC_log(Log::INFO) << "ECALL" << "\n"; + std::cout << "\n" << "ECALL Instruction called, stopping simulation" + << "\n"; regs->dump(); - std::cout << "Simulation time " << sc_core::sc_time_stamp() << std::endl; + std::cout << "Simulation time " << sc_core::sc_time_stamp() << "\n"; perf->dump(); uint32_t gp_value = regs->getValue(Registers::gp); if (gp_value == 1) { - std::cout << "GP value is 1, test result is OK" << std::endl; + std::cout << "GP value is 1, test result is OK" << "\n"; } else { - std::cout << "GP value is " << gp_value << std::endl; + std::cout << "GP value is " << gp_value << "\n"; } //SC_REPORT_ERROR("Execute", "ECALL"); sc_core::sc_stop(); @@ -925,11 +925,11 @@ bool BASE_ISA::Exec_ECALL() { bool BASE_ISA::Exec_EBREAK() { - log->SC_log(Log::INFO) << "EBREAK" << std::endl; - std::cout << std::endl << "EBRAK Instruction called, dumping information" - << std::endl; + log->SC_log(Log::INFO) << "EBREAK" << "\n"; + std::cout << "\n" << "EBRAK Instruction called, dumping information" + << "\n"; regs->dump(); - std::cout << "Simulation time " << sc_core::sc_time_stamp() << std::endl; + std::cout << "Simulation time " << sc_core::sc_time_stamp() << "\n"; perf->dump(); RaiseException(EXCEPTION_CAUSE_BREAKPOINT, m_instr); @@ -957,7 +957,7 @@ bool BASE_ISA::Exec_CSRRW() { log->SC_log(Log::INFO) << std::hex << "CSRRW: CSR #" << csr << " -> x" << std::dec << rd << ". x" << rs1 << "-> CSR #" << std::hex << csr - << " (0x" << aux << ")" << std::endl; + << " (0x" << aux << ")" << "\n"; return true; } @@ -973,7 +973,7 @@ bool BASE_ISA::Exec_CSRRS() { if (rd == 0) { log->SC_log(Log::INFO) << "CSRRS with rd1 == 0, doing nothing." - << std::endl; + << "\n"; return false; } @@ -988,7 +988,7 @@ bool BASE_ISA::Exec_CSRRS() { log->SC_log(Log::INFO) << "CSRRS: CSR #" << csr << "(0x" << std::hex << aux << ") -> x" << std::dec << rd << ". x" << rs1 << " & CSR #" << csr - << " <- 0x" << std::hex << aux2 << std::endl; + << " <- 0x" << std::hex << aux2 << "\n"; return true; } @@ -1004,7 +1004,7 @@ bool BASE_ISA::Exec_CSRRC() { if (rd == 0) { log->SC_log(Log::INFO) << "CSRRC with rd1 == 0, doing nothing." - << std::endl; + << "\n"; return true; } @@ -1019,7 +1019,7 @@ bool BASE_ISA::Exec_CSRRC() { log->SC_log(Log::INFO) << "CSRRC: CSR #" << csr << "(0x" << std::hex << aux << ") -> x" << std::dec << rd << ". x" << rs1 << " & CSR #" << csr - << " <- 0x" << std::hex << aux2 << std::endl; + << " <- 0x" << std::hex << aux2 << "\n"; return true; } @@ -1042,7 +1042,7 @@ bool BASE_ISA::Exec_CSRRWI() { regs->setCSR(csr, aux); log->SC_log(Log::INFO) << "CSRRWI: CSR #" << csr << " -> x" << rd << ". x" - << rs1 << "-> CSR #" << csr << std::endl; + << rs1 << "-> CSR #" << csr << "\n"; return true; } @@ -1070,7 +1070,7 @@ bool BASE_ISA::Exec_CSRRSI() { log->SC_log(Log::INFO) << "CSRRSI: CSR #" << csr << " -> x" << rd << ". x" << rs1 << " & CSR #" << csr << "(0x" << std::hex << aux << ")" - << std::endl; + << "\n"; return true; } @@ -1098,7 +1098,7 @@ bool BASE_ISA::Exec_CSRRCI() { log->SC_log(Log::INFO) << "CSRRCI: CSR #" << csr << " -> x" << rd << ". x" << rs1 << " & CSR #" << csr << "(0x" << std::hex << aux << ")" - << std::endl; + << "\n"; return true; } @@ -1112,7 +1112,7 @@ bool BASE_ISA::Exec_MRET() { regs->setPC(new_pc); log->SC_log(Log::INFO) << "MRET: PC <- 0x" << std::hex << new_pc - << std::endl; + << "\n"; // update mstatus uint32_t csr_temp; @@ -1133,19 +1133,19 @@ bool BASE_ISA::Exec_SRET() { regs->setPC(new_pc); log->SC_log(Log::INFO) << "SRET: PC <- 0x" << std::hex << new_pc - << std::endl; + << "\n"; return true; } bool BASE_ISA::Exec_WFI() { - log->SC_log(Log::INFO) << "WFI" << std::endl; + log->SC_log(Log::INFO) << "WFI" << "\n"; return true; } bool BASE_ISA::Exec_SFENCE() { - log->SC_log(Log::INFO) << "SFENCE" << std::endl; + log->SC_log(Log::INFO) << "SFENCE" << "\n"; return true; } @@ -1317,7 +1317,7 @@ bool BASE_ISA::process_instruction(Instruction &inst) { Exec_SFENCE(); break; [[unlikely]] default: - std::cout << "Wrong instruction" << std::endl; + std::cout << "Wrong instruction" << "\n"; inst.dump(); NOP(); //sc_stop(); diff --git a/src/CPU64.cpp b/src/CPU64.cpp new file mode 100644 index 0000000..8c5d04c --- /dev/null +++ b/src/CPU64.cpp @@ -0,0 +1,221 @@ +/*! + \file CPU.cpp + \brief Main CPU class + \author Màrius Montón + \date August 2018 + */ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "CPU64.h" + +SC_HAS_PROCESS(CPU64); +CPU64::CPU64(sc_core::sc_module_name name, uint32_t PC) : + sc_module(name), instr_bus("instr_bus"), default_time(10, + sc_core::SC_NS) { + register_bank = new Registers(); + mem_intf = new MemoryInterface(); + + perf = Performance::getInstance(); + log = Log::getInstance(); + + register_bank->setPC(PC); + + //register_bank->setValue(Registers::sp, (0xD0000 / 4) - 1); + register_bank->setValue(Registers::sp, (0x10000000 / 4) - 1); + + irq_line_socket.register_b_transport(this, &CPU64::call_interrupt); + interrupt = false; + + int_cause = 0; + irq_already_down = false; + + dmi_ptr_valid = false; + instr_bus.register_invalidate_direct_mem_ptr(this, + &CPU64::invalidate_direct_mem_ptr); + + inst = new Instruction(0); + exec = new BASE_ISA(0, register_bank, mem_intf); + c_inst = new C_extension(0, register_bank, mem_intf); + m_inst = new M_extension(0, register_bank, mem_intf); + a_inst = new A_extension(0, register_bank, mem_intf); + + m_qk = new tlm_utils::tlm_quantumkeeper(); + + SC_THREAD(CPU_thread); +} + +CPU64::~CPU64() { + std::cout << "*********************************************" << std::endl; + register_bank->dump(); + std::cout << "end time: " << sc_core::sc_time_stamp() << std::endl; + perf->dump(); + std::cout << "*********************************************" << std::endl; + delete register_bank; + delete mem_intf; + delete inst; + delete exec; + delete c_inst; + delete m_inst; + delete a_inst; + delete m_qk; +} + +bool CPU64::cpu_process_IRQ() { + uint32_t csr_temp; + uint32_t new_pc, old_pc; + bool ret_value = false; + + if (interrupt == true) { + csr_temp = register_bank->getCSR(CSR_MSTATUS); + if ((csr_temp & MSTATUS_MIE) == 0) { + log->SC_log(Log::DEBUG) << "interrupt delayed" << std::endl; + return ret_value; + } + + csr_temp = register_bank->getCSR(CSR_MIP); + + if ((csr_temp & MIP_MEIP) == 0) { + csr_temp |= MIP_MEIP; // MEIP bit in MIP register (11th bit) + register_bank->setCSR(CSR_MIP, csr_temp); + log->SC_log(Log::DEBUG) << "Interrupt!" << std::endl; + + /* updated MEPC register */ + old_pc = register_bank->getPC(); + register_bank->setCSR(CSR_MEPC, old_pc); + log->SC_log(Log::INFO) << "Old PC Value 0x" << std::hex << old_pc + << std::endl; + + /* update MCAUSE register */ + register_bank->setCSR(CSR_MCAUSE, 0x80000000); + + /* set new PC address */ + new_pc = register_bank->getCSR(CSR_MTVEC); + //new_pc = new_pc & 0xFFFFFFFC; // last two bits always to 0 + log->SC_log(Log::DEBUG) << "NEW PC Value 0x" << std::hex << new_pc + << std::endl; + register_bank->setPC(new_pc); + + ret_value = true; + interrupt = false; + irq_already_down = false; + } + } else { + if (irq_already_down == false) { + csr_temp = register_bank->getCSR(CSR_MIP); + csr_temp &= ~MIP_MEIP; + register_bank->setCSR(CSR_MIP, csr_temp); + irq_already_down = true; + } + } + + return ret_value; +} + +void CPU64::CPU_thread(void) { + + tlm::tlm_generic_payload *trans = new tlm::tlm_generic_payload; + uint32_t INSTR; + sc_core::sc_time delay = sc_core::SC_ZERO_TIME; + bool PC_not_affected = false; + bool incPCby2 = false; + tlm::tlm_dmi dmi_data; + unsigned char *dmi_ptr = NULL; + + trans->set_command(tlm::TLM_READ_COMMAND); + trans->set_data_ptr(reinterpret_cast(&INSTR)); + trans->set_data_length(4); + trans->set_streaming_width(4); // = data_length to indicate no streaming + trans->set_byte_enable_ptr(0); // 0 indicates unused + trans->set_dmi_allowed(false); // Mandatory initial value + trans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); + + m_qk->reset(); + + while (1) { + /* Get new PC value */ + if (dmi_ptr_valid == true) { + /* if memory_offset at Memory module is set, this won't work */ + memcpy(&INSTR, dmi_ptr + register_bank->getPC(), 4); + } else { + trans->set_address(register_bank->getPC()); + instr_bus->b_transport(*trans, delay); + + if (trans->is_response_error()) { + SC_REPORT_ERROR("CPU base", "Read memory"); + } + + if (trans->is_dmi_allowed()) { + dmi_ptr_valid = instr_bus->get_direct_mem_ptr(*trans, dmi_data); + if (dmi_ptr_valid) { + std::cout << "Get DMI_PTR " << std::endl; + dmi_ptr = dmi_data.get_dmi_ptr(); + } + } + } + + perf->codeMemoryRead(); + + log->SC_log(Log::INFO) << "PC: 0x" << std::hex << register_bank->getPC() + << ". "; + + inst->setInstr(INSTR); + + /* check what type of instruction is and execute it */ + switch (inst->check_extension()) { + [[likely]] case BASE_EXTENSION: + PC_not_affected = exec->process_instruction(*inst); + incPCby2 = false; + break; + case C_EXTENSION: + PC_not_affected = c_inst->process_instruction(*inst); + incPCby2 = true; + break; + case M_EXTENSION: + PC_not_affected = m_inst->process_instruction(*inst); + incPCby2 = false; + break; + case A_EXTENSION: + PC_not_affected = a_inst->process_instruction(*inst); + incPCby2 = false; + break; + [[unlikely]] default: + std::cout << "Extension not implemented yet" << std::endl; + inst->dump(); + exec->NOP(); + } + + perf->instructionsInc(); + + if (PC_not_affected == true) { + register_bank->incPC(incPCby2); + } + + /* Process IRQ (if any) */ + cpu_process_IRQ(); + + /* Fixed instruction time to 10 ns (i.e. 100 MHz) */ +//#define USE_QK +#ifdef USE_QK + // Model time used for additional processing + m_qk->inc(default_time); + if (m_qk->need_sync()) { + m_qk->sync(); + } +#else + sc_core::wait(10, sc_core::SC_NS); + +#endif + + } // while(1) +} // CPU_thread + +void CPU64::call_interrupt(tlm::tlm_generic_payload &trans, + sc_core::sc_time &delay) { + interrupt = true; + /* Socket caller send a cause (its id) */ + memcpy(&int_cause, trans.get_data_ptr(), sizeof(uint32_t)); +} + +void CPU64::invalidate_direct_mem_ptr(sc_dt::uint64 start, sc_dt::uint64 end) { + dmi_ptr_valid = false; +} diff --git a/src/C_extension.cpp b/src/C_extension.cpp index 1c8f32b..52a7931 100644 --- a/src/C_extension.cpp +++ b/src/C_extension.cpp @@ -158,7 +158,7 @@ bool C_extension::Exec_C_JR() { regs->setPC(new_pc); if (log->getLogLevel() >= Log::INFO) { - log->SC_log(Log::INFO) << "JR: PC <- 0x" << std::hex << new_pc << std::endl; + log->SC_log(Log::INFO) << "JR: PC <- 0x" << std::hex << new_pc << "\n"; } return true; @@ -179,7 +179,7 @@ bool C_extension::Exec_C_MV() { log->SC_log(Log::INFO) << "C.MV: x" << std::dec << rs1 << "(0x" << std::hex << regs->getValue(rs1) << ") + x" << std::dec << rs2 << "(0x" << std::hex << regs->getValue(rs2) << ") -> x" << std::dec << rd - << "(0x" << std::hex << calc << ")" << std::endl; + << "(0x" << std::hex << calc << ")" << "\n"; } return true; @@ -198,7 +198,7 @@ bool C_extension::Exec_C_ADD() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "C.ADD: x" << std::dec << rs1 << " + x" << rs2 - << " -> x" << rd << "(0x" << std::hex << calc << ")" << std::endl; + << " -> x" << rd << "(0x" << std::hex << calc << ")" << "\n"; } return true; @@ -224,7 +224,7 @@ bool C_extension::Exec_C_LWSP() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "C.LWSP: x" << std::dec << rs1 << " + " << imm << " (@0x" << std::hex << mem_addr << std::dec << ") -> x" << rd - << "(" << std::hex << data << ")" << std::dec << std::endl; + << "(" << std::hex << data << ")" << std::dec << "\n"; } return true; @@ -250,7 +250,7 @@ bool C_extension::Exec_C_ADDI4SPN() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << std::dec << "C.ADDI4SPN: x" << rs1 << "(0x" << std::hex << regs->getValue(rs1) << ") + " << std::dec << imm - << " -> x" << rd << "(0x" << std::hex << calc << ")" << std::endl; + << " -> x" << rd << "(0x" << std::hex << calc << ")" << "\n"; } return true; @@ -272,14 +272,14 @@ bool C_extension::Exec_C_ADDI16SP() { log->SC_log(Log::INFO) << std::dec << "C.ADDI16SP: x" << rs1 << " + " << std::dec << imm << " -> x" << rd << "(0x" << std::hex << calc - << ")" << std::endl; + << ")" << "\n"; } else { /* C.LUI OPCODE */ rd = get_rd(); imm = get_imm_LUI(); regs->setValue(rd, imm); log->SC_log(Log::INFO) << std::dec << "C.LUI x" << rd << " <- 0x" - << std::hex << imm << std::endl; + << std::hex << imm << "\n"; } return true; @@ -304,7 +304,7 @@ bool C_extension::Exec_C_SWSP() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << std::dec << "C.SWSP: x" << rs2 << "(0x" << std::hex << data << ") -> x" << std::dec << rs1 << " + " << imm - << " (@0x" << std::hex << mem_addr << std::dec << ")" << std::endl; + << " (@0x" << std::hex << mem_addr << std::dec << ")" << "\n"; } return true; @@ -329,7 +329,7 @@ bool C_extension::Exec_C_BEQZ() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "C.BEQZ: x" << std::dec << rs1 << "(" << val1 << ") == 0? -> PC (0x" << std::hex << new_pc << ")" << std::dec - << std::endl; + << "\n"; } return true; @@ -354,7 +354,7 @@ bool C_extension::Exec_C_BNEZ() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "C.BNEZ: x" << std::dec << rs1 << "(0x" << std::hex << val1 << ") != 0? -> PC (0x" << std::hex << new_pc - << ")" << std::dec << std::endl; + << ")" << std::dec << "\n"; } return true; @@ -375,7 +375,7 @@ bool C_extension::Exec_C_LI() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << std::dec << "C.LI: x" << rs1 << "(" << regs->getValue(rs1) << ") + " << imm << " -> x" << rd << "(" - << calc << ")" << std::endl; + << calc << ")" << "\n"; } return true; @@ -397,7 +397,7 @@ bool C_extension::Exec_C_SRLI() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "C.SRLI: x" << rs1 << " >> " << shift << " -> x" - << rd << std::endl; + << rd << "\n"; } return true; @@ -419,7 +419,7 @@ bool C_extension::Exec_C_SRAI() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "C.SRAI: x" << rs1 << " >> " << std::dec << shift - << " -> x" << rd << "(" << calc << ")" << std::endl; + << " -> x" << rd << "(" << calc << ")" << "\n"; } return true; @@ -441,7 +441,7 @@ bool C_extension::Exec_C_SLLI() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "C.SLLI: x" << std::dec << rs1 << " << " << shift - << " -> x" << rd << "(0x" << calc << ")" << std::endl; + << " -> x" << rd << "(0x" << calc << ")" << "\n"; } return true; @@ -463,7 +463,7 @@ bool C_extension::Exec_C_ANDI() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "C.ANDI: x" << rs1 << "(" << aux << ") AND " - << imm << " -> x" << rd << std::endl; + << imm << " -> x" << rd << "\n"; } return true; @@ -482,7 +482,7 @@ bool C_extension::Exec_C_SUB() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "C.SUB: x" << std::dec << rs1 << " - x" << rs2 - << " -> x" << rd << std::endl; + << " -> x" << rd << "\n"; } return true; @@ -501,7 +501,7 @@ bool C_extension::Exec_C_XOR() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "C.XOR: x" << std::dec << rs1 << " XOR x" << rs2 - << "-> x" << rd << std::endl; + << "-> x" << rd << "\n"; } return true; @@ -520,7 +520,7 @@ bool C_extension::Exec_C_OR() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "C_OR: x" << std::dec << rs1 << " OR x" << rs2 - << "-> x" << rd << std::endl; + << "-> x" << rd << "\n"; } return true; @@ -539,7 +539,7 @@ bool C_extension::Exec_C_AND() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "C.AND: x" << std::dec << rs1 << " AND x" << rs2 - << "-> x" << rd << std::endl; + << "-> x" << rd << "\n"; } return true; @@ -560,7 +560,7 @@ bool C_extension::Exec_C_ADDI() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "C.ADDI: x" << std::dec << rs1 << " + " << imm << " -> x" << std::dec << rd << "(0x" << std::hex << calc << ")" - << std::endl; + << "\n"; } return true; @@ -583,7 +583,7 @@ bool C_extension::Exec_C_JALR() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "C.JALR: x" << std::dec << rd << " <- 0x" << std::hex << old_pc + 4 << " PC <- 0x" << std::hex << new_pc - << std::endl; + << "\n"; } return true; @@ -607,7 +607,7 @@ bool C_extension::Exec_C_LW() { log->SC_log(Log::INFO) << std::dec << "C.LW: x" << rs1 << "(0x" << std::hex << regs->getValue(rs1) << ") + " << std::dec << imm << " (@0x" << std::hex << mem_addr << std::dec << ") -> x" << rd << std::hex - << " (0x" << data << ")" << std::endl; + << " (0x" << data << ")" << "\n"; } return true; @@ -631,7 +631,7 @@ bool C_extension::Exec_C_SW() { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "C.SW: x" << std::dec << rs2 << "(0x" << std::hex << data << ") -> x" << std::dec << rs1 << " + 0x" << std::hex << imm - << " (@0x" << std::hex << mem_addr << std::dec << ")" << std::endl; + << " (@0x" << std::hex << mem_addr << std::dec << ")" << "\n"; } return true; @@ -655,7 +655,7 @@ bool C_extension::Exec_C_JAL(int m_rd) { if (log->getLogLevel() >= Log::INFO) { log->SC_log(Log::INFO) << "C.JAL: x" << std::dec << rd << " <- 0x" << std::hex << old_pc << std::dec << ". PC + 0x" << std::hex - << mem_addr << " -> PC (0x" << new_pc << ")" << std::endl; + << mem_addr << " -> PC (0x" << new_pc << ")" << "\n"; } return true; @@ -746,7 +746,7 @@ bool C_extension::process_instruction(Instruction &inst) { Exec_C_AND(); break; [[unlikely]] default: - std::cout << "C instruction not implemented yet" << std::endl; + std::cout << "C instruction not implemented yet" << "\n"; inst.dump(); NOP(); break; diff --git a/src/Log.cpp b/src/Log.cpp index b34f38c..6fd36ff 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -25,7 +25,7 @@ void Log::SC_log(std::string msg, enum LogLevel level) { if (level <= currentLogLevel) { m_stream << "time " << sc_core::sc_time_stamp() << ": " << msg - << std::endl; + << "\n"; } } @@ -41,7 +41,7 @@ std::ofstream& Log::SC_log(enum LogLevel level) { } void Log::setLogLevel(enum LogLevel newLevel) { - std::cout << "LogLevel set to " << newLevel << std::endl; + std::cout << "LogLevel set to " << newLevel << "\n"; currentLogLevel = newLevel; } diff --git a/src/M_extension.cpp b/src/M_extension.cpp index 5cda739..76b99cb 100644 --- a/src/M_extension.cpp +++ b/src/M_extension.cpp @@ -60,7 +60,7 @@ bool M_extension::Exec_M_MUL() { regs->setValue(rd, result); log->SC_log(Log::INFO) << std::dec << "MUL: x" << rs1 << " * x" << rs2 - << " -> x" << rd << "(" << result << ")" << std::endl; + << " -> x" << rd << "(" << result << ")" << "\n"; return true; } @@ -84,7 +84,7 @@ bool M_extension::Exec_M_MULH() { regs->setValue(rd, ret_value); log->SC_log(Log::INFO) << std::dec << "MULH: x" << rs1 << " * x" << rs2 - << " -> x" << rd << "(" << result << ")" << std::endl; + << " -> x" << rd << "(" << result << ")" << "\n"; return true; } @@ -107,7 +107,7 @@ bool M_extension::Exec_M_MULHSU() { regs->setValue(rd, result); log->SC_log(Log::INFO) << std::dec << "MULHSU: x" << rs1 << " * x" << rs2 - << " -> x" << rd << "(" << result << ")" << std::endl; + << " -> x" << rd << "(" << result << ")" << "\n"; return true; } @@ -130,7 +130,7 @@ bool M_extension::Exec_M_MULHU() { regs->setValue(rd, ret_value); log->SC_log(Log::INFO) << std::dec << "MULHU: x" << rs1 << " * x" << rs2 - << " -> x" << rd << "(" << ret_value << ")" << std::endl; + << " -> x" << rd << "(" << ret_value << ")" << "\n"; return true; } @@ -159,7 +159,7 @@ bool M_extension::Exec_M_DIV() { regs->setValue(rd, result); log->SC_log(Log::INFO) << std::dec << "DIV: x" << rs1 << " / x" << rs2 - << " -> x" << rd << "(" << result << ")" << std::endl; + << " -> x" << rd << "(" << result << ")" << "\n"; return true; } @@ -186,7 +186,7 @@ bool M_extension::Exec_M_DIVU() { regs->setValue(rd, result); log->SC_log(Log::INFO) << std::dec << "DIVU: x" << rs1 << " / x" << rs2 - << " -> x" << rd << "(" << result << ")" << std::endl; + << " -> x" << rd << "(" << result << ")" << "\n"; return true; } @@ -214,7 +214,7 @@ bool M_extension::Exec_M_REM() { regs->setValue(rd, result); log->SC_log(Log::INFO) << std::dec << "REM: x" << rs1 << " / x" << rs2 - << " -> x" << rd << "(" << result << ")" << std::endl; + << " -> x" << rd << "(" << result << ")" << "\n"; return true; } @@ -240,7 +240,7 @@ bool M_extension::Exec_M_REMU() { regs->setValue(rd, result); log->SC_log(Log::INFO) << std::dec << "REMU: x" << rs1 << " / x" << rs2 - << " -> x" << rd << "(" << result << ")" << std::endl; + << " -> x" << rd << "(" << result << ")" << "\n"; return true; } @@ -276,7 +276,7 @@ bool M_extension::process_instruction(Instruction &inst) { Exec_M_REMU(); break; [[unlikely]] default: - std::cout << "M instruction not implemented yet" << std::endl; + std::cout << "M instruction not implemented yet" << "\n"; inst.dump(); //NOP(inst); sc_core::sc_stop();