From 90d96778c368a948e9844b72c1a3b8a54145e356 Mon Sep 17 00:00:00 2001 From: derzhavin3016 Date: Thu, 5 Jan 2023 15:03:32 +0300 Subject: [PATCH 01/12] [cmake] Typo fix --- cmake/comp_flags.cmake | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/cmake/comp_flags.cmake b/cmake/comp_flags.cmake index b946254..8863ed1 100644 --- a/cmake/comp_flags.cmake +++ b/cmake/comp_flags.cmake @@ -81,17 +81,19 @@ set(GCC_WARNINGS -flto-odr-type-merging -fno-omit-frame-pointer) -function(apply_compiler_flags TARGET VISIBILIY) +function(apply_compiler_flags TARGET VISIBILITY) # Add sanitizers - target_link_options(${TARGET} ${VISIBILIY} "$<$:${SANITIZERS}>") - target_compile_options(${TARGET} ${VISIBILIY} + target_link_options(${TARGET} ${VISIBILITY} "$<$:${SANITIZERS}>") + target_compile_options(${TARGET} ${VISIBILITY} "$<$:${SANITIZERS}>") # Compile stuff - target_compile_options(${TARGET} ${VISIBILIY} + target_compile_options(${TARGET} ${VISIBILITY} "$<$:${COMMON_WARNINGS}>") + target_compile_options(${TARGET} ${VISIBILITY} + "$<$:-g>") target_compile_options( - ${TARGET} ${VISIBILIY} + ${TARGET} ${VISIBILITY} "$<$:$<$:${GCC_WARNINGS}>>") endfunction() From 982991fee166b65c1e7814a467cc41453574b5b3 Mon Sep 17 00:00:00 2001 From: derzhavin3016 Date: Thu, 5 Jan 2023 15:03:44 +0300 Subject: [PATCH 02/12] Gitignore upd --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index ddd8d5c..76309d4 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,5 @@ build* .vscode/ .cache/ + +callgrind.out.* From 7dbab332b7c7f5a56f63298a7531c5f54c04cc23 Mon Sep 17 00:00:00 2001 From: derzhavin3016 Date: Thu, 5 Jan 2023 15:03:54 +0300 Subject: [PATCH 03/12] 8queens fix --- test/e2e/simulator/8-queens.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/e2e/simulator/8-queens.c b/test/e2e/simulator/8-queens.c index e47cf01..94ba6ea 100644 --- a/test/e2e/simulator/8-queens.c +++ b/test/e2e/simulator/8-queens.c @@ -14,9 +14,9 @@ int solution_count; /* how many solutions are there? */ bool finished = FALSE; /* found all solutions yet? */ -bool is_a_solution(int[], int k, int n) { return (k == n); } +bool is_a_solution(int a[], int k, int n) { return (k == n); } -void process_solution(int[], int) { solution_count++; } +void process_solution(int a[], int b) { solution_count++; } void construct_candidates(int a[], int k, int n, int c[], int *ncandidates); From bfafa426e629ead78fb132250acf7d79f4213527 Mon Sep 17 00:00:00 2001 From: derzhavin3016 Date: Thu, 5 Jan 2023 16:22:41 +0300 Subject: [PATCH 04/12] Improved perf by making logging lazier --- include/common/common.hh | 7 ++++++- include/common/inst.hh | 11 +++++++++++ include/common/state.hh | 11 +++++++++++ include/executor/executor.hh | 4 ++-- src/hart/hart.cc | 2 +- 5 files changed, 31 insertions(+), 4 deletions(-) diff --git a/include/common/common.hh b/include/common/common.hh index 0965535..49b845a 100644 --- a/include/common/common.hh +++ b/include/common/common.hh @@ -37,9 +37,14 @@ constexpr std::uint16_t kOffsetBits = 12; constexpr std::string_view kCosimLoggerName = "cosim"; +inline const auto &getCosimLogger() { + static auto coSimLogger = spdlog::get(kCosimLoggerName.data()); + return coSimLogger; +} + template void cosimLog(fmt::format_string str, Args &&...args) { - auto coSimLogger = spdlog::get(kCosimLoggerName.data()); + const auto &coSimLogger = getCosimLogger(); if (coSimLogger) { coSimLogger->info(str, std::forward(args)...); } diff --git a/include/common/inst.hh b/include/common/inst.hh index ec92852..48a9307 100644 --- a/include/common/inst.hh +++ b/include/common/inst.hh @@ -6,6 +6,8 @@ #include #include +#include + #include "common.hh" namespace sim { @@ -31,4 +33,13 @@ using BasicBlock = std::vector; } // namespace sim +template <> struct fmt::formatter { + constexpr auto parse(format_parse_context &ctx) { return ctx.end(); } + + template + auto format(const sim::Instruction &inst, FormatContext &ctx) const { + return fmt::format_to(ctx.out(), "{}", inst.str()); + } +}; + #endif // __INCLUDE_COMMON_INST_HH__ diff --git a/include/common/state.hh b/include/common/state.hh index 0a13d87..7db82a8 100644 --- a/include/common/state.hh +++ b/include/common/state.hh @@ -2,12 +2,14 @@ #define __INCLUDE_COMMON_STATE_HH__ #include +#include #include #include #include #include #include +#include #include #include "common/common.hh" @@ -60,4 +62,13 @@ struct State final { } // namespace sim +template <> struct fmt::formatter { + constexpr auto parse(format_parse_context &ctx) { return ctx.end(); } + + template + auto format(const sim::RegFile ®File, FormatContext &ctx) const { + return fmt::format_to(ctx.out(), "{}", regFile.str()); + } +}; + #endif // __INCLUDE_COMMON_STATE_HH__ diff --git a/include/executor/executor.hh b/include/executor/executor.hh index 031ed2b..ae03085 100644 --- a/include/executor/executor.hh +++ b/include/executor/executor.hh @@ -34,8 +34,8 @@ public: cosimLog("NUM={}", instrCount); this->execute(inst, state); cosimLog("PC=0x{:08x}", state.pc); - spdlog::trace("Instruction:\n [0x{:08x}]{}", state.pc, inst.str()); - spdlog::trace("Current regfile state:\n{}", state.regs.str()); + spdlog::trace("Instruction:\n [0x{:08x}]{}", state.pc, inst); + spdlog::trace("Current regfile state:\n{}", state.regs); this->instrCount += 1; }); } diff --git a/src/hart/hart.cc b/src/hart/hart.cc index 66f892b..156dff7 100644 --- a/src/hart/hart.cc +++ b/src/hart/hart.cc @@ -30,7 +30,7 @@ BasicBlock Hart::createBB(Addr addr) { throw std::logic_error{ "Unknown instruction found while decoding basic block" + inst.str()}; - spdlog::trace(inst.str()); + spdlog::trace("{}", inst); isBranch = inst.isBranch; bb.push_back(inst); } From 4d2292bebf74359860d73218f76a476220504a4f Mon Sep 17 00:00:00 2001 From: derzhavin3016 Date: Thu, 5 Jan 2023 21:38:11 +0300 Subject: [PATCH 05/12] [executor] Added useful alias for map --- include/executor/executor.hh | 7 +- src/executor/executor.cc | 333 +++++++++++++++++++---------------- 2 files changed, 181 insertions(+), 159 deletions(-) diff --git a/include/executor/executor.hh b/include/executor/executor.hh index ae03085..386b4be 100644 --- a/include/executor/executor.hh +++ b/include/executor/executor.hh @@ -19,6 +19,9 @@ concept InstForwardIterator = std::input_iterator && class Executor final { public: + using ExecutorMap = std::unordered_map< + OpType, std::function>; + Executor() = default; Executor(const Executor &) = delete; Executor(Executor &&) = delete; @@ -41,9 +44,7 @@ public: } private: - static const std::unordered_map< - OpType, std::function> - execMap_; + static const ExecutorMap execMap_; std::size_t instrCount{1}; }; diff --git a/src/executor/executor.cc b/src/executor/executor.cc index bc6cf47..ddd87a6 100644 --- a/src/executor/executor.cc +++ b/src/executor/executor.cc @@ -51,166 +51,187 @@ void executeCondBranch(const Instruction &inst, State &state, Func op) { } } -const std::unordered_map> - Executor::execMap_{ - {OpType::ADD, - [](const Instruction &inst, State &state) { - executeRegisterRegisterOp(inst, state, std::plus()); - }}, - {OpType::SUB, - [](const Instruction &inst, State &state) { - executeRegisterRegisterOp(inst, state, std::minus()); - }}, - {OpType::MUL, - [](const Instruction &inst, State &state) { - executeRegisterRegisterOp(inst, state, std::multiplies()); - }}, - {OpType::DIV, - [](const Instruction &inst, State &state) { - auto rs2 = state.regs.get(inst.rs2); - if (rs2 == 0) { - throw std::logic_error("division by zero"); - } - executeRegisterRegisterOp(inst, state, std::divides()); - }}, - {OpType::LW, - [](const Instruction &inst, State &state) { - auto rs1 = state.regs.get(inst.rs1); - auto word = state.mem.loadWord(rs1 + inst.imm); - state.regs.set(inst.rd, word); - }}, - {OpType::SW, - [](const Instruction &inst, State &state) { - auto rs1 = state.regs.get(inst.rs1); - auto rs2 = state.regs.get(inst.rs2); - state.mem.storeWord(rs1 + inst.imm, rs2); - }}, - {OpType::JAL, - [](const Instruction &inst, State &state) { - state.branchIsTaken = true; - state.regs.set(inst.rd, state.pc + kXLENInBytes); - state.npc = state.pc + inst.imm; - }}, - {OpType::JALR, - [](const Instruction &inst, State &state) { - state.branchIsTaken = true; - state.regs.set(inst.rd, state.pc + kXLENInBytes); - auto rs1 = state.regs.get(inst.rs1); - state.npc = - setBit<0, 0>(rs1 + inst.imm); // setting the least-significant +const Executor:: + ExecutorMap + Executor::execMap_{{OpType::ADD, + [](const Instruction &inst, State &state) { + executeRegisterRegisterOp(inst, state, + std::plus()); + }}, + {OpType::SUB, + [](const Instruction &inst, State &state) { + executeRegisterRegisterOp(inst, state, + std::minus()); + }}, + {OpType::MUL, + [](const Instruction &inst, State &state) { + executeRegisterRegisterOp( + inst, state, std::multiplies()); + }}, + {OpType::DIV, + [](const Instruction &inst, State &state) { + auto rs2 = state.regs.get(inst.rs2); + if (rs2 == 0) { + throw std::logic_error("division by zero"); + } + executeRegisterRegisterOp(inst, state, + std::divides()); + }}, + {OpType::LW, + [](const Instruction &inst, State &state) { + auto rs1 = state.regs.get(inst.rs1); + auto word = state.mem.loadWord(rs1 + inst.imm); + state.regs.set(inst.rd, word); + }}, + {OpType::SW, + [](const Instruction &inst, State &state) { + auto rs1 = state.regs.get(inst.rs1); + auto rs2 = state.regs.get(inst.rs2); + state.mem.storeWord(rs1 + inst.imm, rs2); + }}, + {OpType::JAL, + [](const Instruction &inst, State &state) { + state.branchIsTaken = true; + state.regs.set(inst.rd, state.pc + kXLENInBytes); + state.npc = state.pc + inst.imm; + }}, + {OpType::JALR, + [](const Instruction &inst, State &state) { + state.branchIsTaken = true; + state.regs.set(inst.rd, state.pc + kXLENInBytes); + auto rs1 = state.regs.get(inst.rs1); + state.npc = setBit<0, 0>( + rs1 + + inst.imm); // setting the least-significant // bit of the result to zero. - }}, - {OpType::ECALL, - [](const Instruction &, State &state) { state.complete = true; }}, - {OpType::ADDI, - [](const Instruction &inst, State &state) { - executeRegisterImmidiateOp(inst, state, std::plus()); - }}, - {OpType::ANDI, - [](const Instruction &inst, State &state) { - executeRegisterImmidiateOp(inst, state, std::bit_and()); - }}, + }}, + {OpType::ECALL, + [](const Instruction &, State &state) { + state.complete = true; + }}, + {OpType::ADDI, + [](const Instruction &inst, State &state) { + executeRegisterImmidiateOp(inst, state, + std::plus()); + }}, + {OpType::ANDI, + [](const Instruction &inst, State &state) { + executeRegisterImmidiateOp( + inst, state, std::bit_and()); + }}, - {OpType::XORI, - [](const Instruction &inst, State &state) { - executeRegisterImmidiateOp(inst, state, std::bit_xor()); - }}, + {OpType::XORI, + [](const Instruction &inst, State &state) { + executeRegisterImmidiateOp( + inst, state, std::bit_xor()); + }}, - {OpType::ORI, - [](const Instruction &inst, State &state) { - executeRegisterImmidiateOp(inst, state, std::bit_or()); - }}, - {OpType::SLTI, - [](const Instruction &inst, State &state) { - auto rs1 = state.regs.get(inst.rs1); - auto lhs = signCast(rs1); - auto rhs = signCast(inst.imm); - auto res = unsignedCast(executeSLT(lhs, rhs)); - state.regs.set(inst.rd, res); - }}, - {OpType::SLTIU, - [](const Instruction &inst, State &state) { - auto rs1 = state.regs.get(inst.rs1); - state.regs.set(inst.rd, executeSLT(rs1, inst.imm)); - }}, + {OpType::ORI, + [](const Instruction &inst, State &state) { + executeRegisterImmidiateOp(inst, state, + std::bit_or()); + }}, + {OpType::SLTI, + [](const Instruction &inst, State &state) { + auto rs1 = state.regs.get(inst.rs1); + auto lhs = signCast(rs1); + auto rhs = signCast(inst.imm); + auto res = unsignedCast(executeSLT(lhs, rhs)); + state.regs.set(inst.rd, res); + }}, + {OpType::SLTIU, + [](const Instruction &inst, State &state) { + auto rs1 = state.regs.get(inst.rs1); + state.regs.set(inst.rd, + executeSLT(rs1, inst.imm)); + }}, - {OpType::LUI, - [](const Instruction &inst, State &state) { - state.regs.set(inst.rd, inst.imm << 12); - }}, - {OpType::AUIPC, - [](const Instruction &inst, State &state) { - state.regs.set(inst.rd, state.pc + (inst.imm << 12)); - }}, + {OpType::LUI, + [](const Instruction &inst, State &state) { + state.regs.set(inst.rd, inst.imm << 12); + }}, + {OpType::AUIPC, + [](const Instruction &inst, State &state) { + state.regs.set(inst.rd, + state.pc + (inst.imm << 12)); + }}, - {OpType::SLLI, - [](const Instruction &inst, State &state) { - auto shamt = getBits<4, 0>(inst.imm); - auto rs1 = state.regs.get(inst.rs1); - state.regs.set(inst.rd, rs1 << shamt); - }}, - {OpType::SRLI, - [](const Instruction &inst, State &state) { - auto rs1 = state.regs.get(inst.rs1); - auto res = executeSRLT(rs1, inst.imm); - state.regs.set(inst.rd, res); - }}, - {OpType::SRAI, - [](const Instruction &inst, State &state) { - auto rs1 = state.regs.get(inst.rs1); - auto signedRs1 = signCast(rs1); - auto res = unsignedCast(executeSRLT(signedRs1, inst.imm)); - state.regs.set(inst.rd, res); - }}, - {OpType::SLL, - [](const Instruction &inst, State &state) { - auto rs1 = state.regs.get(inst.rs1); - auto rs2 = state.regs.get(inst.rs2); - state.regs.set(inst.rd, rs1 << rs2); - }}, - {OpType::SRL, - [](const Instruction &inst, State &state) { - executeRegisterRegisterOp(inst, state, executeSR); - }}, - {OpType::SRA, - [](const Instruction &inst, State &state) { - auto rs1 = signCast(state.regs.get(inst.rs1)); - auto rs2 = signCast(state.regs.get(inst.rs2)); - auto res = unsignedCast(executeSR(rs1, rs2)); - state.regs.set(inst.rd, res); - }}, - {OpType::BEQ, - [](const Instruction &inst, State &state) { - executeCondBranch(inst, state, std::equal_to()); - }}, - {OpType::BNE, - [](const Instruction &inst, State &state) { - executeCondBranch(inst, state, std::not_equal_to()); - }}, - {OpType::BLT, - [](const Instruction &inst, State &state) { - executeCondBranch(inst, state, std::less()); - }}, - {OpType::BLTU, - [](const Instruction &inst, State &state) { - executeCondBranch(inst, state, std::greater()); - }}, - {OpType::BGEU, - [](const Instruction &inst, State &state) { - executeCondBranch(inst, state, std::greater_equal()); - }}, - {OpType::BGE, - [](const Instruction &inst, State &state) { - auto rs1 = signCast(state.regs.get(inst.rs1)); - auto rs2 = signCast(state.regs.get(inst.rs2)); - if (rs1 >= rs2) { - state.branchIsTaken = true; - state.npc = state.pc + inst.imm; - } - }}, - {OpType::XOR, [](const Instruction &inst, State &state) { - executeRegisterRegisterOp(inst, state, std::bit_xor()); - }}}; + {OpType::SLLI, + [](const Instruction &inst, State &state) { + auto shamt = getBits<4, 0>(inst.imm); + auto rs1 = state.regs.get(inst.rs1); + state.regs.set(inst.rd, rs1 << shamt); + }}, + {OpType::SRLI, + [](const Instruction &inst, State &state) { + auto rs1 = state.regs.get(inst.rs1); + auto res = executeSRLT(rs1, inst.imm); + state.regs.set(inst.rd, res); + }}, + {OpType::SRAI, + [](const Instruction &inst, State &state) { + auto rs1 = state.regs.get(inst.rs1); + auto signedRs1 = signCast(rs1); + auto res = unsignedCast( + executeSRLT(signedRs1, inst.imm)); + state.regs.set(inst.rd, res); + }}, + {OpType::SLL, + [](const Instruction &inst, State &state) { + auto rs1 = state.regs.get(inst.rs1); + auto rs2 = state.regs.get(inst.rs2); + state.regs.set(inst.rd, rs1 << rs2); + }}, + {OpType::SRL, + [](const Instruction &inst, State &state) { + executeRegisterRegisterOp(inst, state, + executeSR); + }}, + {OpType::SRA, + [](const Instruction &inst, State &state) { + auto rs1 = signCast(state.regs.get(inst.rs1)); + auto rs2 = signCast(state.regs.get(inst.rs2)); + auto res = unsignedCast(executeSR(rs1, rs2)); + state.regs.set(inst.rd, res); + }}, + {OpType::BEQ, + [](const Instruction &inst, State &state) { + executeCondBranch(inst, state, + std::equal_to()); + }}, + {OpType::BNE, + [](const Instruction &inst, State &state) { + executeCondBranch(inst, state, + std::not_equal_to()); + }}, + {OpType::BLT, + [](const Instruction &inst, State &state) { + executeCondBranch(inst, state, + std::less()); + }}, + {OpType::BLTU, + [](const Instruction &inst, State &state) { + executeCondBranch(inst, state, + std::greater()); + }}, + {OpType::BGEU, + [](const Instruction &inst, State &state) { + executeCondBranch(inst, state, + std::greater_equal()); + }}, + {OpType::BGE, + [](const Instruction &inst, State &state) { + auto rs1 = signCast(state.regs.get(inst.rs1)); + auto rs2 = signCast(state.regs.get(inst.rs2)); + if (rs1 >= rs2) { + state.branchIsTaken = true; + state.npc = state.pc + inst.imm; + } + }}, + {OpType::XOR, + [](const Instruction &inst, State &state) { + executeRegisterRegisterOp(inst, state, + std::bit_xor()); + }}}; } // namespace sim From b188fd22850acc0232845e03b63136343d09d41f Mon Sep 17 00:00:00 2001 From: derzhavin3016 Date: Thu, 5 Jan 2023 21:38:32 +0300 Subject: [PATCH 06/12] [hart, memory] Optimized work w/ maps --- include/memory/memory.hh | 14 +++++++------- src/hart/hart.cc | 8 +++++--- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/include/memory/memory.hh b/include/memory/memory.hh index 9bf198e..4519c42 100644 --- a/include/memory/memory.hh +++ b/include/memory/memory.hh @@ -172,16 +172,16 @@ PagePtr PhysMemory::pageTableLookup(const AddrSections §) { using MemOp = PhysMemory::MemoryOp; auto index = sect.indexPt; - auto it_PT = pageTable.find(index); - if (it_PT == pageTable.end()) { - if constexpr (op == MemOp::LOAD) + auto [it_PT, inserted] = pageTable.try_emplace(index); + + if constexpr (op == MemOp::LOAD) { + if (inserted) { throw PhysMemory::PageFaultException( "Load on unmapped region in physical mem"); - else { - pageTable[index] = Page(); } } - return &pageTable.at(index); + + return &it_PT->second; } template @@ -268,7 +268,7 @@ inline PagePtr TLB::tlbLookup(Addr addr) { inline void TLB::tlbUpdate(Addr addr, PagePtr page) { auto idx = getTLBIndex(addr); - tlb[idx] = TLBEntry(addr, page); + tlb.insert_or_assign(idx, TLBEntry(addr, page)); } inline const TLB::TLBStats &TLB::getTLBStats() const { return stats; } diff --git a/src/hart/hart.cc b/src/hart/hart.cc index 156dff7..2da8f4d 100644 --- a/src/hart/hart.cc +++ b/src/hart/hart.cc @@ -41,10 +41,12 @@ BasicBlock Hart::createBB(Addr addr) { void Hart::run() { while (!state_.complete) { - if (cache_.find(getPC()) == cache_.end()) - cache_[getPC()] = createBB(getPC()); + auto [iter, inserted] = cache_.try_emplace(getPC()); - const auto &bb = cache_[getPC()]; + if (inserted) + iter->second = createBB(getPC()); + + const auto &bb = iter->second; exec_.execute(bb.begin(), bb.end(), state_); } } From 2eb964b1a529c67eae3c1f414964a5b651a2b536 Mon Sep 17 00:00:00 2001 From: derzhavin3016 Date: Thu, 5 Jan 2023 22:46:18 +0300 Subject: [PATCH 07/12] [memory] Minor fixes --- include/memory/memory.hh | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/include/memory/memory.hh b/include/memory/memory.hh index 4519c42..13047a8 100644 --- a/include/memory/memory.hh +++ b/include/memory/memory.hh @@ -74,14 +74,7 @@ public: uint16_t offset{}; AddrSections(uint32_t pt, uint16_t off) : indexPt(pt), offset(off) {} - AddrSections(Addr addr) { - constexpr std::pair of_bits{kOffsetBits - 1, 0}; - constexpr std::pair pt_bits{sizeofBits() - 1, - kOffsetBits}; - indexPt = getBits(addr); - offset = - static_cast(getBits(addr)); - } + AddrSections(Addr addr) : AddrSections(getPt(addr), getOffset(addr)) {} bool operator==(const AddrSections &) const = default; }; @@ -102,7 +95,8 @@ public: template PagePtr pageTableLookup(const AddrSections §); template T *getEntity(Addr addr); - uint16_t getOffset(Addr addr); + constexpr static uint16_t getOffset(Addr addr); + constexpr static uint8_t getPt(Addr addr); private: PT pageTable{}; @@ -149,19 +143,22 @@ public: template inline T *PhysMemory::getEntity(Addr addr) { - if (addr % sizeof(T) || ((getOffset(addr) + sizeof(T)) > (1 << kOffsetBits))) + auto offset = getOffset(addr); + + if (addr % sizeof(T) || ((offset + sizeof(T)) > (1 << kOffsetBits))) throw PhysMemory::MisAlignedAddrException( "Misaligned memory access is not supported!"); - AddrSections sections(addr); - auto offset = sections.offset; + auto isInTLB = tlb.tlbLookup(addr); PagePtr page; + if (isInTLB) { page = isInTLB; } else { - page = PhysMemory::pageTableLookup(sections); + page = PhysMemory::pageTableLookup({getPt(addr), offset}); tlb.tlbUpdate(addr, page); } + Word *word = &page->wordStorage.at(offset / sizeof(Word)); Byte *byte = reinterpret_cast(word) + (offset % sizeof(Word)); return reinterpret_cast(byte); @@ -201,10 +198,15 @@ inline void Memory::printMemStats(std::ostream &ost) const { inline const Memory::MemoryStats &Memory::getMemStats() const { return stats; } -inline uint16_t PhysMemory::getOffset(Addr addr) { +constexpr inline uint16_t PhysMemory::getOffset(Addr addr) { return static_cast(getBits(addr)); } +constexpr inline uint8_t PhysMemory::getPt(Addr addr) { + return static_cast( + getBits() - 1, kOffsetBits>(addr)); +} + inline Word Memory::loadWord(Addr addr) { stats.numLoads++; Word loadedWord = *physMem.getEntity(addr); @@ -257,12 +259,13 @@ inline PagePtr TLB::tlbLookup(Addr addr) { stats.TLBMisses++; return nullptr; } - if (it->second.virtualAddress != addr) { + const auto &entry = it->second; + if (entry.virtualAddress != addr) { stats.TLBMisses++; return nullptr; } stats.TLBHits++; - return it->second.physPage; + return entry.physPage; } inline void TLB::tlbUpdate(Addr addr, PagePtr page) { From 702110a25f7c643fb41ddead8731e22cc7da9343 Mon Sep 17 00:00:00 2001 From: Andrey Derzhavin Date: Tue, 10 Jan 2023 12:30:28 +0300 Subject: [PATCH 08/12] Update include/common/state.hh --- include/common/state.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/common/state.hh b/include/common/state.hh index 7db82a8..7ee0bc0 100644 --- a/include/common/state.hh +++ b/include/common/state.hh @@ -2,13 +2,13 @@ #define __INCLUDE_COMMON_STATE_HH__ #include -#include #include #include #include #include #include +#include #include #include From 7eca5ab88eb1ec974c880273e18048465286f7f7 Mon Sep 17 00:00:00 2001 From: Tako-San Date: Sun, 15 Jan 2023 21:18:51 +0300 Subject: [PATCH 09/12] Fixed test failure --- include/memory/memory.hh | 6 +++--- test/unit/memory/memory.test.cc | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/memory/memory.hh b/include/memory/memory.hh index 13047a8..9f14435 100644 --- a/include/memory/memory.hh +++ b/include/memory/memory.hh @@ -96,7 +96,7 @@ public: template T *getEntity(Addr addr); constexpr static uint16_t getOffset(Addr addr); - constexpr static uint8_t getPt(Addr addr); + constexpr static uint32_t getPt(Addr addr); private: PT pageTable{}; @@ -202,8 +202,8 @@ constexpr inline uint16_t PhysMemory::getOffset(Addr addr) { return static_cast(getBits(addr)); } -constexpr inline uint8_t PhysMemory::getPt(Addr addr) { - return static_cast( +constexpr inline uint32_t PhysMemory::getPt(Addr addr) { + return static_cast( getBits() - 1, kOffsetBits>(addr)); } diff --git a/test/unit/memory/memory.test.cc b/test/unit/memory/memory.test.cc index 6b4b8ad..c244136 100644 --- a/test/unit/memory/memory.test.cc +++ b/test/unit/memory/memory.test.cc @@ -43,7 +43,7 @@ TEST(PhysMemory, AddrSectionsCtor) { sim::PhysMemory phMem; // 0xDEADB, 0xEEF - EXPECT_EQ(AddrSections(0xDEADBEEF), AddrSections(912091, 3823)); + EXPECT_EQ(AddrSections(0xDEADBEEF), AddrSections(0xDEADB, 0xEEF)); EXPECT_EQ(AddrSections(0x0), AddrSections(0, 0)); // 2^20 - 1, 2^12 - 1 EXPECT_EQ(AddrSections(0xFFFFFFFF), AddrSections(1048575, 4095)); From 28612e3fc71626187c5d1703741d200e9537505e Mon Sep 17 00:00:00 2001 From: Tako-San Date: Mon, 16 Jan 2023 23:24:45 +0300 Subject: [PATCH 10/12] Removed global logging --- include/common/common.hh | 6 ++++++ include/executor/executor.hh | 4 ++-- src/hart/hart.cc | 6 +++--- tools/simulator/main.cc | 10 ++++++++-- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/include/common/common.hh b/include/common/common.hh index 49b845a..9602d42 100644 --- a/include/common/common.hh +++ b/include/common/common.hh @@ -36,6 +36,7 @@ constexpr std::uint16_t kTLBBits = 10; constexpr std::uint16_t kOffsetBits = 12; constexpr std::string_view kCosimLoggerName = "cosim"; +constexpr std::string_view kGlobalLoggerName = "global"; inline const auto &getCosimLogger() { static auto coSimLogger = spdlog::get(kCosimLoggerName.data()); @@ -50,6 +51,11 @@ void cosimLog(fmt::format_string str, Args &&...args) { } } +inline const auto &globalLogger() { + static auto logger = spdlog::get(kCosimLoggerName.data()); + return logger; +} + template constexpr auto signCast(T val) { return static_cast>(val); } diff --git a/include/executor/executor.hh b/include/executor/executor.hh index 386b4be..2b5efcd 100644 --- a/include/executor/executor.hh +++ b/include/executor/executor.hh @@ -37,8 +37,8 @@ public: cosimLog("NUM={}", instrCount); this->execute(inst, state); cosimLog("PC=0x{:08x}", state.pc); - spdlog::trace("Instruction:\n [0x{:08x}]{}", state.pc, inst); - spdlog::trace("Current regfile state:\n{}", state.regs); + globalLogger()->trace("Instruction:\n [0x{:08x}]{}", state.pc, inst); + globalLogger()->trace("Current regfile state:\n{}", state.regs); this->instrCount += 1; }); } diff --git a/src/hart/hart.cc b/src/hart/hart.cc index 2da8f4d..20b1205 100644 --- a/src/hart/hart.cc +++ b/src/hart/hart.cc @@ -23,19 +23,19 @@ Hart::Hart(const fs::path &executable) { BasicBlock Hart::createBB(Addr addr) { BasicBlock bb{}; - spdlog::trace("Creating basic block:"); + globalLogger()->trace("Creating basic block:"); for (bool isBranch = false; !isBranch; addr += kXLENInBytes) { auto inst = decoder_.decode(getMem().loadWord(addr)); if (inst.type == OpType::UNKNOWN) throw std::logic_error{ "Unknown instruction found while decoding basic block" + inst.str()}; - spdlog::trace("{}", inst); + globalLogger()->trace("{}", inst); isBranch = inst.isBranch; bb.push_back(inst); } - spdlog::trace("Basic blok created."); + globalLogger()->trace("Basic blok created."); return bb; } diff --git a/tools/simulator/main.cc b/tools/simulator/main.cc index ab7f82d..af945a8 100644 --- a/tools/simulator/main.cc +++ b/tools/simulator/main.cc @@ -21,7 +21,13 @@ void initCosimLogger(const fs::path &cosimFile, bool toStdout) { : spdlog::basic_logger_mt(sim::kCosimLoggerName.data(), cosimFile, true); logger->set_pattern("%v"); - logger->set_level(spdlog::level::info); + logger->set_level(lvl::info); +} + +void initGlobalLogger(lvl::level_enum lvl) { + auto logger = spdlog::stdout_color_mt(sim::kGlobalLoggerName.data()); + logger->set_pattern("%v"); + logger->set_level(lvl); } int main(int argc, char **argv) try { @@ -66,7 +72,7 @@ int main(int argc, char **argv) try { return app.exit(e); } - spdlog::set_level(loggingLevel); + initGlobalLogger(loggingLevel); if (*isCosimOpt) { initCosimLogger(cosimFile, !*cosimFileOpt); } From 2385038223a63fe88d85b23038efdb4fbab4fb57 Mon Sep 17 00:00:00 2001 From: derzhavin3016 Date: Tue, 17 Jan 2023 22:30:46 +0300 Subject: [PATCH 11/12] Remove useless cast --- include/memory/memory.hh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/memory/memory.hh b/include/memory/memory.hh index 9f14435..aab964f 100644 --- a/include/memory/memory.hh +++ b/include/memory/memory.hh @@ -203,8 +203,7 @@ constexpr inline uint16_t PhysMemory::getOffset(Addr addr) { } constexpr inline uint32_t PhysMemory::getPt(Addr addr) { - return static_cast( - getBits() - 1, kOffsetBits>(addr)); + return getBits() - 1, kOffsetBits>(addr); } inline Word Memory::loadWord(Addr addr) { From 409421d1a9deeed4c75a7268b5e5454329b046e2 Mon Sep 17 00:00:00 2001 From: Tako-San Date: Tue, 17 Jan 2023 22:48:31 +0300 Subject: [PATCH 12/12] Fix + rename * Fixed globalLogger(): changed name in get method to correct * Renamed globalLogger() to getGlobalLogger() --- include/common/common.hh | 4 ++-- include/executor/executor.hh | 4 ++-- src/hart/hart.cc | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/common/common.hh b/include/common/common.hh index 9602d42..ecbe08b 100644 --- a/include/common/common.hh +++ b/include/common/common.hh @@ -51,8 +51,8 @@ void cosimLog(fmt::format_string str, Args &&...args) { } } -inline const auto &globalLogger() { - static auto logger = spdlog::get(kCosimLoggerName.data()); +inline const auto &getGlobalLogger() { + static auto logger = spdlog::get(kGlobalLoggerName.data()); return logger; } diff --git a/include/executor/executor.hh b/include/executor/executor.hh index 2b5efcd..353f440 100644 --- a/include/executor/executor.hh +++ b/include/executor/executor.hh @@ -37,8 +37,8 @@ public: cosimLog("NUM={}", instrCount); this->execute(inst, state); cosimLog("PC=0x{:08x}", state.pc); - globalLogger()->trace("Instruction:\n [0x{:08x}]{}", state.pc, inst); - globalLogger()->trace("Current regfile state:\n{}", state.regs); + getGlobalLogger()->trace("Instruction:\n [0x{:08x}]{}", state.pc, inst); + getGlobalLogger()->trace("Current regfile state:\n{}", state.regs); this->instrCount += 1; }); } diff --git a/src/hart/hart.cc b/src/hart/hart.cc index 20b1205..e0e7df7 100644 --- a/src/hart/hart.cc +++ b/src/hart/hart.cc @@ -23,19 +23,19 @@ Hart::Hart(const fs::path &executable) { BasicBlock Hart::createBB(Addr addr) { BasicBlock bb{}; - globalLogger()->trace("Creating basic block:"); + getGlobalLogger()->trace("Creating basic block:"); for (bool isBranch = false; !isBranch; addr += kXLENInBytes) { auto inst = decoder_.decode(getMem().loadWord(addr)); if (inst.type == OpType::UNKNOWN) throw std::logic_error{ "Unknown instruction found while decoding basic block" + inst.str()}; - globalLogger()->trace("{}", inst); + getGlobalLogger()->trace("{}", inst); isBranch = inst.isBranch; bb.push_back(inst); } - globalLogger()->trace("Basic blok created."); + getGlobalLogger()->trace("Basic blok created."); return bb; }