From 376d3e9e4fe4202a4c4701c1ca86ea0d70f71caf Mon Sep 17 00:00:00 2001 From: mariusmonton Date: Sat, 20 Jun 2020 11:22:22 +0200 Subject: [PATCH 1/9] better container class --- inc/A_extension.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/A_extension.h b/inc/A_extension.h index 397c18c..00667fb 100644 --- a/inc/A_extension.h +++ b/inc/A_extension.h @@ -11,7 +11,7 @@ #include "systemc" -#include +#include #include "Log.h" #include "Registers.h" @@ -139,7 +139,7 @@ public: bool TLB_reserved(uint32_t address); private: - std::set TLB_A_Entries; + std::unordered_set TLB_A_Entries; }; #endif From 5b91897244a240818711a769af77504b200675c1 Mon Sep 17 00:00:00 2001 From: mariusmonton Date: Sun, 21 Jun 2020 00:22:51 +0200 Subject: [PATCH 2/9] added likely, unlikely attributes to switch case, could boost perfomance --- src/A_extension.cpp | 4 ++-- src/BASE_ISA.cpp | 2 +- src/BusCtrl.cpp | 2 +- src/CPU.cpp | 6 +++--- src/C_extension.cpp | 10 +++++----- src/M_extension.cpp | 4 ++-- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/A_extension.cpp b/src/A_extension.cpp index d1ebc95..595da0b 100644 --- a/src/A_extension.cpp +++ b/src/A_extension.cpp @@ -44,7 +44,7 @@ op_A_Codes A_extension::decode() { case A_AMOMAXU: return OP_A_AMOMAXU; break; - default: + [[unlikely]] default: return OP_A_ERROR; break; @@ -405,7 +405,7 @@ bool A_extension::process_instruction(Instruction &inst) { case OP_A_AMOMAXU: Exec_A_AMOMAXU(); break; - default: + [[unlikely]] default: std::cout << "A instruction not implemented yet" << std::endl; inst.dump(); NOP(); diff --git a/src/BASE_ISA.cpp b/src/BASE_ISA.cpp index 650b457..7678899 100644 --- a/src/BASE_ISA.cpp +++ b/src/BASE_ISA.cpp @@ -1316,7 +1316,7 @@ bool BASE_ISA::process_instruction(Instruction &inst) { case OP_SFENCE: Exec_SFENCE(); break; - default: + [[unlikely]] default: std::cout << "Wrong instruction" << std::endl; inst.dump(); NOP(); diff --git a/src/BusCtrl.cpp b/src/BusCtrl.cpp index cc5c6ef..52fa20a 100644 --- a/src/BusCtrl.cpp +++ b/src/BusCtrl.cpp @@ -37,7 +37,7 @@ void BusCtrl::b_transport(tlm::tlm_generic_payload &trans, case TRACE_MEMORY_ADDRESS / 4: trace_socket->b_transport(trans, delay); break; - default: + [[likely]] default: memory_socket->b_transport(trans, delay); break; } diff --git a/src/CPU.cpp b/src/CPU.cpp index 7587ca4..90f6ace 100644 --- a/src/CPU.cpp +++ b/src/CPU.cpp @@ -162,7 +162,7 @@ void CPU::CPU_thread(void) { /* check what type of instruction is and execute it */ switch (inst->check_extension()) { - case BASE_EXTENSION: + [[likely]] case BASE_EXTENSION: PC_not_affected = exec->process_instruction(*inst); incPCby2 = false; break; @@ -178,7 +178,7 @@ void CPU::CPU_thread(void) { PC_not_affected = a_inst->process_instruction(*inst); incPCby2 = false; break; - default: + [[unlikely]] default: std::cout << "Extension not implemented yet" << std::endl; inst->dump(); exec->NOP(); @@ -193,7 +193,7 @@ void CPU::CPU_thread(void) { /* Process IRQ (if any) */ cpu_process_IRQ(); - /* Fixed instruction time to 10 ns (i.e. 100 MHz)*/ + /* Fixed instruction time to 10 ns (i.e. 100 MHz) */ //#define USE_QK #ifdef USE_QK // Model time used for additional processing diff --git a/src/C_extension.cpp b/src/C_extension.cpp index e550177..1c8f32b 100644 --- a/src/C_extension.cpp +++ b/src/C_extension.cpp @@ -33,7 +33,7 @@ op_C_Codes C_extension::decode() { case C_FSW: return OP_C_FSW; break; - default: + [[unlikely]] default: return OP_C_ERROR; break; } @@ -90,7 +90,7 @@ op_C_Codes C_extension::decode() { case C_BNEZ: return OP_C_BNEZ; break; - default: + [[unlikely]] default: return OP_C_ERROR; break; } @@ -131,13 +131,13 @@ op_C_Codes C_extension::decode() { return OP_C_SWSP; break; case C_FWWSP: - default: + [[unlikely]] default: return OP_C_ERROR; break; } break; - default: + [[unlikely]] default: return OP_C_ERROR; break; @@ -745,7 +745,7 @@ bool C_extension::process_instruction(Instruction &inst) { case OP_C_AND: Exec_C_AND(); break; - default: + [[unlikely]] default: std::cout << "C instruction not implemented yet" << std::endl; inst.dump(); NOP(); diff --git a/src/M_extension.cpp b/src/M_extension.cpp index ef59fd6..5cda739 100644 --- a/src/M_extension.cpp +++ b/src/M_extension.cpp @@ -35,7 +35,7 @@ op_M_Codes M_extension::decode() { case M_REMU: return OP_M_REMU; break; - default: + [[unlikely]] default: return OP_M_ERROR; break; } @@ -275,7 +275,7 @@ bool M_extension::process_instruction(Instruction &inst) { case OP_M_REMU: Exec_M_REMU(); break; - default: + [[unlikely]] default: std::cout << "M instruction not implemented yet" << std::endl; inst.dump(); //NOP(inst); From abf47625a1f7e415ea8aaeb78caccbf5be2fb4de Mon Sep 17 00:00:00 2001 From: mariusmonton Date: Sun, 21 Jun 2020 00:29:45 +0200 Subject: [PATCH 3/9] change fixed array for CSR to unordered map --- inc/Registers.h | 6 +++++- src/Registers.cpp | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/inc/Registers.h b/inc/Registers.h index f2d1194..eef56a0 100644 --- a/inc/Registers.h +++ b/inc/Registers.h @@ -11,6 +11,7 @@ #define SC_INCLUDE_DYNAMIC_PROCESSES #include +#include #include "systemc" #include "tlm.h" @@ -254,7 +255,10 @@ private: /** * CSR registers (4096 maximum) */ - uint32_t CSR[4096]; + //uint32_t CSR[4096]; + std::unordered_map CSR; + + Performance *perf; void initCSR(void); diff --git a/src/Registers.cpp b/src/Registers.cpp index b49f6f8..cc7dc09 100644 --- a/src/Registers.cpp +++ b/src/Registers.cpp @@ -11,7 +11,7 @@ Registers::Registers() { memset(register_bank, 0, sizeof(uint32_t) * 32); // 32 registers of 32 bits each - memset(CSR, 0, sizeof(uint32_t) * 4096); + //memset(CSR, 0, sizeof(uint32_t) * 4096); perf = Performance::getInstance(); initCSR(); @@ -156,7 +156,7 @@ uint32_t Registers::getCSR(int csr) { - sc_core::sc_time(sc_core::SC_ZERO_TIME)).to_double()) >> 32 & 0x00000000FFFFFFFF); break; - default: + [[likely]] default: ret_value = CSR[csr]; break; } From 04aa12e42d40e8eb522910810272fe911ba1daad Mon Sep 17 00:00:00 2001 From: mariusmonton Date: Fri, 10 Jul 2020 16:48:29 +0200 Subject: [PATCH 4/9] fix issue #5 --- tests/C/forloop/Makefile | 1 - tests/C/func1/Makefile | 1 - tests/C/func2/Makefile | 5 +--- tests/C/func3/Makefile | 3 +-- tests/C/func4/Makefile | 1 - tests/C/func5/Makefile | 2 -- tests/C/stdlibs/Makefile | 2 -- tests/C/timer/Makefile | 56 ---------------------------------------- tests/C/trace/Makefile | 2 +- tests/C/trace2/Makefile | 2 +- tests/C/trace3/Makefile | 2 +- 11 files changed, 5 insertions(+), 72 deletions(-) delete mode 100644 tests/C/timer/Makefile diff --git a/tests/C/forloop/Makefile b/tests/C/forloop/Makefile index 1b54a52..9db9d24 100644 --- a/tests/C/forloop/Makefile +++ b/tests/C/forloop/Makefile @@ -9,7 +9,6 @@ CFLAGS = -Wall -I. -O0 -nostdlib -march=rv32i -mabi=ilp32 --entry main #CFLAGS = -Wall -I. -O0 -nodefaultlibs -march=rv32i -mabi=ilp32 -LINKER = riscv32-unknown-linux-gnu-gcc # linking flags here LFLAGS = -I. --entry main LIBS = $(EXTRA_LIBS) diff --git a/tests/C/func1/Makefile b/tests/C/func1/Makefile index 7bbc725..245ab11 100644 --- a/tests/C/func1/Makefile +++ b/tests/C/func1/Makefile @@ -7,7 +7,6 @@ CC = riscv32-unknown-elf-gcc CFLAGS = -Wall -L. -O0 -g -static -LINKER = riscv32-unknown-linux-gnu-gcc # linking flags here LFLAGS = -I. --entry main LIBS = $(EXTRA_LIBS) diff --git a/tests/C/func2/Makefile b/tests/C/func2/Makefile index 049a267..9069887 100644 --- a/tests/C/func2/Makefile +++ b/tests/C/func2/Makefile @@ -6,8 +6,6 @@ CC = riscv32-unknown-elf-gcc # compiling flags here CFLAGS = -Wall -I. -O0 -march=rv32i -mabi=ilp32 - -LINKER = riscv32-unknown-linux-gnu-gcc # linking flags here LFLAGS = -I. --entry main LIBS = $(EXTRA_LIBS) @@ -28,8 +26,7 @@ rm = rm -f $(BINDIR)/$(TARGET): $(OBJECTS) -# $(LINKER) $(OBJECTS) $(LFLAGS) $(LIBS) $(LIBDIR) -o $@ - riscv32-unknown-linux-gnu-objdump -d $< > dump + riscv32-unknown-elf-objdump -d $< > dump objcopy -Oihex $< $(TARGET).hex # @echo "Linking complete!" diff --git a/tests/C/func3/Makefile b/tests/C/func3/Makefile index 2313792..291c541 100644 --- a/tests/C/func3/Makefile +++ b/tests/C/func3/Makefile @@ -7,7 +7,6 @@ CC = riscv32-unknown-elf-gcc # compiling flags here CFLAGS = -Wall -I. -O0 -static -march=rv32imac -mabi=ilp32 --specs=nosys.specs -LINKER = riscv32-unknown-linux-gnu-gcc LIBS = $(EXTRA_LIBS) # change these to proper directories where each file should be @@ -24,7 +23,7 @@ rm = rm -f $(BINDIR)/$(TARGET): $(OBJECTS) # $(LINKER) $(OBJECTS) $(LDFLAGS) $(LIBS) $(LIBDIR) -o $@ - riscv32-unknown-linux-gnu-objdump -d $< > dump + riscv32-unknown-elf-objdump -d $< > dump objcopy -Oihex $< $(TARGET).hex @echo "Linking complete!" diff --git a/tests/C/func4/Makefile b/tests/C/func4/Makefile index 8ee871f..9d0b28c 100644 --- a/tests/C/func4/Makefile +++ b/tests/C/func4/Makefile @@ -7,7 +7,6 @@ CC = riscv32-unknown-elf-gcc CFLAGS = -Wall -I. -O0 -Xlinker --gc-sections -lgcc -lc -static --specs=nano.specs -LINKER = riscv32-unknown-linux-gnu-gcc # linking flags here LDFLAGS = -I. --entry main -L/opt/riscv/riscv32-unknown-elf/lib/ -T ld_script.ld LIBS = $(EXTRA_LIBS) diff --git a/tests/C/func5/Makefile b/tests/C/func5/Makefile index d8ab0a5..bb5577e 100644 --- a/tests/C/func5/Makefile +++ b/tests/C/func5/Makefile @@ -7,7 +7,6 @@ CC = riscv32-unknown-elf-gcc # compiling flags here CFLAGS = -Wall -I. -O0 -static --specs=nosys.specs -LINKER = riscv32-unknown-linux-gnu-gcc # linking flags here LDFLAGS = -I. --entry main -L/opt/riscv/riscv32-unknown-elf/lib/ -T ld_script.ld LIBS = $(EXTRA_LIBS) @@ -28,7 +27,6 @@ rm = rm -f $(BINDIR)/$(TARGET): $(OBJECTS) -# $(LINKER) $(OBJECTS) $(LDFLAGS) $(LIBS) $(LIBDIR) -o $@ riscv32-unknown-elf-objdump -d $< > dump objcopy -Oihex $< $(TARGET).hex # @echo "Linking complete!" diff --git a/tests/C/stdlibs/Makefile b/tests/C/stdlibs/Makefile index 6a8b281..8fd29c9 100644 --- a/tests/C/stdlibs/Makefile +++ b/tests/C/stdlibs/Makefile @@ -6,8 +6,6 @@ CC = riscv32-unknown-elf-gcc # compiling flags here CFLAGS = -Wall -I. -O0 -march=rv32i -mabi=ilp32 --specs=nosys.specs - -LINKER = riscv32-unknown-linux-gnu-gcc # linking flags here LFLAGS = -I. LIBS = $(EXTRA_LIBS) diff --git a/tests/C/timer/Makefile b/tests/C/timer/Makefile deleted file mode 100644 index 31ab2f9..0000000 --- a/tests/C/timer/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -TARGET = timer - -TARGET_ARCH=riscv32 - -CC = riscv32-unknown-elf-gcc - -# compiling flags here -CFLAGS = -Wall -I. -O0 -static --specs=nosys.specs - -LINKER = riscv32-unknown-linux-gnu-gcc -# linking flags here -LDFLAGS = -I. --entry main -L/opt/riscv/riscv32-unknown-elf/lib/ -T ld_script.ld -LIBS = $(EXTRA_LIBS) - - -# change these to proper directories where each file should be -SRCDIR = ./ -OBJDIR = . -BINDIR = ./ -INCDIR = -I. -LIBDIR = -L. - - -SOURCES := $(wildcard $(SRCDIR)/*.c) -INCLUDES := $(wildcard $(INCDIR)/*.h) -OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o) -rm = rm -f - - -$(BINDIR)/$(TARGET): $(OBJECTS) -# $(LINKER) $(OBJECTS) $(LDFLAGS) $(LIBS) $(LIBDIR) -o $@ - riscv32-unknown-linux-gnu-objdump -d $< > dump - objcopy -Oihex $< $(TARGET).hex -# @echo "Linking complete!" - -$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c - @echo "Compiling "$<" ..." -# $(CC) $(CFLAGS) $(INCDIR) -c $< -o $@ - $(CC) $(CFLAGS) $(INCDIR) $< -o $@ - @echo "Done!" - -#$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.S -# @echo "Assembling "$<" ..." -# $(CC) $(CFLAGS) $(INCDIR) -c $< -o $@ -# $(CC) $(CFLAGS) $(INCDIR) $< -o $@ -# @echo "Done!" - -.PHONY: clean -clean: - @$(rm) $(OBJECTS) *.hex dump - @echo "Cleanup complete!" - -.PHONY: remove -remove: clean - @$(rm) $(BINDIR)/$(TARGET) - @echo "Executable removed!" diff --git a/tests/C/trace/Makefile b/tests/C/trace/Makefile index c0aa67c..82b69d3 100644 --- a/tests/C/trace/Makefile +++ b/tests/C/trace/Makefile @@ -31,7 +31,7 @@ rm = rm -f $(BINDIR)/$(TARGET): $(OBJECTS) # $(LINKER) $(OBJECTS) $(LFLAGS) $(LIBS) $(LIBDIR) -o $@ - riscv32-unknown-linux-gnu-objdump -d $< > dump + riscv32-unknown-elf-objdump -d $< > dump objcopy -Oihex $< $(TARGET).hex # @echo "Linking complete!" diff --git a/tests/C/trace2/Makefile b/tests/C/trace2/Makefile index a6b7721..2311a1f 100644 --- a/tests/C/trace2/Makefile +++ b/tests/C/trace2/Makefile @@ -31,7 +31,7 @@ rm = rm -f $(BINDIR)/$(TARGET): $(OBJECTS) # $(LINKER) $(OBJECTS) $(LFLAGS) $(LIBS) $(LIBDIR) -o $@ - riscv32-unknown-linux-gnu-objdump -d $< > dump + riscv32-unknown-elf-objdump -d $< > dump objcopy -Oihex $< $(TARGET).hex # @echo "Linking complete!" diff --git a/tests/C/trace3/Makefile b/tests/C/trace3/Makefile index fa92738..a65a902 100644 --- a/tests/C/trace3/Makefile +++ b/tests/C/trace3/Makefile @@ -31,7 +31,7 @@ rm = rm -f $(BINDIR)/$(TARGET): $(OBJECTS) # $(LINKER) $(OBJECTS) $(LFLAGS) $(LIBS) $(LIBDIR) -o $@ - riscv32-unknown-linux-gnu-objdump -d $< > dump + riscv32-unknown-elf-objdump -d $< > dump objcopy -Oihex $< $(TARGET).hex # @echo "Linking complete!" From d278b1e0a53d4db822874385a1075d27143cda8c Mon Sep 17 00:00:00 2001 From: mariusmonton Date: Fri, 17 Jul 2020 17:02:38 +0200 Subject: [PATCH 5/9] Added ecall to asm example files as commented in issue #7 --- tests/asm/BasicLoop.asm | 1 + tests/asm/BasicRegisters.asm | 1 + tests/asm/Memoryaccess.asm | 1 + tests/asm/trace.asm | 1 + 4 files changed, 4 insertions(+) diff --git a/tests/asm/BasicLoop.asm b/tests/asm/BasicLoop.asm index 6454d8a..19d3b29 100644 --- a/tests/asm/BasicLoop.asm +++ b/tests/asm/BasicLoop.asm @@ -8,3 +8,4 @@ loop: SUB t1, t1, t2 BNE t1, zero, loop # END + ECALL diff --git a/tests/asm/BasicRegisters.asm b/tests/asm/BasicRegisters.asm index 06dd943..5a715a4 100644 --- a/tests/asm/BasicRegisters.asm +++ b/tests/asm/BasicRegisters.asm @@ -9,3 +9,4 @@ ADD t4, t1, t2 ADD t5, t2, t3 SUB t6, t2, t1 #SUB t7, t1, t2 +ECALL diff --git a/tests/asm/Memoryaccess.asm b/tests/asm/Memoryaccess.asm index c1ccc5e..4fafbbb 100644 --- a/tests/asm/Memoryaccess.asm +++ b/tests/asm/Memoryaccess.asm @@ -6,3 +6,4 @@ sb t3, -13(t2) li t1, 23 lbu t1, -6(t2) lbu t3, -13(t2) +ecall diff --git a/tests/asm/trace.asm b/tests/asm/trace.asm index 5c00639..d10d526 100644 --- a/tests/asm/trace.asm +++ b/tests/asm/trace.asm @@ -32,3 +32,4 @@ _start: sb t0, 0(a2) li t0, '\n' sb t0, 0(a2) + ecall From 1d271cbb0ae0b8c44c2e7caf0529299ca50c1c4b Mon Sep 17 00:00:00 2001 From: mariusmonton Date: Sun, 19 Jul 2020 11:18:58 +0200 Subject: [PATCH 6/9] explicit sc_core::wait, typos and newline --- src/A_extension.cpp | 1 + src/Memory.cpp | 2 +- src/Registers.cpp | 3 +-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/A_extension.cpp b/src/A_extension.cpp index 595da0b..8c2e91a 100644 --- a/src/A_extension.cpp +++ b/src/A_extension.cpp @@ -235,6 +235,7 @@ bool A_extension::Exec_A_AMOOR() { log->SC_log(Log::INFO) << std::dec << "AMOOR " << std::endl; return true; } + bool A_extension::Exec_A_AMOMIN() { uint32_t mem_addr = 0; int rd, rs1, rs2; diff --git a/src/Memory.cpp b/src/Memory.cpp index cad9da0..6edf358 100644 --- a/src/Memory.cpp +++ b/src/Memory.cpp @@ -86,7 +86,7 @@ void Memory::b_transport(tlm::tlm_generic_payload &trans, memcpy(&mem[adr], ptr, len); // Illustrates that b_transport may block - wait(delay); + sc_core::wait(delay); // Reset timing annotation after waiting delay = sc_core::SC_ZERO_TIME; diff --git a/src/Registers.cpp b/src/Registers.cpp index cc7dc09..fb08355 100644 --- a/src/Registers.cpp +++ b/src/Registers.cpp @@ -165,7 +165,7 @@ uint32_t Registers::getCSR(int csr) { void Registers::setCSR(int csr, uint32_t value) { /* @FIXME: rv32mi-p-ma_fetch tests doesn't allow MISA to writable, - * but Volume II: Privileged Architectura v1.10 says MISRA is writable (?) + * but Volume II: Privileged Architecture v1.10 says MISA is writable (?) */ if (csr != CSR_MISA) { CSR[csr] = value; @@ -176,5 +176,4 @@ void Registers::initCSR() { CSR[CSR_MISA] = MISA_MXL | MISA_M_EXTENSION | MISA_C_EXTENSION | MISA_A_EXTENSION | MISA_I_BASE; CSR[CSR_MSTATUS] = MISA_MXL; - } From a3ad14b6709b6eed49c8d60d28257137f32f73ef Mon Sep 17 00:00:00 2001 From: mariusmonton Date: Thu, 10 Dec 2020 18:02:42 +0100 Subject: [PATCH 7/9] Replaced std::endl by \n for Log performance --- src/BASE_ISA.cpp | 132 +++++++++++++------------- src/CPU64.cpp | 221 ++++++++++++++++++++++++++++++++++++++++++++ src/C_extension.cpp | 50 +++++----- src/Log.cpp | 4 +- src/M_extension.cpp | 18 ++-- 5 files changed, 323 insertions(+), 102 deletions(-) create mode 100644 src/CPU64.cpp 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(); From a713e13705125c2a32aac016df969f4b66491220 Mon Sep 17 00:00:00 2001 From: mariusmonton Date: Thu, 10 Dec 2020 19:34:57 +0100 Subject: [PATCH 8/9] missing header --- inc/CPU64.h | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 inc/CPU64.h diff --git a/inc/CPU64.h b/inc/CPU64.h new file mode 100644 index 0000000..9ad68e7 --- /dev/null +++ b/inc/CPU64.h @@ -0,0 +1,114 @@ +/*! + \file CPU.h + \brief Main CPU class + \author Màrius Montón + \date July 2020 + */ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef CPU_BASE_H +#define CPU_BASE_H + +#define SC_INCLUDE_DYNAMIC_PROCESSES + +#include "systemc" + +#include "tlm.h" +#include "tlm_utils/simple_initiator_socket.h" +#include "tlm_utils/tlm_quantumkeeper.h" + +#include "memory.h" +#include "MemoryInterface.h" +#include "BASE_ISA.h" +#include "Registers.h" +#include "Log.h" +#include "Instruction.h" +#include "C_extension.h" +#include "M_extension.h" +#include "A_extension.h" + +/** + * @brief ISC_V CPU 64 bitsmodel + * @param name name of the module + */ +class CPU64: sc_core::sc_module { +public: + + /** + * @brief Instruction Memory bus socket + * @param trans transction to perfoem + * @param delay time to annotate + */ + tlm_utils::simple_initiator_socket instr_bus; + + /** + * @brief IRQ line socket + * @param trans transction to perform (empty) + * @param delay time to annotate + */ + tlm_utils::simple_target_socket irq_line_socket; + + /** + * @brief Constructor + * @param name Module name + * @param PC Program Counter initialize value + */ + CPU64(sc_core::sc_module_name name, uint32_t PC); + + /** + * @brief Destructor + */ + ~CPU64(); + + MemoryInterface *mem_intf; + +private: + Registers *register_bank; + Performance *perf; + Log *log; + Instruction *inst; + C_extension *c_inst; + M_extension *m_inst; + A_extension *a_inst; + BASE_ISA *exec; + + tlm_utils::tlm_quantumkeeper *m_qk; + + bool interrupt; + uint32_t int_cause; + bool irq_already_down; + sc_core::sc_time default_time; + bool dmi_ptr_valid; + + /** + * + * @brief Process and triggers IRQ if all conditions met + * @return true if IRQ is triggered, false otherwise + */ + bool cpu_process_IRQ(); + + /** + * main thread for CPU simulation + * @brief CPU mai thread + */ + void CPU_thread(void); + + /** + * @brief callback for IRQ simple socket + * @param trans transaction to perform (empty) + * @param delay time to annotate + * + * it triggers an IRQ when called + */ + void call_interrupt(tlm::tlm_generic_payload &trans, + sc_core::sc_time &delay); + + /** + * DMI pointer is not longer valid + * @param start memory address region start + * @param end memory address region end + */ + void invalidate_direct_mem_ptr(sc_dt::uint64 start, sc_dt::uint64 end); +}; + +#endif From f7dbf106cc96f08f224e0b2f69de94b5a177d533 Mon Sep 17 00:00:00 2001 From: mariusmonton Date: Fri, 15 Jan 2021 09:09:52 +0100 Subject: [PATCH 9/9] trivial changes to increase performance --- inc/A_extension.h | 2 +- inc/BASE_ISA.h | 2 +- inc/C_extension.h | 2 +- inc/Instruction.h | 4 ++-- inc/M_extension.h | 2 +- inc/Performance.h | 14 +++++++------- inc/Registers.h | 4 ++-- src/A_extension.cpp | 6 +++--- src/BASE_ISA.cpp | 6 +++--- src/BusCtrl.cpp | 2 +- src/CPU.cpp | 12 +++++------- src/CPU64.cpp | 8 ++++---- src/C_extension.cpp | 6 +++--- src/Instruction.cpp | 19 +++++++++++-------- src/M_extension.cpp | 6 +++--- src/Memory.cpp | 5 +++-- src/Registers.cpp | 2 -- 17 files changed, 51 insertions(+), 51 deletions(-) diff --git a/inc/A_extension.h b/inc/A_extension.h index 00667fb..a7d67be 100644 --- a/inc/A_extension.h +++ b/inc/A_extension.h @@ -133,7 +133,7 @@ public: bool Exec_A_AMOMINU(); bool Exec_A_AMOMAXU(); - bool process_instruction(Instruction &inst); + bool process_instruction(Instruction *inst); void TLB_reserve(uint32_t address); bool TLB_reserved(uint32_t address); diff --git a/inc/BASE_ISA.h b/inc/BASE_ISA.h index 4546cf5..36c994b 100644 --- a/inc/BASE_ISA.h +++ b/inc/BASE_ISA.h @@ -411,7 +411,7 @@ public: * @param inst instruction to execute * @return true if PC is affected by instruction */ - bool process_instruction(Instruction &inst); + bool process_instruction(Instruction *inst); /** * @brief Decodes opcode of instruction diff --git a/inc/C_extension.h b/inc/C_extension.h index 54fd6d4..df5ca80 100644 --- a/inc/C_extension.h +++ b/inc/C_extension.h @@ -416,7 +416,7 @@ public: bool Exec_C_SW(); bool Exec_C_JAL(int m_rd); - bool process_instruction(Instruction &inst); + bool process_instruction(Instruction *inst); }; #endif diff --git a/inc/Instruction.h b/inc/Instruction.h index e88f1b0..d1ff21f 100644 --- a/inc/Instruction.h +++ b/inc/Instruction.h @@ -35,7 +35,7 @@ typedef enum { class Instruction { public: - Instruction(sc_dt::sc_uint<32> instr); + Instruction(uint32_t instr); /** * @brief returns what instruction extension @@ -59,7 +59,7 @@ public: } private: - sc_dt::sc_uint<32> m_instr; + uint32_t m_instr; }; #endif diff --git a/inc/M_extension.h b/inc/M_extension.h index 14dcc4b..13dbf6f 100644 --- a/inc/M_extension.h +++ b/inc/M_extension.h @@ -69,7 +69,7 @@ public: bool Exec_M_REM(); bool Exec_M_REMU(); - bool process_instruction(Instruction &inst); + bool process_instruction(Instruction *inst); private: diff --git a/inc/Performance.h b/inc/Performance.h index 354af6d..3111729 100644 --- a/inc/Performance.h +++ b/inc/Performance.h @@ -87,13 +87,13 @@ private: static Performance *instance; Performance(); - uint64_t data_memory_read; - uint64_t data_memory_write; - uint64_t code_memory_read; - uint64_t code_memory_write; - uint64_t register_read; - uint64_t register_write; - uint64_t instructions_executed; + uint_fast64_t data_memory_read; + uint_fast64_t data_memory_write; + uint_fast64_t code_memory_read; + uint_fast64_t code_memory_write; + uint_fast64_t register_read; + uint_fast64_t register_write; + uint_fast64_t instructions_executed; }; #endif diff --git a/inc/Registers.h b/inc/Registers.h index eef56a0..deffb1e 100644 --- a/inc/Registers.h +++ b/inc/Registers.h @@ -245,7 +245,7 @@ private: /** * bank of registers (32 regs of 32bits each) */ - int32_t register_bank[32]; + std::array register_bank{0}; /** * Program counter (32 bits width) @@ -256,7 +256,7 @@ private: * CSR registers (4096 maximum) */ //uint32_t CSR[4096]; - std::unordered_map CSR; + std::unordered_map CSR{0}; Performance *perf; diff --git a/src/A_extension.cpp b/src/A_extension.cpp index 8c2e91a..2f5b385 100644 --- a/src/A_extension.cpp +++ b/src/A_extension.cpp @@ -367,10 +367,10 @@ bool A_extension::TLB_reserved(uint32_t address) { } } -bool A_extension::process_instruction(Instruction &inst) { +bool A_extension::process_instruction(Instruction *inst) { bool PC_not_affected = true; - setInstr(inst.getInstr()); + setInstr(inst->getInstr()); switch (decode()) { case OP_A_LR: @@ -408,7 +408,7 @@ bool A_extension::process_instruction(Instruction &inst) { break; [[unlikely]] default: std::cout << "A instruction not implemented yet" << std::endl; - inst.dump(); + inst->dump(); NOP(); break; } diff --git a/src/BASE_ISA.cpp b/src/BASE_ISA.cpp index e493d63..45379e6 100644 --- a/src/BASE_ISA.cpp +++ b/src/BASE_ISA.cpp @@ -1150,10 +1150,10 @@ bool BASE_ISA::Exec_SFENCE() { return true; } -bool BASE_ISA::process_instruction(Instruction &inst) { +bool BASE_ISA::process_instruction(Instruction *inst) { bool PC_not_affected = true; - setInstr(inst.getInstr()); + setInstr(inst->getInstr()); switch (decode()) { case OP_LUI: @@ -1318,7 +1318,7 @@ bool BASE_ISA::process_instruction(Instruction &inst) { break; [[unlikely]] default: std::cout << "Wrong instruction" << "\n"; - inst.dump(); + inst->dump(); NOP(); //sc_stop(); break; diff --git a/src/BusCtrl.cpp b/src/BusCtrl.cpp index 52fa20a..80c0bf6 100644 --- a/src/BusCtrl.cpp +++ b/src/BusCtrl.cpp @@ -24,7 +24,7 @@ BusCtrl::BusCtrl(sc_core::sc_module_name name) : void BusCtrl::b_transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) { - //tlm::tlm_command cmd = trans.get_command(); + sc_dt::uint64 adr = trans.get_address() / 4; switch (adr) { diff --git a/src/CPU.cpp b/src/CPU.cpp index 90f6ace..11bb4ae 100644 --- a/src/CPU.cpp +++ b/src/CPU.cpp @@ -163,19 +163,19 @@ void CPU::CPU_thread(void) { /* check what type of instruction is and execute it */ switch (inst->check_extension()) { [[likely]] case BASE_EXTENSION: - PC_not_affected = exec->process_instruction(*inst); + PC_not_affected = exec->process_instruction(inst); incPCby2 = false; break; case C_EXTENSION: - PC_not_affected = c_inst->process_instruction(*inst); + PC_not_affected = c_inst->process_instruction(inst); incPCby2 = true; break; case M_EXTENSION: - PC_not_affected = m_inst->process_instruction(*inst); + PC_not_affected = m_inst->process_instruction(inst); incPCby2 = false; break; case A_EXTENSION: - PC_not_affected = a_inst->process_instruction(*inst); + PC_not_affected = a_inst->process_instruction(inst); incPCby2 = false; break; [[unlikely]] default: @@ -202,10 +202,8 @@ void CPU::CPU_thread(void) { m_qk->sync(); } #else - sc_core::wait(10, sc_core::SC_NS); - + //sc_core::wait(10, sc_core::SC_NS); #endif - } // while(1) } // CPU_thread diff --git a/src/CPU64.cpp b/src/CPU64.cpp index 8c5d04c..1af765a 100644 --- a/src/CPU64.cpp +++ b/src/CPU64.cpp @@ -163,19 +163,19 @@ void CPU64::CPU_thread(void) { /* check what type of instruction is and execute it */ switch (inst->check_extension()) { [[likely]] case BASE_EXTENSION: - PC_not_affected = exec->process_instruction(*inst); + PC_not_affected = exec->process_instruction(inst); incPCby2 = false; break; case C_EXTENSION: - PC_not_affected = c_inst->process_instruction(*inst); + PC_not_affected = c_inst->process_instruction(inst); incPCby2 = true; break; case M_EXTENSION: - PC_not_affected = m_inst->process_instruction(*inst); + PC_not_affected = m_inst->process_instruction(inst); incPCby2 = false; break; case A_EXTENSION: - PC_not_affected = a_inst->process_instruction(*inst); + PC_not_affected = a_inst->process_instruction(inst); incPCby2 = false; break; [[unlikely]] default: diff --git a/src/C_extension.cpp b/src/C_extension.cpp index 52a7931..d8f6e9d 100644 --- a/src/C_extension.cpp +++ b/src/C_extension.cpp @@ -661,10 +661,10 @@ bool C_extension::Exec_C_JAL(int m_rd) { return true; } -bool C_extension::process_instruction(Instruction &inst) { +bool C_extension::process_instruction(Instruction *inst) { bool PC_not_affected = true; - setInstr(inst.getInstr()); + setInstr(inst->getInstr()); switch (decode()) { case OP_C_ADDI4SPN: @@ -747,7 +747,7 @@ bool C_extension::process_instruction(Instruction &inst) { break; [[unlikely]] default: std::cout << "C instruction not implemented yet" << "\n"; - inst.dump(); + inst->dump(); NOP(); break; } diff --git a/src/Instruction.cpp b/src/Instruction.cpp index 42fe19e..24fda9d 100644 --- a/src/Instruction.cpp +++ b/src/Instruction.cpp @@ -8,26 +8,29 @@ #include "Instruction.h" -Instruction::Instruction(sc_dt::sc_uint<32> instr) { +Instruction::Instruction(uint32_t instr) { m_instr = instr; } extension_t Instruction::check_extension() { - if ((m_instr.range(6, 0) == 0b0110011) - && (m_instr.range(31, 25) == 0b0000001)) { + if (((m_instr & 0x0000007F) == 0b0110011) + && ( ((m_instr & 0x7F000000) >> 25) == 0b0000001)) { return M_EXTENSION; - } else if (m_instr.range(6, 0) == 0b0101111) { + } else if ((m_instr & 0x0000007F) == 0b0101111) { return A_EXTENSION; - } else if (m_instr.range(1, 0) == 0b11) { + } else if ((m_instr & 0x00000003) == 0b11) { return BASE_EXTENSION; - } else if (m_instr.range(1, 0) == 0b00) { + } else if ((m_instr & 0x00000003) == 0b00) { return C_EXTENSION; - } else if (m_instr.range(1, 0) == 0b01) { + } else if ((m_instr & 0x00000003) == 0b01) { return C_EXTENSION; - } else if (m_instr.range(1, 0) == 0b10) { + } else if ((m_instr & 0x00000003) == 0b10) { return C_EXTENSION; } else { + std::cout << "Unknown\n"; return UNKNOWN_EXTENSION; } } + + diff --git a/src/M_extension.cpp b/src/M_extension.cpp index 76b99cb..b442c29 100644 --- a/src/M_extension.cpp +++ b/src/M_extension.cpp @@ -245,10 +245,10 @@ bool M_extension::Exec_M_REMU() { return true; } -bool M_extension::process_instruction(Instruction &inst) { +bool M_extension::process_instruction(Instruction *inst) { bool PC_not_affected = true; - setInstr(inst.getInstr()); + setInstr(inst->getInstr()); switch (decode()) { case OP_M_MUL: @@ -277,7 +277,7 @@ bool M_extension::process_instruction(Instruction &inst) { break; [[unlikely]] default: std::cout << "M instruction not implemented yet" << "\n"; - inst.dump(); + inst->dump(); //NOP(inst); sc_core::sc_stop(); break; diff --git a/src/Memory.cpp b/src/Memory.cpp index 6edf358..7003a28 100644 --- a/src/Memory.cpp +++ b/src/Memory.cpp @@ -58,6 +58,7 @@ void Memory::b_transport(tlm::tlm_generic_payload &trans, unsigned int wid = trans.get_streaming_width(); adr = adr - memory_offset; + // Obliged to check address range and check for unsupported features, // i.e. byte enables, streaming, and bursts // Can ignore extensions @@ -65,7 +66,6 @@ void Memory::b_transport(tlm::tlm_generic_payload &trans, // ********************************************* // Generate the appropriate error response // ********************************************* - if (adr >= sc_dt::uint64(SIZE)) { trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE); return; @@ -79,6 +79,7 @@ void Memory::b_transport(tlm::tlm_generic_payload &trans, return; } + // Obliged to implement read and write commands if (cmd == tlm::TLM_READ_COMMAND) memcpy(ptr, &mem[adr], len); @@ -86,7 +87,7 @@ void Memory::b_transport(tlm::tlm_generic_payload &trans, memcpy(&mem[adr], ptr, len); // Illustrates that b_transport may block - sc_core::wait(delay); + //sc_core::wait(delay); // Reset timing annotation after waiting delay = sc_core::SC_ZERO_TIME; diff --git a/src/Registers.cpp b/src/Registers.cpp index fb08355..94ee631 100644 --- a/src/Registers.cpp +++ b/src/Registers.cpp @@ -10,8 +10,6 @@ Registers::Registers() { - memset(register_bank, 0, sizeof(uint32_t) * 32); // 32 registers of 32 bits each - //memset(CSR, 0, sizeof(uint32_t) * 4096); perf = Performance::getInstance(); initCSR();