Some specializations, removed lot of useless casts.

This commit is contained in:
Màrius Montón 2022-07-22 13:28:36 +02:00
parent fc85c603d4
commit 2615ccc8f8
No known key found for this signature in database
GPG Key ID: FA199E7A752699F0
8 changed files with 325 additions and 257 deletions

View File

@ -61,12 +61,15 @@ namespace riscv_tlm {
*/ */
using extension_base<T>::extension_base; using extension_base<T>::extension_base;
using signed_T = typename std::make_signed<T>::type;
using unsigned_T = typename std::make_unsigned<T>::type;
/** /**
* @brief Access to opcode field * @brief Access to opcode field
* @return return opcode field * @return return opcode field
*/ */
inline std::uint32_t opcode() const override { inline unsigned_T opcode() const override {
return static_cast<std::uint32_t>(this->m_instr.range(31, 27)); return static_cast<unsigned_T>(this->m_instr.range(31, 27));
} }
/** /**

View File

@ -11,6 +11,7 @@
#define SC_INCLUDE_DYNAMIC_PROCESSES #define SC_INCLUDE_DYNAMIC_PROCESSES
#include <type_traits> #include <type_traits>
#include <limits>
#include "systemc" #include "systemc"
#include "tlm.h" #include "tlm.h"
@ -181,6 +182,10 @@ namespace riscv_tlm {
*/ */
using signed_T = typename std::make_signed<T>::type; using signed_T = typename std::make_signed<T>::type;
/**
* @brief Deduce unsigned type for T type
*/
using unsigned_T = typename std::make_unsigned<T>::type;
/** /**
* @brief Access to funct7 field * @brief Access to funct7 field
@ -190,172 +195,73 @@ namespace riscv_tlm {
return this->m_instr.range(31, 25); return this->m_instr.range(31, 25);
} }
/**
* @brief Sets func7 field
* @param value desired func7 value
*/
inline void set_func7(std::int32_t value) {
this->m_instr.range(31, 25) = value;
}
/** /**
* @brief Gets immediate field value for I-type * @brief Gets immediate field value for I-type
* @return immediate_I field * @return immediate_I field
* @note Specialized
*/ */
inline std::int32_t get_imm_I() const { signed_T get_imm_I() const;
std::uint32_t aux = 0;
aux = this->m_instr.range(31, 20);
/* sign extension (optimize) */
if (this->m_instr[31] == 1) {
aux |= (0b11111111111111111111) << 12;
}
return static_cast<std::int32_t>(aux);
}
/**
* @brief Sets immediate field for I-type
* @param value desired I value
*/
inline void set_imm_I(std::int32_t value) {
this->m_instr.range(31, 20) = value;
}
/** /**
* @brief Gets immediate field value for S-type * @brief Gets immediate field value for S-type
* @return immediate_S field * @return immediate_S field
* @note Specialized
*/ */
inline std::int32_t get_imm_S() const { signed_T get_imm_S() const;
std::uint32_t aux = 0;
aux = this->m_instr.range(31, 25) << 5;
aux |= this->m_instr.range(11, 7);
if (this->m_instr[31] == 1) {
aux |= (0b11111111111111111111) << 12;
}
return static_cast<std::int32_t>(aux);
}
/** /**
* @brief Gets immediate field value for U-type * @brief Gets immediate field value for U-type
* @return immediate_U field * @return immediate_U field
*/ */
inline std::int32_t get_imm_U() const { inline unsigned_T get_imm_U() const {
return static_cast<std::int32_t>(this->m_instr.range(31, 12)); return this->m_instr.range(31, 12);
}
/**
* @brief Sets immediate field for U-type
* @param value desired U value
*/
inline void set_imm_U(std::int32_t value) {
this->m_instr.range(31, 12) = (value << 12);
} }
/** /**
* @brief Gets immediate field value for B-type * @brief Gets immediate field value for B-type
* @return immediate_B field * @return immediate_B field
* @note Specialized
*/ */
inline std::int32_t get_imm_B() const { signed_T get_imm_B() const;
std::int32_t aux = 0;
aux |= this->m_instr[7] << 11;
aux |= this->m_instr.range(30, 25) << 5;
aux |= this->m_instr[31] << 12;
aux |= this->m_instr.range(11, 8) << 1;
if (this->m_instr[31] == 1) {
aux |= (0b11111111111111111111) << 12;
}
return aux;
}
/**
* @brief Sets immediate field for B-type
* @param value desired B value
*/
inline void set_imm_B(std::int32_t value) {
sc_dt::sc_uint<32> aux = value;
this->m_instr[31] = aux[12];
this->m_instr.range(30, 25) = aux.range(10, 5);
this->m_instr.range(11, 7) = aux.range(4, 1);
this->m_instr[6] = aux[11];
}
/** /**
* @brief Gets immediate field value for J-type * @brief Gets immediate field value for J-type
* @return immediate_J field * @return immediate_J field
* @note Specialized
*/ */
inline std::int32_t get_imm_J() const { signed_T get_imm_J() const;
std::int32_t aux = 0;
aux = this->m_instr[31] << 20;
aux |= this->m_instr.range(19, 12) << 12;
aux |= this->m_instr[20] << 11;
aux |= this->m_instr.range(30, 21) << 1;
/* bit extension (better way to do that?) */
if (this->m_instr[31] == 1) {
aux |= (0b111111111111) << 20;
}
return aux;
}
/**
* @brief Sets immediate field for J-type
* @param value desired J value
*/
inline void set_imm_J(std::int32_t value) {
sc_dt::sc_uint<32> aux = (value << 20);
this->m_instr[31] = aux[20];
this->m_instr.range(30, 21) = aux.range(10, 1);
this->m_instr[20] = aux[11];
this->m_instr.range(19, 12) = aux.range(19, 12);
}
/** /**
* @brief Returns shamt field for Shifts instructions * @brief Returns shamt field for Shifts instructions
* @return value corresponding to inst(25:20) * @return value corresponding to inst(25:20)
*/ */
inline std::int32_t get_shamt() const { inline unsigned_T get_shamt() const {
return static_cast<std::int32_t>(this->m_instr.range(25, 20)); return this->m_instr.range(25, 20);
} }
/** /**
* @brief Returns CSR field for CSR instructions * @brief Returns CSR field for CSR instructions
* @return value corresponding to instr(31:20) * @return value corresponding to instr(31:20)
*/ */
inline std::int32_t get_csr() const { inline unsigned_T get_csr() const {
std::int32_t aux = 0; return this->m_instr.range(31, 20);
aux = static_cast<std::int32_t>(this->m_instr.range(31, 20));
return aux;
} }
/** /**
* @brief Access to opcode field * @brief Access to opcode field
* @return return opcode field * @return return opcode field
*/ */
inline std::uint32_t opcode() const override { inline unsigned_T opcode() const override {
return static_cast<std::uint32_t>(this->m_instr.range(6, 0)); return this->m_instr.range(6, 0);
} }
bool Exec_LUI() const { bool Exec_LUI() const {
unsigned int rd; unsigned int rd;
std::uint32_t imm; unsigned_T imm;
rd = this->get_rd(); rd = this->get_rd();
imm = get_imm_U() << 12; imm = get_imm_U() << 12;
this->regs->setValue(rd, static_cast<signed_T>(imm)); this->regs->setValue(rd, imm);
this->logger->debug("{} ns. PC: 0x{:x}. LUI: x{:d} <- 0x{:x}", sc_core::sc_time_stamp().value(), this->logger->debug("{} ns. PC: 0x{:x}. LUI: x{:d} <- 0x{:x}", sc_core::sc_time_stamp().value(),
this->regs->getPC(), this->regs->getPC(),
@ -366,12 +272,12 @@ namespace riscv_tlm {
bool Exec_AUIPC() const { bool Exec_AUIPC() const {
unsigned int rd; unsigned int rd;
std::uint32_t imm; unsigned_T imm;
T new_pc; unsigned_T new_pc;
rd = this->get_rd(); rd = this->get_rd();
imm = get_imm_U() << 12; imm = get_imm_U() << 12;
new_pc = static_cast<signed_T>(this->regs->getPC() + imm); new_pc = this->regs->getPC() + imm;
this->regs->setValue(rd, new_pc); this->regs->setValue(rd, new_pc);
@ -386,7 +292,7 @@ namespace riscv_tlm {
bool Exec_JAL() const { bool Exec_JAL() const {
std::int32_t mem_addr; std::int32_t mem_addr;
unsigned int rd; unsigned int rd;
T new_pc, old_pc; unsigned_T new_pc, old_pc;
rd = this->get_rd(); rd = this->get_rd();
mem_addr = get_imm_J(); mem_addr = get_imm_J();
@ -406,9 +312,9 @@ namespace riscv_tlm {
} }
bool Exec_JALR() { bool Exec_JALR() {
std::uint32_t mem_addr; signed_T mem_addr;
unsigned int rd, rs1; unsigned int rd, rs1;
T new_pc, old_pc; unsigned_T new_pc, old_pc;
rd = this->get_rd(); rd = this->get_rd();
rs1 = this->get_rs1(); rs1 = this->get_rs1();
@ -417,7 +323,7 @@ namespace riscv_tlm {
old_pc = this->regs->getPC(); old_pc = this->regs->getPC();
this->regs->setValue(rd, old_pc + 4); this->regs->setValue(rd, old_pc + 4);
new_pc = static_cast<std::uint32_t>((this->regs->getValue(rs1) + mem_addr) & 0xFFFFFFFE); new_pc = static_cast<unsigned_T>((this->regs->getValue(rs1) + mem_addr) & 0xFFFFFFFE);
if ((new_pc & 0x00000003) != 0) { if ((new_pc & 0x00000003) != 0) {
// not aligned // not aligned
@ -442,30 +348,7 @@ namespace riscv_tlm {
bool Exec_BEQ() const { bool Exec_BEQ() const {
unsigned int rs1, rs2; unsigned int rs1, rs2;
std::uint32_t new_pc; unsigned_T val1, val2;
rs1 = this->get_rs1();
rs2 = this->get_rs2();
if (this->regs->getValue(rs1) == this->regs->getValue(rs2)) {
new_pc = static_cast<std::uint32_t>(this->regs->getPC() + get_imm_B());
this->regs->setPC(new_pc);
} else {
this->regs->incPC();
new_pc = static_cast<std::uint32_t>(this->regs->getPC());
}
this->logger->debug("{} ns. PC: 0x{:x}. BEQ: x{:d}(0x{:x}) == x{:d}(0x{:x})? -> PC (0x{:x})",
sc_core::sc_time_stamp().value(), this->regs->getPC(),
rs1, this->regs->getValue(rs1), rs2, this->regs->getValue(rs2), new_pc);
return true;
}
bool Exec_BNE() const {
unsigned int rs1, rs2;
std::uint32_t new_pc;
std::uint32_t val1, val2;
rs1 = this->get_rs1(); rs1 = this->get_rs1();
rs2 = this->get_rs2(); rs2 = this->get_rs2();
@ -473,31 +356,59 @@ namespace riscv_tlm {
val1 = this->regs->getValue(rs1); val1 = this->regs->getValue(rs1);
val2 = this->regs->getValue(rs2); val2 = this->regs->getValue(rs2);
if (val1 != val2) { if (val1 == val2) {
new_pc = static_cast<std::uint32_t>(this->regs->getPC() + get_imm_B()); unsigned_T new_pc;
new_pc = static_cast<unsigned_T>(this->regs->getPC() + get_imm_B());
this->regs->setPC(new_pc);
} else {
this->regs->incPC();
}
this->logger->debug("{} ns. PC: 0x{:x}. BEQ: x{:d}(0x{:x}) == x{:d}(0x{:x})? -> PC (0x{:x})",
sc_core::sc_time_stamp().value(), this->regs->getPC(),
rs1, this->regs->getValue(rs1), rs2, this->regs->getValue(rs2), this->regs->getPC());
return true;
}
bool Exec_BNE() const {
unsigned int rs1, rs2;
signed_T val1, val2;
rs1 = this->get_rs1();
rs2 = this->get_rs2();
val1 = static_cast<signed_T>(this->regs->getValue(rs1));
val2 = static_cast<signed_T>(this->regs->getValue(rs2));
if (val1 != val2) {
unsigned_T new_pc;
new_pc = static_cast<unsigned_T>(this->regs->getPC() + get_imm_B());
this->regs->setPC(new_pc); this->regs->setPC(new_pc);
} else { } else {
this->regs->incPC(); this->regs->incPC();
new_pc = static_cast<std::uint32_t>(this->regs->getPC());
} }
this->logger->debug("{} ns. PC: 0x{:x}. BNE: x{:d}(0x{:x}) != x{:d}(0x{:x})? -> PC (0x{:x})", this->logger->debug("{} ns. PC: 0x{:x}. BNE: x{:d}(0x{:x}) != x{:d}(0x{:x})? -> PC (0x{:x})",
sc_core::sc_time_stamp().value(), this->regs->getPC(), sc_core::sc_time_stamp().value(), this->regs->getPC(),
rs1, val1, rs2, val2, new_pc); rs1, val1, rs2, val2, this->regs->getPC());
return true; return true;
} }
bool Exec_BLT() const { bool Exec_BLT() const {
unsigned int rs1, rs2; unsigned int rs1, rs2;
std::uint32_t new_pc = 0; signed_T val1, val2;
rs1 = this->get_rs1(); rs1 = this->get_rs1();
rs2 = this->get_rs2(); rs2 = this->get_rs2();
if (static_cast<std::int32_t>(this->regs->getValue(rs1)) val1 = static_cast<signed_T>(this->regs->getValue(rs1));
< static_cast<std::int32_t>(this->regs->getValue(rs2))) { val2 = static_cast<signed_T>(this->regs->getValue(rs2));
new_pc = static_cast<std::uint32_t>(this->regs->getPC() + get_imm_B());
if (val1 < val2) {
unsigned_T new_pc;
new_pc = static_cast<unsigned_T>(this->regs->getPC() + get_imm_B());
this->regs->setPC(new_pc); this->regs->setPC(new_pc);
} else { } else {
this->regs->incPC(); this->regs->incPC();
@ -505,21 +416,24 @@ namespace riscv_tlm {
this->logger->debug("{} ns. PC: 0x{:x}. BLT: x{:d}(0x{:x}) < x{:d}(0x{:x})? -> PC (0x{:x})", this->logger->debug("{} ns. PC: 0x{:x}. BLT: x{:d}(0x{:x}) < x{:d}(0x{:x})? -> PC (0x{:x})",
sc_core::sc_time_stamp().value(), this->regs->getPC(), sc_core::sc_time_stamp().value(), this->regs->getPC(),
rs1, this->regs->getValue(rs1), rs2, this->regs->getValue(rs2), new_pc); rs1, this->regs->getValue(rs1), rs2, this->regs->getValue(rs2), this->regs->getPC());
return true; return true;
} }
bool Exec_BGE() const { bool Exec_BGE() const {
unsigned int rs1, rs2; unsigned int rs1, rs2;
std::uint32_t new_pc = 0; signed_T val1, val2;
rs1 = this->get_rs1(); rs1 = this->get_rs1();
rs2 = this->get_rs2(); rs2 = this->get_rs2();
if (static_cast<std::int32_t>(this->regs->getValue(rs1)) val1 = static_cast<signed_T>(this->regs->getValue(rs1));
>= static_cast<std::int32_t>( this->regs->getValue(rs2))) { val2 = static_cast<signed_T>(this->regs->getValue(rs2));
new_pc = static_cast<std::uint32_t>(this->regs->getPC() + get_imm_B());
if (val1 >= val2) {
unsigned_T new_pc;
new_pc = static_cast<unsigned_T>(this->regs->getPC() + get_imm_B());
this->regs->setPC(new_pc); this->regs->setPC(new_pc);
} else { } else {
this->regs->incPC(); this->regs->incPC();
@ -527,63 +441,63 @@ namespace riscv_tlm {
this->logger->debug("{} ns. PC: 0x{:x}. BGE: x{:d}(0x{:x}) > x{:d}(0x{:x})? -> PC (0x{:x})", this->logger->debug("{} ns. PC: 0x{:x}. BGE: x{:d}(0x{:x}) > x{:d}(0x{:x})? -> PC (0x{:x})",
sc_core::sc_time_stamp().value(), this->regs->getPC(), sc_core::sc_time_stamp().value(), this->regs->getPC(),
rs1, this->regs->getValue(rs1), rs2, this->regs->getValue(rs2), new_pc); rs1, this->regs->getValue(rs1), rs2, this->regs->getValue(rs2), this->regs->getPC());
return true; return true;
} }
bool Exec_BLTU() const { bool Exec_BLTU() const {
unsigned int rs1, rs2; unsigned int rs1, rs2;
std::uint32_t new_pc; unsigned_T val1, val2;
rs1 = this->get_rs1(); rs1 = this->get_rs1();
rs2 = this->get_rs2(); rs2 = this->get_rs2();
if (static_cast<std::uint32_t>(this->regs->getValue(rs1)) val1 = this->regs->getValue(rs1);
< static_cast<std::uint32_t>(this->regs->getValue(rs2))) { val2 = this->regs->getValue(rs2);
new_pc = static_cast<std::uint32_t>(this->regs->getPC() + get_imm_B());
if (val1 < val2) {
unsigned_T new_pc;
new_pc = static_cast<unsigned_T>(this->regs->getPC() + get_imm_B());
this->regs->setPC(new_pc); this->regs->setPC(new_pc);
} else { } else {
this->regs->incPC(); this->regs->incPC();
new_pc = static_cast<std::uint32_t>(this->regs->getPC());
} }
this->logger->debug("{} ns. PC: 0x{:x}. BLTU: x{:d}(0x{:x}) < x{:d}(0x{:x})? -> PC (0x{:x})", this->logger->debug("{} ns. PC: 0x{:x}. BLTU: x{:d}(0x{:x}) < x{:d}(0x{:x})? -> PC (0x{:x})",
sc_core::sc_time_stamp().value(), this->regs->getPC(), sc_core::sc_time_stamp().value(), this->regs->getPC(),
rs1, this->regs->getValue(rs1), rs2, this->regs->getValue(rs2), new_pc); rs1, this->regs->getValue(rs1), rs2, this->regs->getValue(rs2), this->regs->getPC());
return true; return true;
} }
bool Exec_BGEU() const { bool Exec_BGEU() const {
unsigned int rs1, rs2; unsigned int rs1, rs2;
unsigned_T val1, val2;
rs1 = this->get_rs1(); rs1 = this->get_rs1();
rs2 = this->get_rs2(); rs2 = this->get_rs2();
if (static_cast<std::uint32_t>(this->regs->getValue(rs1)) val1 = this->regs->getValue(rs1);
>= static_cast<std::uint32_t>(this->regs->getValue(rs2))) { val2 = this->regs->getValue(rs2);
std::uint32_t new_pc;
new_pc = static_cast<std::uint32_t>(this->regs->getPC() + get_imm_B());
this->logger->debug("{} ns. PC: 0x{:x}. BGEU: x{:d}(0x{:x}) > x{:d}(0x{:x}) -> PC (0x{:x})",
sc_core::sc_time_stamp().value(), this->regs->getPC(),
rs1, this->regs->getValue(rs1), rs2, this->regs->getValue(rs2), new_pc);
if (val1 >= val2) {
unsigned_T new_pc;
new_pc = static_cast<unsigned_T>(this->regs->getPC() + get_imm_B());
this->regs->setPC(new_pc); this->regs->setPC(new_pc);
} else { } else {
this->logger->debug("{} ns. PC: 0x{:x}. BGEU: x{:d}(0x{:x}) > x{:d}(0x{:x}) -> PC (0x{:x})",
sc_core::sc_time_stamp().value(), this->regs->getPC(),
rs1, this->regs->getValue(rs1), rs2, this->regs->getValue(rs2),
this->regs->getPC() + 4);
this->regs->incPC(); this->regs->incPC();
} }
this->logger->debug("{} ns. PC: 0x{:x}. BGEU: x{:d}(0x{:x}) > x{:d}(0x{:x}) -> PC (0x{:x})",
sc_core::sc_time_stamp().value(), this->regs->getPC(),
rs1, this->regs->getValue(rs1), rs2, this->regs->getValue(rs2), this->regs->getPC());
return true; return true;
} }
bool Exec_LB() const { bool Exec_LB() const {
std::uint32_t mem_addr; unsigned_T mem_addr;
unsigned int rd, rs1; unsigned int rd, rs1;
std::int32_t imm; std::int32_t imm;
std::int8_t data; std::int8_t data;
@ -606,7 +520,7 @@ namespace riscv_tlm {
} }
bool Exec_LH() const { bool Exec_LH() const {
std::uint32_t mem_addr; unsigned_T mem_addr;
unsigned int rd, rs1; unsigned int rd, rs1;
std::int32_t imm; std::int32_t imm;
int16_t data; int16_t data;
@ -629,7 +543,7 @@ namespace riscv_tlm {
} }
bool Exec_LW() const { bool Exec_LW() const {
std::uint32_t mem_addr; unsigned_T mem_addr;
unsigned int rd, rs1; unsigned int rd, rs1;
std::int32_t imm; std::int32_t imm;
std::uint32_t data; std::uint32_t data;
@ -652,7 +566,7 @@ namespace riscv_tlm {
} }
bool Exec_LBU() const { bool Exec_LBU() const {
std::uint32_t mem_addr; unsigned_T mem_addr;
unsigned int rd, rs1; unsigned int rd, rs1;
std::int32_t imm; std::int32_t imm;
std::uint8_t data; std::uint8_t data;
@ -675,7 +589,7 @@ namespace riscv_tlm {
} }
bool Exec_LHU() const { bool Exec_LHU() const {
std::uint32_t mem_addr; unsigned_T mem_addr;
unsigned int rd, rs1; unsigned int rd, rs1;
std::int32_t imm; std::int32_t imm;
uint16_t data; uint16_t data;
@ -699,7 +613,7 @@ namespace riscv_tlm {
} }
bool Exec_SB() const { bool Exec_SB() const {
std::uint32_t mem_addr; unsigned_T mem_addr;
unsigned int rs1, rs2; unsigned int rs1, rs2;
std::int32_t imm; std::int32_t imm;
std::uint32_t data; std::uint32_t data;
@ -723,7 +637,7 @@ namespace riscv_tlm {
} }
bool Exec_SH() const { bool Exec_SH() const {
std::uint32_t mem_addr; unsigned_T mem_addr;
unsigned int rs1, rs2; unsigned int rs1, rs2;
std::int32_t imm; std::int32_t imm;
std::uint32_t data; std::uint32_t data;
@ -747,7 +661,7 @@ namespace riscv_tlm {
} }
bool Exec_SW() const { bool Exec_SW() const {
std::uint32_t mem_addr; unsigned_T mem_addr;
unsigned int rs1, rs2; unsigned int rs1, rs2;
std::int32_t imm; std::int32_t imm;
std::uint32_t data; std::uint32_t data;
@ -773,13 +687,13 @@ namespace riscv_tlm {
bool Exec_ADDI() const { bool Exec_ADDI() const {
unsigned int rd, rs1; unsigned int rd, rs1;
std::int32_t imm; std::int32_t imm;
std::int32_t calc; signed_T calc;
rd = this->get_rd(); rd = this->get_rd();
rs1 = this->get_rs1(); rs1 = this->get_rs1();
imm = get_imm_I(); imm = get_imm_I();
calc = static_cast<std::int32_t>(this->regs->getValue(rs1)) + imm; calc = static_cast<unsigned_T>(this->regs->getValue(rs1)) + imm;
this->regs->setValue(rd, calc); this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. ADDI: x{:d} + x{:d} -> x{:d}(0x{:x})", this->logger->debug("{} ns. PC: 0x{:x}. ADDI: x{:d} + x{:d} -> x{:d}(0x{:x})",
@ -793,14 +707,16 @@ namespace riscv_tlm {
bool Exec_SLTI() const { bool Exec_SLTI() const {
unsigned int rd, rs1; unsigned int rd, rs1;
std::int32_t imm; std::int32_t imm;
signed_T val1;
rd = this->get_rd(); rd = this->get_rd();
rs1 = this->get_rs1(); rs1 = this->get_rs1();
imm = get_imm_I(); imm = get_imm_I();
if (static_cast<std::int32_t>(this->regs->getValue(rs1)) < imm) { val1 = static_cast<signed_T>(this->regs->getValue(rs1));
this->regs->setValue(rd, 1);
if (val1 < imm) {
this->regs->setValue(rd, 1);
this->logger->debug("{} ns. PC: 0x{:x}. SLTI: x{:d} < x{:d} => 1 -> x{:d}", this->logger->debug("{} ns. PC: 0x{:x}. SLTI: x{:d} < x{:d} => 1 -> x{:d}",
sc_core::sc_time_stamp().value(), sc_core::sc_time_stamp().value(),
this->regs->getPC(), this->regs->getPC(),
@ -818,13 +734,15 @@ namespace riscv_tlm {
bool Exec_SLTIU() const { bool Exec_SLTIU() const {
unsigned int rd, rs1; unsigned int rd, rs1;
std::int32_t imm; unsigned_T imm;
unsigned_T val1;
rd = this->get_rd(); rd = this->get_rd();
rs1 = this->get_rs1(); rs1 = this->get_rs1();
imm = get_imm_I(); imm = static_cast<unsigned_T>(get_imm_I());
val1 = static_cast<unsigned_T>(this->regs->getValue(rs1));
if (static_cast<std::uint32_t>(this->regs->getValue(rs1)) < static_cast<std::uint32_t>(imm)) { if (val1 < imm) {
this->regs->setValue(rd, 1); this->regs->setValue(rd, 1);
this->logger->debug("{} ns. PC: 0x{:x}. SLTIU: x{:d} < x{:d} => 1 -> x{:d}", this->logger->debug("{} ns. PC: 0x{:x}. SLTIU: x{:d} < x{:d} => 1 -> x{:d}",
sc_core::sc_time_stamp().value(), sc_core::sc_time_stamp().value(),
@ -843,15 +761,15 @@ namespace riscv_tlm {
bool Exec_XORI() const { bool Exec_XORI() const {
unsigned int rd, rs1; unsigned int rd, rs1;
std::int32_t imm; unsigned_T imm;
std::uint32_t calc; unsigned_T calc;
rd = this->get_rd(); rd = this->get_rd();
rs1 = this->get_rs1(); rs1 = this->get_rs1();
imm = get_imm_I(); imm = get_imm_I();
calc = this->regs->getValue(rs1) ^ imm; calc = this->regs->getValue(rs1) ^ imm;
this->regs->setValue(rd, static_cast<std::int32_t>(calc)); this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. XORI: x{:d} XOR x{:d} -> x{:d}", sc_core::sc_time_stamp().value(), this->logger->debug("{} ns. PC: 0x{:x}. XORI: x{:d} XOR x{:d} -> x{:d}", sc_core::sc_time_stamp().value(),
this->regs->getPC(), this->regs->getPC(),
@ -862,15 +780,15 @@ namespace riscv_tlm {
bool Exec_ORI() const { bool Exec_ORI() const {
unsigned int rd, rs1; unsigned int rd, rs1;
std::int32_t imm; unsigned_T imm;
std::uint32_t calc; unsigned_T calc;
rd = this->get_rd(); rd = this->get_rd();
rs1 = this->get_rs1(); rs1 = this->get_rs1();
imm = get_imm_I(); imm = get_imm_I();
calc = this->regs->getValue(rs1) | imm; calc = this->regs->getValue(rs1) | imm;
this->regs->setValue(rd, static_cast<std::int32_t>(calc)); this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. ORI: x{:d} OR x{:d} -> x{:d}", sc_core::sc_time_stamp().value(), this->logger->debug("{} ns. PC: 0x{:x}. ORI: x{:d} OR x{:d} -> x{:d}", sc_core::sc_time_stamp().value(),
this->regs->getPC(), this->regs->getPC(),
@ -881,30 +799,28 @@ namespace riscv_tlm {
bool Exec_ANDI() const { bool Exec_ANDI() const {
unsigned int rd, rs1; unsigned int rd, rs1;
std::uint32_t imm; unsigned_T imm;
std::uint32_t calc; unsigned_T calc;
std::uint32_t aux;
rd = this->get_rd(); rd = this->get_rd();
rs1 = this->get_rs1(); rs1 = this->get_rs1();
imm = get_imm_I(); imm = get_imm_I();
aux = this->regs->getValue(rs1); calc = this->regs->getValue(rs1) & imm;
calc = aux & imm; this->regs->setValue(rd, calc);
this->regs->setValue(rd, static_cast<std::int32_t>(calc));
this->logger->debug("{} ns. PC: 0x{:x}. ANDI: x{:d}(0x{:x}) AND 0x{:x} -> x{:d}", this->logger->debug("{} ns. PC: 0x{:x}. ANDI: x{:d} AND 0x{:x} -> x{:d}",
sc_core::sc_time_stamp().value(), sc_core::sc_time_stamp().value(),
this->regs->getPC(), this->regs->getPC(),
rs1, aux, imm, rd); rs1, imm, rd);
return true; return true;
} }
bool Exec_SLLI() { bool Exec_SLLI() {
unsigned int rd, rs1, rs2; unsigned int rd, rs1, rs2;
std::uint32_t shift; unsigned_T shift;
std::uint32_t calc; unsigned_T calc;
rd = this->get_rd(); rd = this->get_rd();
rs1 = this->get_rs1(); rs1 = this->get_rs1();
@ -919,8 +835,8 @@ namespace riscv_tlm {
shift = rs2 & 0x1F; shift = rs2 & 0x1F;
calc = static_cast<std::uint32_t>(this->regs->getValue(rs1)) << shift; calc = static_cast<unsigned_T>(this->regs->getValue(rs1)) << shift;
this->regs->setValue(rd, static_cast<std::int32_t>(calc)); this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. SLLI: x{:d} << {:d} -> x{:d}(0x{:x})", this->logger->debug("{} ns. PC: 0x{:x}. SLLI: x{:d} << {:d} -> x{:d}(0x{:x})",
sc_core::sc_time_stamp().value(), sc_core::sc_time_stamp().value(),
@ -932,8 +848,8 @@ namespace riscv_tlm {
bool Exec_SRLI() const { bool Exec_SRLI() const {
unsigned int rd, rs1, rs2; unsigned int rd, rs1, rs2;
std::uint32_t shift; unsigned_T shift;
std::uint32_t calc; unsigned_T calc;
rd = this->get_rd(); rd = this->get_rd();
rs1 = this->get_rs1(); rs1 = this->get_rs1();
@ -941,8 +857,8 @@ namespace riscv_tlm {
shift = rs2 & 0x1F; shift = rs2 & 0x1F;
calc = static_cast<std::uint32_t>(this->regs->getValue(rs1)) >> shift; calc = static_cast<unsigned_T>(this->regs->getValue(rs1)) >> shift;
this->regs->setValue(rd, static_cast<std::int32_t>(calc)); this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. SRLI: x{:d} >> {:d} -> x{:d}(0x{:x})", this->logger->debug("{} ns. PC: 0x{:x}. SRLI: x{:d} >> {:d} -> x{:d}(0x{:x})",
sc_core::sc_time_stamp().value(), sc_core::sc_time_stamp().value(),
@ -954,8 +870,8 @@ namespace riscv_tlm {
bool Exec_SRAI() const { bool Exec_SRAI() const {
unsigned int rd, rs1, rs2; unsigned int rd, rs1, rs2;
std::uint32_t shift; unsigned_T shift;
std::int32_t calc; signed_T calc;
rd = this->get_rd(); rd = this->get_rd();
rs1 = this->get_rs1(); rs1 = this->get_rs1();
@ -963,7 +879,7 @@ namespace riscv_tlm {
shift = rs2 & 0x1F; shift = rs2 & 0x1F;
calc = static_cast<std::int32_t>(this->regs->getValue(rs1)) >> shift; calc = static_cast<signed_T>(this->regs->getValue(rs1)) >> shift;
this->regs->setValue(rd, calc); this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. SRAI: x{:d} >> {:d} -> x{:d}(0x{:x})", this->logger->debug("{} ns. PC: 0x{:x}. SRAI: x{:d} >> {:d} -> x{:d}(0x{:x})",
@ -976,14 +892,14 @@ namespace riscv_tlm {
bool Exec_ADD() const { bool Exec_ADD() const {
unsigned int rd, rs1, rs2; unsigned int rd, rs1, rs2;
std::uint32_t calc; unsigned_T calc;
rd = this->get_rd(); rd = this->get_rd();
rs1 = this->get_rs1(); rs1 = this->get_rs1();
rs2 = this->get_rs2(); rs2 = this->get_rs2();
calc = this->regs->getValue(rs1) + this->regs->getValue(rs2); calc = this->regs->getValue(rs1) + this->regs->getValue(rs2);
this->regs->setValue(rd, static_cast<std::int32_t>(calc)); this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. ADD: x{:d} + x{:d} -> x{:d}(0x{:x})", this->logger->debug("{} ns. PC: 0x{:x}. ADD: x{:d} + x{:d} -> x{:d}(0x{:x})",
sc_core::sc_time_stamp().value(), sc_core::sc_time_stamp().value(),
@ -995,13 +911,13 @@ namespace riscv_tlm {
bool Exec_SUB() const { bool Exec_SUB() const {
unsigned int rd, rs1, rs2; unsigned int rd, rs1, rs2;
std::uint32_t calc; unsigned_T calc;
rd = this->get_rd(); rd = this->get_rd();
rs1 = this->get_rs1(); rs1 = this->get_rs1();
rs2 = this->get_rs2(); rs2 = this->get_rs2();
calc = this->regs->getValue(rs1) - this->regs->getValue(rs2); calc = this->regs->getValue(rs1) - this->regs->getValue(rs2);
this->regs->setValue(rd, static_cast<std::int32_t>(calc)); this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. SUB: x{:d} - x{:d} -> x{:d}(0x{:x})", this->logger->debug("{} ns. PC: 0x{:x}. SUB: x{:d} - x{:d} -> x{:d}(0x{:x})",
sc_core::sc_time_stamp().value(), sc_core::sc_time_stamp().value(),
@ -1013,8 +929,8 @@ namespace riscv_tlm {
bool Exec_SLL() const { bool Exec_SLL() const {
unsigned int rd, rs1, rs2; unsigned int rd, rs1, rs2;
std::uint32_t shift; unsigned_T shift;
std::uint32_t calc; unsigned_T calc;
rd = this->get_rd(); rd = this->get_rd();
rs1 = this->get_rs1(); rs1 = this->get_rs1();
@ -1022,8 +938,8 @@ namespace riscv_tlm {
shift = this->regs->getValue(rs2) & 0x1F; shift = this->regs->getValue(rs2) & 0x1F;
calc = static_cast<std::uint32_t>(this->regs->getValue(rs1)) << shift; calc = this->regs->getValue(rs1) << shift;
this->regs->setValue(rd, static_cast<std::int32_t>(calc)); this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. SLL: x{:d} << x{:d} -> x{:d}(0x{:x})", this->logger->debug("{} ns. PC: 0x{:x}. SLL: x{:d} << x{:d} -> x{:d}(0x{:x})",
sc_core::sc_time_stamp().value(), sc_core::sc_time_stamp().value(),
@ -1035,12 +951,16 @@ namespace riscv_tlm {
bool Exec_SLT() const { bool Exec_SLT() const {
unsigned int rd, rs1, rs2; unsigned int rd, rs1, rs2;
signed_T val1, val2;
rd = this->get_rd(); rd = this->get_rd();
rs1 = this->get_rs1(); rs1 = this->get_rs1();
rs2 = this->get_rs2(); rs2 = this->get_rs2();
if (this->regs->getValue(rs1) < this->regs->getValue(rs2)) { val1 = static_cast<signed_T>(this->regs->getValue(rs1));
val2 = static_cast<signed_T>(this->regs->getValue(rs2));
if (val1 < val2) {
this->regs->setValue(rd, 1); this->regs->setValue(rd, 1);
this->logger->debug("{} ns. PC: 0x{:x}. SLT: x{:d} < x{:d} => 1 -> x{:d}", this->logger->debug("{} ns. PC: 0x{:x}. SLT: x{:d} < x{:d} => 1 -> x{:d}",
sc_core::sc_time_stamp().value(), sc_core::sc_time_stamp().value(),
@ -1059,13 +979,16 @@ namespace riscv_tlm {
bool Exec_SLTU() const { bool Exec_SLTU() const {
unsigned int rd, rs1, rs2; unsigned int rd, rs1, rs2;
unsigned_T val1, val2;
rd = this->get_rd(); rd = this->get_rd();
rs1 = this->get_rs1(); rs1 = this->get_rs1();
rs2 = this->get_rs2(); rs2 = this->get_rs2();
if (static_cast<std::uint32_t>(this->regs->getValue(rs1)) val1 = this->regs->getValue(rs1);
< static_cast<std::uint32_t>(this->regs->getValue(rs2))) { val2 = this->regs->getValue(rs2);
if (val1 < val2) {
this->regs->setValue(rd, 1); this->regs->setValue(rd, 1);
this->logger->debug("{} ns. PC: 0x{:x}. SLTU: x{:d} < x{:d} => 1 -> x{:d}", this->logger->debug("{} ns. PC: 0x{:x}. SLTU: x{:d} < x{:d} => 1 -> x{:d}",
sc_core::sc_time_stamp().value(), sc_core::sc_time_stamp().value(),
@ -1084,14 +1007,14 @@ namespace riscv_tlm {
bool Exec_XOR() const { bool Exec_XOR() const {
unsigned int rd, rs1, rs2; unsigned int rd, rs1, rs2;
std::uint32_t calc; unsigned_T calc;
rd = this->get_rd(); rd = this->get_rd();
rs1 = this->get_rs1(); rs1 = this->get_rs1();
rs2 = this->get_rs2(); rs2 = this->get_rs2();
calc = this->regs->getValue(rs1) ^ this->regs->getValue(rs2); calc = this->regs->getValue(rs1) ^ this->regs->getValue(rs2);
this->regs->setValue(rd, static_cast<std::int32_t>(calc)); this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. XOR: x{:d} XOR x{:d} -> x{:d}(0x{:x})", this->logger->debug("{} ns. PC: 0x{:x}. XOR: x{:d} XOR x{:d} -> x{:d}(0x{:x})",
sc_core::sc_time_stamp().value(), sc_core::sc_time_stamp().value(),
@ -1103,17 +1026,17 @@ namespace riscv_tlm {
bool Exec_SRL() const { bool Exec_SRL() const {
unsigned int rd, rs1, rs2; unsigned int rd, rs1, rs2;
std::uint32_t shift; unsigned_T shift;
std::uint32_t calc; unsigned_T calc;
rd = this->get_rd(); rd = this->get_rd();
rs1 = this->get_rs1(); rs1 = this->get_rs1();
rs2 = this->get_rs2(); rs2 = this->get_rs2();
shift = this->regs->getValue(rs2) & 0x1F; shift = this->regs->getValue(rs2) & 0x1F;
calc = this->regs->getValue(rs1) >> shift;
calc = static_cast<std::uint32_t>(this->regs->getValue(rs1)) >> shift; this->regs->setValue(rd, calc);
this->regs->setValue(rd, static_cast<std::int32_t>(calc));
this->logger->debug("{} ns. PC: 0x{:x}. SRL: x{:d} >> {:d} -> x{:d}(0x{:x})", this->logger->debug("{} ns. PC: 0x{:x}. SRL: x{:d} >> {:d} -> x{:d}(0x{:x})",
sc_core::sc_time_stamp().value(), sc_core::sc_time_stamp().value(),
@ -1125,16 +1048,15 @@ namespace riscv_tlm {
bool Exec_SRA() const { bool Exec_SRA() const {
unsigned int rd, rs1, rs2; unsigned int rd, rs1, rs2;
std::uint32_t shift; unsigned_T shift;
std::int32_t calc; signed_T calc;
rd = this->get_rd(); rd = this->get_rd();
rs1 = this->get_rs1(); rs1 = this->get_rs1();
rs2 = this->get_rs2(); rs2 = this->get_rs2();
shift = this->regs->getValue(rs2) & 0x1F; shift = this->regs->getValue(rs2) & 0x1F;
calc = static_cast<signed_T>(this->regs->getValue(rs1)) >> shift;
calc = static_cast<std::int32_t>(this->regs->getValue(rs1)) >> shift;
this->regs->setValue(rd, calc); this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. SRA: x{:d} >> {:d} -> x{:d}(0x{:x})", this->logger->debug("{} ns. PC: 0x{:x}. SRA: x{:d} >> {:d} -> x{:d}(0x{:x})",
@ -1147,14 +1069,14 @@ namespace riscv_tlm {
bool Exec_OR() const { bool Exec_OR() const {
unsigned int rd, rs1, rs2; unsigned int rd, rs1, rs2;
std::uint32_t calc; unsigned_T calc;
rd = this->get_rd(); rd = this->get_rd();
rs1 = this->get_rs1(); rs1 = this->get_rs1();
rs2 = this->get_rs2(); rs2 = this->get_rs2();
calc = this->regs->getValue(rs1) | this->regs->getValue(rs2); calc = this->regs->getValue(rs1) | this->regs->getValue(rs2);
this->regs->setValue(rd, static_cast<std::int32_t>(calc)); this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. OR: x{:d} OR x{:d} -> x{:d}(0x{:x})", this->logger->debug("{} ns. PC: 0x{:x}. OR: x{:d} OR x{:d} -> x{:d}(0x{:x})",
sc_core::sc_time_stamp().value(), sc_core::sc_time_stamp().value(),
@ -1166,14 +1088,14 @@ namespace riscv_tlm {
bool Exec_AND() const { bool Exec_AND() const {
unsigned int rd, rs1, rs2; unsigned int rd, rs1, rs2;
std::uint32_t calc; unsigned_T calc;
rd = this->get_rd(); rd = this->get_rd();
rs1 = this->get_rs1(); rs1 = this->get_rs1();
rs2 = this->get_rs2(); rs2 = this->get_rs2();
calc = this->regs->getValue(rs1) & this->regs->getValue(rs2); calc = this->regs->getValue(rs1) & this->regs->getValue(rs2);
this->regs->setValue(rd, static_cast<std::int32_t>(calc)); this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. AND: x{:d} AND x{:d} -> x{:d}(0x{:x})", this->logger->debug("{} ns. PC: 0x{:x}. AND: x{:d} AND x{:d} -> x{:d}(0x{:x})",
sc_core::sc_time_stamp().value(), sc_core::sc_time_stamp().value(),

View File

@ -154,7 +154,7 @@ namespace riscv_tlm {
* it triggers an IRQ when called * it triggers an IRQ when called
*/ */
void call_interrupt(tlm::tlm_generic_payload &trans, void call_interrupt(tlm::tlm_generic_payload &trans,
sc_core::sc_time &delay); sc_core::sc_time &delay) override;
}; // RV32 class }; // RV32 class
/** /**
@ -205,7 +205,7 @@ namespace riscv_tlm {
* it triggers an IRQ when called * it triggers an IRQ when called
*/ */
void call_interrupt(tlm::tlm_generic_payload &trans, void call_interrupt(tlm::tlm_generic_payload &trans,
sc_core::sc_time &delay); sc_core::sc_time &delay) override;
}; // RV64 class }; // RV64 class
} }

View File

@ -100,16 +100,19 @@ namespace riscv_tlm {
public: public:
/** /**
* @brief Constructor, same as base clase * @brief Constructor, same as base class
*/ */
using extension_base<T>::extension_base; using extension_base<T>::extension_base;
using signed_T = typename std::make_signed<T>::type;
using unsigned_T = typename std::make_unsigned<T>::type;
/** /**
* @brief Access to opcode field * @brief Access to opcode field
* @return return opcode field * @return return opcode field
*/ */
[[nodiscard]] inline std::uint32_t opcode() const override { [[nodiscard]] inline unsigned_T opcode() const override {
return static_cast<std::uint32_t>(this->m_instr.range(1, 0)); return static_cast<unsigned_T>(this->m_instr.range(1, 0));
} }
[[nodiscard]] inline std::uint32_t get_rdp() const { [[nodiscard]] inline std::uint32_t get_rdp() const {
@ -507,6 +510,8 @@ namespace riscv_tlm {
break; break;
case C_FWWSP: case C_FWWSP:
[[unlikely]] [[unlikely]]
return OP_C_FSWSP;
break;
default: default:
return OP_C_ERROR; return OP_C_ERROR;
break; break;

View File

@ -48,10 +48,13 @@ namespace riscv_tlm {
public: public:
/** /**
* @brief Constructor, same as base clase * @brief Constructor, same as base class
*/ */
using extension_base<T>::extension_base; using extension_base<T>::extension_base;
using signed_T = typename std::make_signed<T>::type;
using unsigned_T = typename std::make_unsigned<T>::type;
/** /**
* @brief Decodes opcode of instruction * @brief Decodes opcode of instruction
* @return opcode of instruction * @return opcode of instruction
@ -342,8 +345,8 @@ namespace riscv_tlm {
* @brief Access to opcode field * @brief Access to opcode field
* @return return opcode field * @return return opcode field
*/ */
[[nodiscard]] inline std::uint32_t opcode() const override { [[nodiscard]] inline unsigned_T opcode() const override {
return static_cast<std::uint32_t>(this->m_instr.range(14, 12)); return static_cast<unsigned_T>(this->m_instr.range(14, 12));
} }
}; };

View File

@ -31,6 +31,9 @@ namespace riscv_tlm {
template<typename T> template<typename T>
class extension_base { class extension_base {
using signed_T = typename std::make_signed<T>::type;
using unsigned_T = typename std::make_unsigned<T>::type;
public: public:
extension_base(const T &instr, Registers<T> *register_bank, extension_base(const T &instr, Registers<T> *register_bank,
MemoryInterface *mem_interface) : MemoryInterface *mem_interface) :
@ -80,7 +83,7 @@ namespace riscv_tlm {
} }
/* pure virtual functions */ /* pure virtual functions */
virtual std::uint32_t opcode() const = 0; virtual unsigned_T opcode() const = 0;
virtual unsigned int get_rd() const { virtual unsigned int get_rd() const {
return m_instr.range(11, 7); return m_instr.range(11, 7);

View File

@ -6,3 +6,135 @@
*/ */
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#include "BASE_ISA.h"
namespace riscv_tlm {
///// RV32 Specialization
template<>
int32_t BASE_ISA<std::uint32_t>::get_imm_I() const {
std::uint32_t aux = 0;
aux = this->m_instr.range(31, 20);
/* sign extension (optimize) */
if (this->m_instr[31] == 1) {
aux |= (0b11111111111111111111) << 12;
}
return static_cast<std::int32_t>(aux);
}
template<>
std::int32_t BASE_ISA<std::uint32_t>::get_imm_S() const {
std::uint32_t aux = 0;
aux = this->m_instr.range(31, 25) << 5;
aux |= this->m_instr.range(11, 7);
if (this->m_instr[31] == 1) {
aux |= (0b11111111111111111111) << 12;
}
return static_cast<std::int32_t>(aux);
}
template<>
std::int32_t BASE_ISA<std::uint32_t>::get_imm_B() const {
std::uint32_t aux = 0;
aux |= this->m_instr[7] << 11;
aux |= this->m_instr.range(30, 25) << 5;
aux |= this->m_instr[31] << 12;
aux |= this->m_instr.range(11, 8) << 1;
if (this->m_instr[31] == 1) {
aux |= (0b11111111111111111111) << 12;
}
return static_cast<std::int32_t>(aux);
}
template<>
std::int32_t BASE_ISA<std::uint32_t>::get_imm_J() const {
std::uint32_t aux = 0;
aux = this->m_instr[31] << 20;
aux |= this->m_instr.range(19, 12) << 12;
aux |= this->m_instr[20] << 11;
aux |= this->m_instr.range(30, 21) << 1;
/* bit extension (better way to do that?) */
if (this->m_instr[31] == 1) {
aux |= (0b111111111111) << 20;
}
return static_cast<std::int32_t>(aux);
}
///// RV64 Specialization
template<>
int64_t BASE_ISA<std::uint64_t>::get_imm_I() const {
std::uint64_t aux = 0;
aux = this->m_instr.range(31, 20);
/* sign extension (optimize) */
if (this->m_instr[31] == 1) {
aux |= (0b11111111111111111111) << 12;
aux |= 0xFFFFFFFFULL << 32;
}
return static_cast<std::int64_t>(aux);
}
template<>
std::int64_t BASE_ISA<std::uint64_t>::get_imm_S() const {
std::uint64_t aux = 0;
aux = this->m_instr.range(31, 25) << 5;
aux |= this->m_instr.range(11, 7);
if (this->m_instr[31] == 1) {
aux |= (0b11111111111111111111) << 12;
aux |= 0xFFFFFFFFULL << 32;
}
return static_cast<std::int64_t>(aux);
}
template<>
std::int64_t BASE_ISA<std::uint64_t>::get_imm_B() const {
std::uint64_t aux = 0;
aux |= this->m_instr[7] << 11;
aux |= this->m_instr.range(30, 25) << 5;
aux |= this->m_instr[31] << 12;
aux |= this->m_instr.range(11, 8) << 1;
if (this->m_instr[31] == 1) {
aux |= (0b11111111111111111111) << 12;
aux |= 0xFFFFFFFFULL << 32;
}
return static_cast<std::int64_t>(aux);
}
template<>
std::int64_t BASE_ISA<std::uint64_t>::get_imm_J() const {
std::uint64_t aux = 0;
aux = this->m_instr[31] << 20;
aux |= this->m_instr.range(19, 12) << 12;
aux |= this->m_instr[20] << 11;
aux |= this->m_instr.range(30, 21) << 1;
/* bit extension (better way to do that?) */
if (this->m_instr[31] == 1) {
aux |= (0b111111111111) << 20;
}
return static_cast<std::int64_t>(aux);
}
}

View File

@ -17,7 +17,7 @@ namespace riscv_tlm {
m_qk = new tlm_utils::tlm_quantumkeeper(); m_qk = new tlm_utils::tlm_quantumkeeper();
m_qk->reset(); m_qk->reset();
mem_intf = nullptr;
dmi_ptr_valid = false; dmi_ptr_valid = false;
irq_already_down = false; irq_already_down = false;