Decouple VSRTL::Design from RipesProcessor interface [WIP 1]
MODIFY
src/processorhandler.cpp
src/processorhandler.cpp
#include "processorhandler.h"
#include "processorregistry.h"
+#include "processors/ripesprocessor.h"
#include "ripessettings.h"
#include "statusmanager.h"

MODIFY
src/processorhandler.h
src/processorhandler.h
@@ -29,8 +29,8 @@ public:
return handler;
}
- static vsrtl::core::RipesProcessor* getProcessorNonConst() { return get()->_getProcessorNonConst(); }
- static const vsrtl::core::RipesProcessor* getProcessor() { return get()->_getProcessor(); }
+ static vsrtl::core::RipesVSRTLProcessor* getProcessorNonConst() { return get()->_getProcessorNonConst(); }
+ static const vsrtl::core::RipesVSRTLProcessor* getProcessor() { return get()->_getProcessor(); }
static const std::shared_ptr<Assembler::AssemblerBase> getAssembler() { return get()->_getAssembler(); }
static const ProcessorID& getID() { return get()->_getID(); }
static std::shared_ptr<const Program> getProgram() { return get()->_getProgram(); }
@@ -47,7 +47,7 @@ public:
/**
* @brief selectProcessor
* Constructs the processor identified by @param id, and performs all necessary initialization through the
- * RipesProcessor interface.
+ * RipesVSRTLProcessor interface.
*/
static void selectProcessor(const ProcessorID& id, const QStringList& extensions = {},
RegisterInitialization setup = RegisterInitialization()) {
@@ -193,8 +193,8 @@ private slots:
void asyncTrap();
private:
- vsrtl::core::RipesProcessor* _getProcessorNonConst() { return m_currentProcessor.get(); }
- const vsrtl::core::RipesProcessor* _getProcessor() { return m_currentProcessor.get(); }
+ vsrtl::core::RipesVSRTLProcessor* _getProcessorNonConst() { return m_currentProcessor.get(); }
+ const vsrtl::core::RipesVSRTLProcessor* _getProcessor() { return m_currentProcessor.get(); }
const std::shared_ptr<Assembler::AssemblerBase> _getAssembler() { return m_currentAssembler; }
const ProcessorID& _getID() const { return m_currentID; }
std::shared_ptr<const Program> _getProgram() const { return m_program; }
@@ -239,7 +239,7 @@ private:
ProcessorHandler();
ProcessorID m_currentID;
- std::unique_ptr<vsrtl::core::RipesProcessor> m_currentProcessor;
+ std::unique_ptr<vsrtl::core::RipesVSRTLProcessor> m_currentProcessor;
std::unique_ptr<SyscallManager> m_syscallManager;
std::shared_ptr<Assembler::AssemblerBase> m_currentAssembler;

MODIFY
src/processorregistry.h
src/processorregistry.h
@@ -75,7 +75,7 @@ public:
}
return desc->second;
}
- static std::unique_ptr<vsrtl::core::RipesProcessor> constructProcessor(ProcessorID id,
+ static std::unique_ptr<vsrtl::core::RipesVSRTLProcessor> constructProcessor(ProcessorID id,
const QStringList& extensions) {
switch (id) {
case ProcessorID::RV32_5S_NO_FW_HZ:

MODIFY
src/processors/CMakeLists.txt
src/processors/CMakeLists.txt
@@ -4,13 +4,16 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
macro(create_isa_lib isa)
file(GLOB LIB_SOURCES ${isa}/*.cpp)
- file(GLOB LIB_HEADERS ripesprocessor.h ${isa}/*.h)
+ file(GLOB LIB_HEADERS
+ RipesVSRTLProcessor.h
+ ripesvsrtlprocessor.h
+ ${isa}/*.h)
add_library(${isa}_lib ${LIB_SOURCES} ${LIB_HEADERS})
endmacro()
-macro(create_processor isa name)
+macro(create_vsrtl_processor isa name)
file(GLOB LIB_SOURCES ${isa}/${name}/*.cpp)
- file(GLOB LIB_HEADERS ripesprocessor.h ${isa}/${name}/*.h)
+ file(GLOB LIB_HEADERS RipesVSRTLProcessor.h ${isa}/${name}/*.h)
add_library(${name} ${LIB_SOURCES} ${LIB_HEADERS})
target_link_libraries(${name} ${VSRTL_CORE_LIB} ${isa}_lib)
target_include_directories(${name} PUBLIC ${isa})
@@ -21,9 +24,9 @@ endmacro()
# RISC-V Processors
create_isa_lib(RISC-V)
-create_processor(RISC-V rvss)
-create_processor(RISC-V rv5s)
-create_processor(RISC-V rv5s_no_fw_hz)
-create_processor(RISC-V rv5s_no_hz)
-create_processor(RISC-V rv5s_no_fw)
-create_processor(RISC-V rv6s_dual)
+create_vsrtl_processor(RISC-V rvss)
+create_vsrtl_processor(RISC-V rv5s)
+create_vsrtl_processor(RISC-V rv5s_no_fw_hz)
+create_vsrtl_processor(RISC-V rv5s_no_hz)
+create_vsrtl_processor(RISC-V rv5s_no_fw)
+create_vsrtl_processor(RISC-V rv6s_dual)

MODIFY
src/processors/RISC-V/rv5s/rv5s.h
src/processors/RISC-V/rv5s/rv5s.h
#include "VSRTL/core/vsrtl_logicgate.h"
#include "VSRTL/core/vsrtl_multiplexer.h"
-#include "../../ripesprocessor.h"
+#include "../../ripesvsrtlprocessor.h"
// Functional units
#include "../riscv.h"
@@ -34,12 +34,12 @@ namespace core {
using namespace Ripes;
template <unsigned XLEN>
-class RV5S : public RipesProcessor {
+class RV5S : public RipesVSRTLProcessor {
static_assert(XLEN == 32 || XLEN == 64, "Only supports 32- and 64-bit variants");
public:
enum Stage { IF = 0, ID = 1, EX = 2, MEM = 3, WB = 4, STAGECOUNT };
- RV5S(const QStringList& extensions) : RipesProcessor("5-Stage RISC-V Processor") {
+ RV5S(const QStringList& extensions) : RipesVSRTLProcessor("5-Stage RISC-V Processor") {
m_enabledISA = std::make_shared<ISAInfo<XLenToRVISA<XLEN>()>>(extensions);
decode->setISA(m_enabledISA);
@@ -455,7 +455,7 @@ public:
m_instructionsRetired++;
}
- RipesProcessor::clock();
+ RipesVSRTLProcessor::clock();
}
void reverse() override {
@@ -465,7 +465,7 @@ public:
ecallChecker->setSysCallExiting(false);
m_syscallExitCycle = -1;
}
- RipesProcessor::reverse();
+ RipesVSRTLProcessor::reverse();
if (memwb_reg->valid_out.uValue() != 0 && isExecutableAddress(memwb_reg->pc_out.uValue())) {
m_instructionsRetired--;
}
@@ -473,7 +473,7 @@ public:
void reset() override {
ecallChecker->setSysCallExiting(false);
- RipesProcessor::reset();
+ RipesVSRTLProcessor::reset();
m_syscallExitCycle = -1;
}

MODIFY
src/processors/RISC-V/rv5s_no_fw/rv5s_no_fw.h
src/processors/RISC-V/rv5s_no_fw/rv5s_no_fw.h
#include "VSRTL/core/vsrtl_logicgate.h"
#include "VSRTL/core/vsrtl_multiplexer.h"
-#include "../../ripesprocessor.h"
+#include "../../ripesvsrtlprocessor.h"
// Functional units
#include "../riscv.h"
@@ -33,12 +33,12 @@ namespace core {
using namespace Ripes;
template <unsigned XLEN>
-class RV5S_NO_FW : public RipesProcessor {
+class RV5S_NO_FW : public RipesVSRTLProcessor {
static_assert(XLEN == 32 || XLEN == 64, "Only supports 32- and 64-bit variants");
public:
enum Stage { IF = 0, ID = 1, EX = 2, MEM = 3, WB = 4, STAGECOUNT };
- RV5S_NO_FW(const QStringList& extensions) : RipesProcessor("5-Stage RISC-V Processor without forwarding unit") {
+ RV5S_NO_FW(const QStringList& extensions) : RipesVSRTLProcessor("5-Stage RISC-V Processor without forwarding unit") {
m_enabledISA = std::make_shared<ISAInfo<XLenToRVISA<XLEN>()>>(extensions);
decode->setISA(m_enabledISA);
@@ -430,7 +430,7 @@ public:
m_instructionsRetired++;
}
- RipesProcessor::clock();
+ RipesVSRTLProcessor::clock();
}
void reverse() override {
@@ -440,7 +440,7 @@ public:
ecallChecker->setSysCallExiting(false);
m_syscallExitCycle = -1;
}
- RipesProcessor::reverse();
+ RipesVSRTLProcessor::reverse();
if (memwb_reg->valid_out.uValue() != 0 && isExecutableAddress(memwb_reg->pc_out.uValue())) {
m_instructionsRetired--;
}
@@ -448,7 +448,7 @@ public:
void reset() override {
ecallChecker->setSysCallExiting(false);
- RipesProcessor::reset();
+ RipesVSRTLProcessor::reset();
m_syscallExitCycle = -1;
}

MODIFY
src/processors/RISC-V/rv5s_no_fw_hz/rv5s_no_fw_hz.h
src/processors/RISC-V/rv5s_no_fw_hz/rv5s_no_fw_hz.h
#include "VSRTL/core/vsrtl_logicgate.h"
#include "VSRTL/core/vsrtl_multiplexer.h"
-#include "../../ripesprocessor.h"
+#include "../../ripesvsrtlprocessor.h"
// Functional units
#include "../riscv.h"
@@ -30,13 +30,13 @@ namespace core {
using namespace Ripes;
template <unsigned XLEN>
-class RV5S_NO_FW_HZ : public RipesProcessor {
+class RV5S_NO_FW_HZ : public RipesVSRTLProcessor {
static_assert(XLEN == 32 || XLEN == 64, "Only supports 32- and 64-bit variants");
public:
enum Stage { IF = 0, ID = 1, EX = 2, MEM = 3, WB = 4, STAGECOUNT };
RV5S_NO_FW_HZ(const QStringList& extensions)
- : RipesProcessor("5-Stage RISC-V Processor without forwarding or hazard detection") {
+ : RipesVSRTLProcessor("5-Stage RISC-V Processor without forwarding or hazard detection") {
m_enabledISA = std::make_shared<ISAInfo<XLenToRVISA<XLEN>()>>(extensions);
decode->setISA(m_enabledISA);
@@ -381,7 +381,7 @@ public:
m_instructionsRetired++;
}
- RipesProcessor::clock();
+ RipesVSRTLProcessor::clock();
}
void reverse() override {
@@ -391,14 +391,14 @@ public:
ecallChecker->setSysCallExiting(false);
m_syscallExitCycle = -1;
}
- RipesProcessor::reverse();
+ RipesVSRTLProcessor::reverse();
if (memwb_reg->valid_out.uValue() != 0 && isExecutableAddress(memwb_reg->pc_out.uValue())) {
m_instructionsRetired--;
}
}
void reset() override {
- RipesProcessor::reset();
+ RipesVSRTLProcessor::reset();
ecallChecker->setSysCallExiting(false);
m_syscallExitCycle = -1;
}

MODIFY
src/processors/RISC-V/rv5s_no_hz/rv5s_no_hz.h
src/processors/RISC-V/rv5s_no_hz/rv5s_no_hz.h
#include "VSRTL/core/vsrtl_logicgate.h"
#include "VSRTL/core/vsrtl_multiplexer.h"
-#include "../../ripesprocessor.h"
+#include "../../ripesvsrtlprocessor.h"
// Functional units
#include "../riscv.h"
@@ -31,12 +31,12 @@ namespace core {
using namespace Ripes;
template <unsigned XLEN>
-class RV5S_NO_HZ : public RipesProcessor {
+class RV5S_NO_HZ : public RipesVSRTLProcessor {
static_assert(XLEN == 32 || XLEN == 64, "Only supports 32- and 64-bit variants");
public:
enum Stage { IF = 0, ID = 1, EX = 2, MEM = 3, WB = 4, STAGECOUNT };
- RV5S_NO_HZ(const QStringList& extensions) : RipesProcessor("5-Stage RISC-V Processor without forwarding") {
+ RV5S_NO_HZ(const QStringList& extensions) : RipesVSRTLProcessor("5-Stage RISC-V Processor without forwarding") {
m_enabledISA = std::make_shared<ISAInfo<XLenToRVISA<XLEN>()>>(extensions);
decode->setISA(m_enabledISA);
@@ -414,7 +414,7 @@ public:
m_instructionsRetired++;
}
- RipesProcessor::clock();
+ RipesVSRTLProcessor::clock();
}
void reverse() override {
@@ -424,14 +424,14 @@ public:
ecallChecker->setSysCallExiting(false);
m_syscallExitCycle = -1;
}
- RipesProcessor::reverse();
+ RipesVSRTLProcessor::reverse();
if (memwb_reg->valid_out.uValue() != 0 && isExecutableAddress(memwb_reg->pc_out.uValue())) {
m_instructionsRetired--;
}
}
void reset() override {
- RipesProcessor::reset();
+ RipesVSRTLProcessor::reset();
ecallChecker->setSysCallExiting(false);
m_syscallExitCycle = -1;
}

MODIFY
src/processors/RISC-V/rv6s_dual/rv6s_dual.h
src/processors/RISC-V/rv6s_dual/rv6s_dual.h
#include "VSRTL/core/vsrtl_logicgate.h"
#include "VSRTL/core/vsrtl_multiplexer.h"
-#include "../../ripesprocessor.h"
+#include "../../ripesvsrtlprocessor.h"
#include "../riscv.h"
#include "../rv_alu.h"
@@ -39,7 +39,7 @@ namespace core {
using namespace Ripes;
template <unsigned XLEN>
-class RV6S_DUAL : public RipesProcessor {
+class RV6S_DUAL : public RipesVSRTLProcessor {
static_assert(XLEN == 32 || XLEN == 64, "Only supports 32- and 64-bit variants");
public:
@@ -58,7 +58,7 @@ public:
WB_DATA = 11,
STAGECOUNT
};
- RV6S_DUAL(const QStringList& extensions) : RipesProcessor("6-Stage dual-issue RISC-V Processor") {
+ RV6S_DUAL(const QStringList& extensions) : RipesVSRTLProcessor("6-Stage dual-issue RISC-V Processor") {
m_enabledISA = std::make_shared<ISAInfo<XLenToRVISA<XLEN>()>>(extensions);
decode_way2->setISA(m_enabledISA);
decode_way1->setISA(m_enabledISA);
@@ -774,7 +774,7 @@ public:
// executable range of the program
m_instructionsRetired += instructionsRetired();
- RipesProcessor::clock();
+ RipesVSRTLProcessor::clock();
}
void reverse() override {
@@ -784,13 +784,13 @@ public:
ecallChecker->setSysCallExiting(false);
m_syscallExitCycle = -1;
}
- RipesProcessor::reverse();
+ RipesVSRTLProcessor::reverse();
m_instructionsRetired -= instructionsRetired();
}
void reset() override {
ecallChecker->setSysCallExiting(false);
- RipesProcessor::reset();
+ RipesVSRTLProcessor::reset();
m_syscallExitCycle = -1;
}

MODIFY
src/processors/RISC-V/rvss/rvss.h
src/processors/RISC-V/rvss/rvss.h
#include "VSRTL/core/vsrtl_logicgate.h"
#include "VSRTL/core/vsrtl_multiplexer.h"
-#include "../../ripesprocessor.h"
+#include "../../ripesvsrtlprocessor.h"
#include "../riscv.h"
#include "../rv_alu.h"
@@ -23,11 +23,11 @@ namespace core {
using namespace Ripes;
template <unsigned XLEN>
-class RVSS : public RipesProcessor {
+class RVSS : public RipesVSRTLProcessor {
static_assert(XLEN == 32 || XLEN == 64, "Only supports 32- and 64-bit variants");
public:
- RVSS(const QStringList& extensions) : RipesProcessor("Single Cycle RISC-V Processor") {
+ RVSS(const QStringList& extensions) : RipesVSRTLProcessor("Single Cycle RISC-V Processor") {
m_enabledISA = std::make_shared<ISAInfo<XLenToRVISA<XLEN>()>>(extensions);
decode->setISA(m_enabledISA);
@@ -189,7 +189,7 @@ public:
// m_finishInNextCycle may be set during Design::clock(). Store the value before clocking the processor, and
// emit finished if this was the final clock cycle.
const bool finishInThisCycle = m_finishInNextCycle;
- RipesProcessor::clock();
+ RipesVSRTLProcessor::clock();
if (finishInThisCycle) {
m_finished = true;
}
@@ -197,14 +197,14 @@ public:
void reverse() override {
m_instructionsRetired--;
- RipesProcessor::reverse();
+ RipesVSRTLProcessor::reverse();
// Ensure that reverses performed when we expected to finish in the following cycle, clears this expectation.
m_finishInNextCycle = false;
m_finished = false;
}
void reset() override {
- RipesProcessor::reset();
+ RipesVSRTLProcessor::reset();
m_finishInNextCycle = false;
m_finished = false;
}

MODIFY
src/processors/ripesprocessor.h
src/processors/ripesprocessor.h
@@ -36,19 +36,21 @@ struct FinalizeReason {
bool any() const { return exitedExecutableRegion || exitSyscall; }
};
-} // namespace Ripes
-
-namespace vsrtl {
-namespace core {
-using namespace Ripes;
-
-class RipesProcessor : public Design {
+/**
+ * @brief The RipesProcessor class
+ * Interface for all Ripes processors. This interface is intended to be simulator-agnostic, and thus provides an opaque
+ * interface for retrieving any relevant information required to display the processor state of execution in Ripes.
+ *
+ * @todo: Various parts are still dependent on VSRTL structures. For these structures, there should ideally be shim
+ * classes to handle the translation from Ripes to the backend.
+ */
+class RipesProcessor {
public:
- RipesProcessor(std::string name) : Design(name) {}
+ RipesProcessor() {}
/**
* @brief registerFiles
- * @return the set of unique indentifiers for the register files exposed by this processor, under inclusion of the
+ * @return the set of register file types exposed by this processor, under inclusion of the
* ISA which the processor has been instantiated with.
*/
virtual const std::set<RegisterFileType> registerFiles() const = 0;
@@ -86,20 +88,20 @@ public:
/**
* @brief nextFetchedAddress
- * @return Address will be fetched from instruction memory in the next clock cycle
+ * @return Address which will be fetched from instruction memory in the next clock cycle
*/
virtual unsigned int nextFetchedAddress() const = 0;
/**
* @brief stageInfo
* @param stageIndex
- * @return Additional info related to the current execution state of stage @param stageIndex
+ * @return Additional info related to the state of stage @param stageIndex in the current cycle
*/
virtual StageInfo stageInfo(unsigned int stageIndex) const = 0;
/**
* @brief breakpointTriggeringStages
- * @returns the stage indicies for which a breakpoint is triggered when the breakpoint PC address enters the stage.
+ * @returns the stage indices for which a breakpoint is triggered when the breakpoint PC address enters the stage.
*/
virtual const std::vector<unsigned> breakpointTriggeringStages() const = 0;
@@ -107,15 +109,15 @@ public:
* @brief getMemory
* @return reference to the address space utilized by the implementing processor
*/
- virtual AddressSpaceMM& getMemory() = 0;
+ virtual vsrtl::core::AddressSpaceMM& getMemory() = 0;
/**
* @brief getData/InstrMemory
* @returns a pointer to the component which implements the instruction and data memory interfaces. These types may
* be implementation specific, and as such should be cast to these types at the callers end.
*/
- virtual const BaseMemory<true>* getDataMemory() const = 0;
- virtual const BaseMemory<true>* getInstrMemory() const = 0;
+ virtual const vsrtl::core::BaseMemory<true>* getDataMemory() const = 0;
+ virtual const vsrtl::core::BaseMemory<true>* getInstrMemory() const = 0;
/**
* @brief getRegister
@@ -129,7 +131,7 @@ public:
* @brief getArchRegisters
* @return reference to the register address space utilized by the implementing processor
*/
- virtual AddressSpace& getArchRegisters() = 0;
+ virtual vsrtl::core::AddressSpace& getArchRegisters() = 0;
/**
* @brief setRegister
@@ -151,28 +153,29 @@ public:
*/
virtual void setPCInitialValue(uint32_t address) = 0;
- void reset() override {
- m_instructionsRetired = 0;
- Design::reset();
- }
+ /**
+ * @brief reset
+ * Resets the processor
+ */
+ virtual void reset() = 0;
/**
* @brief isExecutableAddress
- * Callback registerred by the environment instantiating the processor. The environment shall return whether the @p
+ * Callback that the processor can use to query the Ripes environment. Returns whether the @p
* address is an address which is valid to be executed.
*/
std::function<bool(uint32_t)> isExecutableAddress;
/**
* @brief handleSysCall
- * Signal for passing control to the outside environment whenever a system call must be handled (RISC-V ecall
- * instruction).
+ * Signal that the processor can use to pass control to the outside environment whenever a system call must be
+ * handled (RISC-V ecall instruction).
*/
Gallant::Signal0<> handleSysCall;
/**
* @brief finalize
- * Called from the outside environment to indicate that the processor should start or stop its finishing sequence.
+ * Called from Ripes to indicate that the processor should start or stop its finishing sequence.
* The finishing sequence is defined as executing all remaining instructions in the pipeline, but not fetching new
* instructions. Typically, finalize would be called once the PC of the processor starts executing outside of the
* current .text segment, or the processor has executed an exit system call.
@@ -192,12 +195,7 @@ public:
* @brief getInstructionsRetired
* @returns the number of instructions which has retired (ie. executed and no longer in the pipeline).
*/
- long long getInstructionsRetired() const { return m_instructionsRetired; }
-
-protected:
- // Statistics
- long long m_instructionsRetired = 0;
+ virtual long long getInstructionsRetired() const = 0;
};
-} // namespace core
-} // namespace vsrtl
+} // namespace Ripes

ADD
src/processors/ripesvsrtlprocessor.h
+#pragma once
+
+/**
+ * Interface for all VSRTL-based Ripes processors
+ */
+
+#include "VSRTL/core/vsrtl_design.h"
+#include "ripesprocessor.h"
+
+namespace Ripes {
+
+class RipesVSRTLProcessor : public RipesProcessor, public vsrtl::core::Design {
+public:
+ RipesVSRTLProcessor(std::string name) : Design(name) {}
+
+ virtual void reset() override {
+ m_instructionsRetired = 0;
+ Design::reset();
+ }
+
+ long long getInstructionsRetired() const override { return m_instructionsRetired; }
+
+protected:
+ // Statistics
+ long long m_instructionsRetired = 0;
+};
+
+} // namespace Ripes

MODIFY
src/processortab.cpp
src/processortab.cpp
namespace Ripes {
namespace {
-//
inline QString convertToSIUnits(const double l_value, int precision = 2) {
QString unit;
double value;

Decouple VSRTL::Design from RipesProcessor interface [WIP 1]