Add full RV64 simulation. It passes almost all tests.

This commit is contained in:
Màrius Montón 2022-09-15 12:48:22 +02:00
parent 9176dbb2ed
commit ab2d5139c2
No known key found for this signature in database
GPG Key ID: FA199E7A752699F0
4 changed files with 1211 additions and 292 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -78,6 +78,7 @@ namespace riscv_tlm {
bool NOP() {
logger->debug("{} ns. PC: 0x{:x}. NOP! new PC 0x{:x} ", sc_core::sc_time_stamp().value(), regs->getPC());
logger->flush();
sc_core::sc_stop();
return true;
}
@ -117,6 +118,10 @@ namespace riscv_tlm {
m_instr.range(14, 12) = value;
}
// For RV64 SLLI, SRLI & SRAI
virtual unsigned int get_shamt_slli() const {
return m_instr.range(25, 20);
}
virtual void dump() const {
std::cout << std::hex << "0x" << m_instr << std::dec << std::endl;
}

View File

@ -12,7 +12,7 @@ namespace riscv_tlm {
///// RV32 Specialization
template<>
int32_t BASE_ISA<std::uint32_t>::get_imm_I() const {
std::int32_t BASE_ISA<std::uint32_t>::get_imm_I() const {
std::uint32_t aux = 0;
aux = this->m_instr.range(31, 20);
@ -73,9 +73,160 @@ namespace riscv_tlm {
return static_cast<std::int32_t>(aux);
}
template<>
std::uint32_t BASE_ISA<std::uint32_t>::get_funct7b() const {
return this->m_instr.range(31, 25);
}
// SLLI, SRLI and SRAI get different shamt field depending on RV32 or RV64
template<>
bool BASE_ISA<std::uint32_t>::Exec_SLLI() {
unsigned int rd, rs1, rs2;
unsigned_T shift;
unsigned_T calc;
rd = this->get_rd();
rs1 = this->get_rs1();
rs2 = get_shamt();
if (rs2 >= 0x20) {
std::cout << "ILLEGAL INSTRUCTION, shamt[5] != 0" << "\n";
sc_core::sc_stop();
this->RaiseException(EXCEPTION_CAUSE_ILLEGAL_INSTRUCTION, this->m_instr);
return false;
}
shift = rs2 & 0x1F;
calc = static_cast<unsigned_T>(this->regs->getValue(rs1)) << shift;
this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. SLLI: x{:d} << {:d} -> x{:d}(0x{:x})",
sc_core::sc_time_stamp().value(),
this->regs->getPC(),
rs1, shift, rd, calc);
return true;
}
template<>
bool BASE_ISA<std::uint32_t>::Exec_SRLI() const {
unsigned int rd, rs1, rs2;
unsigned_T shift;
unsigned_T calc;
rd = this->get_rd();
rs1 = this->get_rs1();
rs2 = this->get_rs2();
shift = rs2 & 0x1F;
calc = static_cast<unsigned_T>(this->regs->getValue(rs1)) >> shift;
this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. SRLI: x{:d} >> {:d} -> x{:d}(0x{:x})",
sc_core::sc_time_stamp().value(),
this->regs->getPC(),
rs1, shift, rd, calc);
return true;
}
template<>
bool BASE_ISA<std::uint32_t>::Exec_SRAI() const {
unsigned int rd, rs1, rs2;
unsigned_T shift;
signed_T calc;
rd = this->get_rd();
rs1 = this->get_rs1();
rs2 = this->get_rs2();
shift = rs2 & 0x1F;
calc = static_cast<signed_T>(this->regs->getValue(rs1)) >> shift;
this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. SRAI: x{:d} >> {:d} -> x{:d}(0x{:x})",
sc_core::sc_time_stamp().value(),
this->regs->getPC(),
rs1, shift, rd, calc);
return true;
}
template<>
bool BASE_ISA<std::uint32_t>::Exec_SRL() const {
unsigned int rd, rs1, rs2;
unsigned_T shift;
unsigned_T calc;
rd = this->get_rd();
rs1 = this->get_rs1();
rs2 = this->get_rs2();
shift = this->regs->getValue(rs2) & 0x1F;
calc = this->regs->getValue(rs1) >> shift;
this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. SRL: x{:d} >> {:d} -> x{:d}(0x{:x})",
sc_core::sc_time_stamp().value(),
this->regs->getPC(),
rs1, shift, rd, calc);
return true;
}
template<>
bool BASE_ISA<std::uint32_t>::Exec_SRA() const {
unsigned int rd, rs1, rs2;
unsigned_T shift;
signed_T calc;
rd = this->get_rd();
rs1 = this->get_rs1();
rs2 = this->get_rs2();
shift = this->regs->getValue(rs2) & 0x1F;
calc = static_cast<signed_T>(this->regs->getValue(rs1)) >> shift;
this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. SRA: x{:d} >> {:d} -> x{:d}(0x{:x})",
sc_core::sc_time_stamp().value(),
this->regs->getPC(),
rs1, shift, rd, calc);
return true;
}
template<>
bool BASE_ISA<std::uint32_t>::Exec_SLL() const {
unsigned int rd, rs1, rs2;
unsigned_T shift;
unsigned_T calc;
rd = this->get_rd();
rs1 = this->get_rs1();
rs2 = this->get_rs2();
shift = this->regs->getValue(rs2) & 0x1F;
calc = this->regs->getValue(rs1) << shift;
this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. SLL: x{:d} << x{:d} -> x{:d}(0x{:x})",
sc_core::sc_time_stamp().value(),
this->regs->getPC(),
rs1, shift, rd, calc);
return true;
}
///// RV64 Specialization
template<>
int64_t BASE_ISA<std::uint64_t>::get_imm_I() const {
std::int64_t BASE_ISA<std::uint64_t>::get_imm_I() const {
std::uint64_t aux = 0;
aux = this->m_instr.range(31, 20);
@ -137,4 +288,161 @@ namespace riscv_tlm {
return static_cast<std::int64_t>(aux);
}
}
template<>
std::uint32_t BASE_ISA<std::uint64_t>::get_funct7b() const {
return this->m_instr.range(31, 26);
}
// PASS
template<>
bool BASE_ISA<std::uint64_t>::Exec_SLLI() {
unsigned int rd, rs1, rs2;
unsigned_T shift;
unsigned_T calc;
rd = this->get_rd();
rs1 = this->get_rs1();
rs2 = this->get_shamt_slli();
if (rs2 >= 0x40) {
std::cout << "ILLEGAL INSTRUCTION, shamt[5] > 0x40" << "\n";
sc_core::sc_stop();
this->RaiseException(EXCEPTION_CAUSE_ILLEGAL_INSTRUCTION, this->m_instr);
return false;
}
shift = rs2 & 0x3F;
calc = this->regs->getValue(rs1) << shift;
this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. SLLI: x{:d} << {:d} -> x{:d}(0x{:x})",
sc_core::sc_time_stamp().value(),
this->regs->getPC(),
rs1, shift, rd, calc);
return true;
}
// PASS
template<>
bool BASE_ISA<std::uint64_t>::Exec_SRLI() const {
unsigned int rd, rs1, rs2;
unsigned_T shift;
unsigned_T calc;
rd = this->get_rd();
rs1 = this->get_rs1();
rs2 = this->get_shamt_slli();
shift = rs2 & 0x3F;
calc = static_cast<unsigned_T>(this->regs->getValue(rs1)) >> shift;
this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. SRLI: x{:d} >> {:d} -> x{:d}(0x{:x})",
sc_core::sc_time_stamp().value(),
this->regs->getPC(),
rs1, shift, rd, calc);
return true;
}
// PASS
template<>
bool BASE_ISA<std::uint64_t>::Exec_SRAI() const {
unsigned int rd, rs1, rs2;
unsigned_T shift;
signed_T calc;
rd = this->get_rd();
rs1 = this->get_rs1();
rs2 = this->get_shamt_slli();
shift = rs2 & 0x3F;
calc = static_cast<signed_T>(static_cast<signed_T>(this->regs->getValue(rs1)) >> shift);
this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. SRAI: x{:d} >> {:d} -> x{:d}(0x{:x})",
sc_core::sc_time_stamp().value(),
this->regs->getPC(),
rs1, shift, rd, calc);
return true;
}
// PASS
template<>
bool BASE_ISA<std::uint64_t>::Exec_SRL() const {
unsigned int rd, rs1, rs2;
unsigned_T shift;
unsigned_T calc;
rd = this->get_rd();
rs1 = this->get_rs1();
rs2 = this->get_rs2();
shift = this->regs->getValue(rs2) & 0x3F;
calc = this->regs->getValue(rs1) >> shift;
this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. SRL: x{:d} >> {:d} -> x{:d}(0x{:x})",
sc_core::sc_time_stamp().value(),
this->regs->getPC(),
rs1, shift, rd, calc);
return true;
}
// PASS
template<>
bool BASE_ISA<std::uint64_t>::Exec_SRA() const {
unsigned int rd, rs1, rs2;
unsigned_T shift;
signed_T calc;
rd = this->get_rd();
rs1 = this->get_rs1();
rs2 = this->get_rs2();
shift = this->regs->getValue(rs2) & 0x3F;
calc = static_cast<signed_T>(this->regs->getValue(rs1)) >> shift;
this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. SRA: x{:d} >> {:d} -> x{:d}(0x{:x})",
sc_core::sc_time_stamp().value(),
this->regs->getPC(),
rs1, shift, rd, calc);
return true;
}
// PASS
template<>
bool BASE_ISA<std::uint64_t>::Exec_SLL() const {
unsigned int rd, rs1, rs2;
unsigned_T shift;
unsigned_T calc;
rd = this->get_rd();
rs1 = this->get_rs1();
rs2 = this->get_rs2();
shift = this->regs->getValue(rs2) & 0x3F;
calc = this->regs->getValue(rs1) << shift;
this->regs->setValue(rd, calc);
this->logger->debug("{} ns. PC: 0x{:x}. SLL: x{:d} << x{:d} -> x{:d}(0x{:x})",
sc_core::sc_time_stamp().value(),
this->regs->getPC(),
rs1, shift, rd, calc);
return true;
}
}