Use VT_U/VT_S casts where applicable
MODIFY
external/VSRTL
external/VSRTL
-Subproject commit 1b8be3b8549c21e95eecace1290dba3cc4e3a40d
+Subproject commit 074fc74657a2398f13e9fbfa4aa623ff75f2f499

MODIFY
src/binutils.h
src/binutils.h
@@ -74,4 +74,8 @@ constexpr inline unsigned ceillog2(unsigned x) {
return x == 1 || x == 0 ? 1 : floorlog2(x - 1) + 1;
}
+constexpr bool is_powerof2(int v) {
+ return v && ((v & (v - 1)) == 0);
+}
+
} // namespace Ripes

MODIFY
src/processors/RISC-V/riscv.h
src/processors/RISC-V/riscv.h
#include <functional>
#include "../../isa/rv32isainfo.h"
#include "VSRTL/core/vsrtl_enum.h"
-#include "VSRTL/interface/vsrtl.h"
#include "VSRTL/interface/vsrtl_binutils.h"
+#include "VSRTL/interface/vsrtl_defines.h"
#include "rv_instrparser.h"
namespace Ripes {
@@ -45,28 +45,28 @@ public:
return &parser;
}
- std::vector<::vsrtl::VSRTL_VT_U> decodeUInstr(::vsrtl::VSRTL_VT_U instr) const { return m_decodeUInstr(instr); }
- std::vector<::vsrtl::VSRTL_VT_U> decodeJInstr(::vsrtl::VSRTL_VT_U instr) const { return m_decodeJInstr(instr); }
- std::vector<::vsrtl::VSRTL_VT_U> decodeIInstr(::vsrtl::VSRTL_VT_U instr) const { return m_decodeIInstr(instr); }
- std::vector<::vsrtl::VSRTL_VT_U> decodeSInstr(::vsrtl::VSRTL_VT_U instr) const { return m_decodeSInstr(instr); }
- std::vector<::vsrtl::VSRTL_VT_U> decodeRInstr(::vsrtl::VSRTL_VT_U instr) const { return m_decodeRInstr(instr); }
- std::vector<::vsrtl::VSRTL_VT_U> decodeBInstr(::vsrtl::VSRTL_VT_U instr) const { return m_decodeBInstr(instr); }
+ std::vector<uint32_t> decodeU32Instr(const uint32_t& instr) const { return m_decodeU32Instr(instr); }
+ std::vector<uint32_t> decodeJ32Instr(const uint32_t& instr) const { return m_decodeJ32Instr(instr); }
+ std::vector<uint32_t> decodeI32Instr(const uint32_t& instr) const { return m_decodeI32Instr(instr); }
+ std::vector<uint32_t> decodeS32Instr(const uint32_t& instr) const { return m_decodeS32Instr(instr); }
+ std::vector<uint32_t> decodeR32Instr(const uint32_t& instr) const { return m_decodeR32Instr(instr); }
+ std::vector<uint32_t> decodeB32Instr(const uint32_t& instr) const { return m_decodeB32Instr(instr); }
private:
RVInstrParser() {
- m_decodeRInstr = generateInstrParser(std::vector<int>{5, 3, 5, 5, 7}); // from LSB to MSB
- m_decodeIInstr = generateInstrParser(std::vector<int>{5, 3, 5, 12});
- m_decodeSInstr = generateInstrParser(std::vector<int>{5, 3, 5, 5, 7});
- m_decodeBInstr = generateInstrParser(std::vector<int>{1, 4, 3, 5, 5, 6, 1});
- m_decodeUInstr = generateInstrParser(std::vector<int>{5, 20});
- m_decodeJInstr = generateInstrParser(std::vector<int>{5, 8, 1, 10, 1});
+ m_decodeR32Instr = generateInstrParser<uint32_t>(std::vector<int>{7, 5, 3, 5, 5, 7}); // from LSB to MSB
+ m_decodeI32Instr = generateInstrParser<uint32_t>(std::vector<int>{7, 5, 3, 5, 12});
+ m_decodeS32Instr = generateInstrParser<uint32_t>(std::vector<int>{7, 5, 3, 5, 5, 7});
+ m_decodeB32Instr = generateInstrParser<uint32_t>(std::vector<int>{7, 1, 4, 3, 5, 5, 6, 1});
+ m_decodeU32Instr = generateInstrParser<uint32_t>(std::vector<int>{7, 5, 20});
+ m_decodeJ32Instr = generateInstrParser<uint32_t>(std::vector<int>{7, 5, 8, 1, 10, 1});
}
- decode_functor m_decodeUInstr;
- decode_functor m_decodeJInstr;
- decode_functor m_decodeIInstr;
- decode_functor m_decodeSInstr;
- decode_functor m_decodeRInstr;
- decode_functor m_decodeBInstr;
+ decode_functor<uint32_t> m_decodeU32Instr;
+ decode_functor<uint32_t> m_decodeJ32Instr;
+ decode_functor<uint32_t> m_decodeI32Instr;
+ decode_functor<uint32_t> m_decodeS32Instr;
+ decode_functor<uint32_t> m_decodeR32Instr;
+ decode_functor<uint32_t> m_decodeB32Instr;
};
} // namespace Ripes

MODIFY
src/processors/RISC-V/rv_alu.h
src/processors/RISC-V/rv_alu.h
@@ -21,32 +21,32 @@ public:
case ALUOp::SUB:
return op1.uValue() - op2.uValue();
case ALUOp::MUL:
- return static_cast<uint32_t>(op1.sValue() * op2.sValue());
+ return VT_U(op1.sValue() * op2.sValue());
case ALUOp::MULH: {
const auto result = static_cast<int64_t>(op1.sValue()) * static_cast<int64_t>(op2.sValue());
- return static_cast<uint32_t>(result >> 32);
+ return VT_U(result >> 32);
}
case ALUOp::MULHU: {
const auto result = static_cast<uint64_t>(op1.uValue()) * static_cast<uint64_t>(op2.uValue());
- return static_cast<uint32_t>(result >> 32);
+ return VT_U(result >> 32);
}
case ALUOp::MULHSU: {
const int64_t result = static_cast<int64_t>(op1.sValue()) * static_cast<uint64_t>(op2.uValue());
- return static_cast<uint32_t>(result >> 32);
+ return VT_U(result >> 32);
}
case ALUOp::DIV:
if (op2.sValue() == 0) {
- return static_cast<uint32_t>(-1);
+ return VT_U(-1);
} else if (op1.sValue() == static_cast<int64_t>(-(std::pow(2, 32 - 1))) && op2.sValue() == -1) {
// Overflow
- return static_cast<uint32_t>(0x80000000); // -2^(32-1)
+ return VT_U(0x80000000); // -2^(32-1)
} else {
- return static_cast<uint32_t>(op1.sValue() / op2.sValue());
+ return VT_U(op1.sValue() / op2.sValue());
}
case ALUOp::DIVU:
if (op2.sValue() == 0) {
- return static_cast<uint32_t>(std::pow(2, 32) - 1);
+ return VT_U(std::pow(2, 32) - 1);
} else {
return op1.uValue() / op2.uValue();
}
@@ -56,9 +56,9 @@ public:
return op1.uValue();
} else if (op1.sValue() == static_cast<int64_t>(-(std::pow(2, 32 - 1))) && op2.sValue() == -1) {
// Overflow
- return static_cast<uint32_t>(0);
+ return VT_U(0);
} else {
- return static_cast<uint32_t>(op1.sValue() % op2.sValue());
+ return VT_U(op1.sValue() % op2.sValue());
}
case ALUOp::REMU:
@@ -81,7 +81,7 @@ public:
return op1.uValue() << op2.uValue();
case ALUOp::SRA:
- return static_cast<uint32_t>(op1.sValue() >> op2.uValue());
+ return VT_U(op1.sValue() >> op2.uValue());
case ALUOp::SRL:
return op1.uValue() >> op2.uValue();
@@ -90,13 +90,13 @@ public:
return op2.uValue();
case ALUOp::LT:
- return static_cast<uint32_t>(op1.sValue() < op2.sValue() ? 1 : 0);
+ return VT_U(op1.sValue() < op2.sValue() ? 1 : 0);
case ALUOp::LTU:
- return static_cast<uint32_t>(op1.uValue() < op2.uValue() ? 1 : 0);
+ return VT_U(op1.uValue() < op2.uValue() ? 1 : 0);
case ALUOp::NOP:
- return 0xDEADBEEF;
+ return VT_U(0xDEADBEEF);
default:
throw std::runtime_error("Invalid ALU opcode");

MODIFY
src/processors/RISC-V/rv_decode.h
src/processors/RISC-V/rv_decode.h
@@ -25,7 +25,7 @@ public:
case 0b0010011: {
// I-Type
- const auto fields = RVInstrParser::getParser()->decodeIInstr(instr.uValue());
+ const auto fields = RVInstrParser::getParser()->decodeI32Instr(instr.uValue());
switch(fields[2]) {
case 0b000: return RVInstr::ADDI;
case 0b010: return RVInstr::SLTI;
@@ -47,7 +47,7 @@ public:
case 0b0110011: {
// R-Type
- const auto fields = RVInstrParser::getParser()->decodeRInstr(instr.uValue());
+ const auto fields = RVInstrParser::getParser()->decodeR32Instr(instr.uValue());
if (fields[0] == 0b1) {
if(m_isa && m_isa->extensionEnabled("M")) {
// RV32M Standard extension
@@ -95,7 +95,7 @@ public:
case 0b0000011: {
// Load instruction
- const auto fields = RVInstrParser::getParser()->decodeIInstr(instr.uValue());
+ const auto fields = RVInstrParser::getParser()->decodeI32Instr(instr.uValue());
switch (fields[2]) {
case 0b000: return RVInstr::LB;
case 0b001: return RVInstr::LH;
@@ -109,7 +109,7 @@ public:
case 0b0100011: {
// Store instructions
- const auto fields = RVInstrParser::getParser()->decodeSInstr(instr.uValue());
+ const auto fields = RVInstrParser::getParser()->decodeS32Instr(instr.uValue());
switch (fields[3]) {
case 0b000: return RVInstr::SB;
case 0b001: return RVInstr::SH;
@@ -121,7 +121,7 @@ public:
case 0b1100011: {
// Branch instruction
- const auto fields = RVInstrParser::getParser()->decodeBInstr(instr.uValue());
+ const auto fields = RVInstrParser::getParser()->decodeB32Instr(instr.uValue());
switch (fields[4]) {
case 0b000: return RVInstr::BEQ;
case 0b001: return RVInstr::BNE;

MODIFY
src/processors/RISC-V/rv_immediate.h
src/processors/RISC-V/rv_immediate.h
@@ -17,12 +17,12 @@ public:
case RVInstr::AUIPC:
return instr.uValue() & 0xfffff000;
case RVInstr::JAL: {
- const auto fields = RVInstrParser::getParser()->decodeJInstr(instr.uValue());
- return static_cast<unsigned>(
+ const auto fields = RVInstrParser::getParser()->decodeJ32Instr(instr.uValue());
+ return VT_U(
signextend<int32_t, 21>(fields[0] << 20 | fields[1] << 1 | fields[2] << 11 | fields[3] << 12));
}
case RVInstr::JALR: {
- return static_cast<unsigned>(signextend<int32_t, 12>((instr.uValue() >> 20)));
+ return VT_U(signextend<int32_t, 12>((instr.uValue() >> 20)));
}
case RVInstr::BEQ:
case RVInstr::BNE:
@@ -30,9 +30,9 @@ public:
case RVInstr::BGE:
case RVInstr::BLTU:
case RVInstr::BGEU: {
- const auto fields = RVInstrParser::getParser()->decodeBInstr(instr.uValue());
- return static_cast<unsigned>(signextend<int32_t, 13>((fields[0] << 12) | (fields[1] << 5) |
- (fields[5] << 1) | (fields[6] << 11)));
+ const auto fields = RVInstrParser::getParser()->decodeB32Instr(instr.uValue());
+ return VT_U(signextend<int32_t, 13>((fields[0] << 12) | (fields[1] << 5) | (fields[5] << 1) |
+ (fields[6] << 11)));
}
case RVInstr::LB:
case RVInstr::LH:
@@ -48,15 +48,15 @@ public:
case RVInstr::SLLI:
case RVInstr::SRLI:
case RVInstr::SRAI:
- return static_cast<unsigned>(signextend<int32_t, 12>((instr.uValue() >> 20)));
+ return VT_U(signextend<int32_t, 12>((instr.uValue() >> 20)));
case RVInstr::SB:
case RVInstr::SH:
case RVInstr::SW: {
- return static_cast<unsigned>(signextend<int32_t, 12>(((instr.uValue() & 0xfe000000)) >> 20) |
+ return VT_U(signextend<int32_t, 12>(((instr.uValue() & 0xfe000000)) >> 20) |
((instr.uValue() & 0xf80) >> 7));
}
default:
- return unsigned(0xDEADBEEF);
+ return VT_U(0xDEADBEEF);
}
};
}

MODIFY
src/processors/RISC-V/rv_memory.h
src/processors/RISC-V/rv_memory.h
@@ -35,11 +35,11 @@ public:
data_out << [=] {
switch (op.uValue()) {
case MemOp::LB:
- return static_cast<uint32_t>(signextend<int32_t, 8>(mem->data_out.uValue() & 0xFF));
+ return VT_U(signextend<int32_t, 8>(mem->data_out.uValue() & 0xFF));
case MemOp::LBU:
return mem->data_out.uValue() & 0xFF;
case MemOp::LH:
- return static_cast<uint32_t>(signextend<int32_t, 16>(mem->data_out.uValue() & 0xFFFF));
+ return VT_U(signextend<int32_t, 16>(mem->data_out.uValue() & 0xFFFF));
case MemOp::LHU:
return mem->data_out.uValue() & 0xFFFF;
case MemOp::LW:

MODIFY
src/processors/RISC-V/rv_registerfile.h
src/processors/RISC-V/rv_registerfile.h
@@ -38,8 +38,9 @@ public:
if constexpr (readBypass) {
r1_out << [=] {
const int rd_idx = r1_addr.uValue();
- if (rd_idx == 0)
- return static_cast<unsigned>(0);
+ if (rd_idx == 0) {
+ return VT_U(0);
+ }
const unsigned wr_idx = wr_addr.uValue();
if (wr_en.uValue() && wr_idx == r1_addr.uValue()) {
@@ -51,8 +52,9 @@ public:
r2_out << [=] {
const unsigned rd_idx = r2_addr.uValue();
- if (rd_idx == 0)
- return static_cast<unsigned>(0);
+ if (rd_idx == 0) {
+ return VT_U(0);
+ }
const unsigned wr_idx = wr_addr.uValue();
if (wr_en.uValue() && wr_idx == r2_addr.uValue()) {

MODIFY
src/processors/ripesprocessor.h
src/processors/ripesprocessor.h
@@ -17,7 +17,7 @@ namespace Ripes {
*/
struct StageInfo {
enum class State { None, Stalled, Flushed, WayHazard, Unused };
- unsigned int pc = 0;
+ vsrtl::VSRTL_VT_U pc = 0;
bool stage_valid = false;
State state;
bool operator==(const StageInfo& other) const {

MODIFY
test/tst_cosimulate.cpp
test/tst_cosimulate.cpp
@@ -167,6 +167,10 @@ void tst_Cosimulate::loadCurrentTest() {
void tst_Cosimulate::executeSimulator(Trace& trace, const Trace* refTrace) {
loadCurrentTest();
+ if (!ProcessorHandler::getProgram()) {
+ QFAIL("No program was loaded!");
+ }
+
m_stop = false;
m_err = QString();
bool maxCyclesReached = false;

Use VT_U/VT_S casts where applicable