fixed CSRRS and CSRRC bug

This commit is contained in:
mariusmonton 2018-11-22 12:08:16 +01:00
parent 9cd354b822
commit 0cd34f9f3b
3 changed files with 47 additions and 15 deletions

View File

@ -16,6 +16,21 @@
#include "Performance.h" #include "Performance.h"
#include "Memory.h" #include "Memory.h"
#define WARL_M_EXTENSION (1 << 12)
#define WARL_C_EXTENSION (1 << 2)
#define WARL_I_BASE (1 << 8)
#define WARL_MXL (1 << 29)
#define CSR_MSTATUS (0x300)
#define CSR_MISA (0x301)
#define CSR_MEDELEG (0x302)
#define CSR_MIDELEG (0x303)
#define CSR_MIE (0x304)
#define CSR_MTVEC (0x305)
#define CSR_MCOUNTEREN (0x306)
using namespace sc_core; using namespace sc_core;
using namespace sc_dt; using namespace sc_dt;
using namespace std; using namespace std;
@ -141,18 +156,14 @@ public:
* @param csr CSR number to access * @param csr CSR number to access
* @return CSR value * @return CSR value
*/ */
inline uint32_t getCSR(int csr) { uint32_t getCSR(int csr);
return CSR[csr];
}
/** /**
* @brief Set CSR value * @brief Set CSR value
* @param csr CSR number to access * @param csr CSR number to access
* @param value new value to register * @param value new value to register
*/ */
inline void setCSR(int csr, uint32_t value) { void setCSR(int csr, uint32_t value);
CSR[csr] = value;
}
/** /**
* Dump register data to console * Dump register data to console
@ -174,6 +185,8 @@ private:
*/ */
uint32_t CSR[4096]; uint32_t CSR[4096];
Performance *perf; Performance *perf;
void initCSR(void);
}; };
#endif #endif

View File

@ -829,21 +829,23 @@ void Execute::CSRRS(Instruction &inst) {
/* These operations must be atomical */ /* These operations must be atomical */
aux = regs->getCSR(csr); aux = regs->getCSR(csr);
bitmask = regs->getValue(rs1);
regs->setValue(rd, aux); regs->setValue(rd, aux);
bitmask = regs->getValue(rs1);
aux2 = aux | bitmask; aux2 = aux | bitmask;
regs->setCSR(csr, aux2); regs->setCSR(csr, aux2);
log->SC_log(Log::INFO) << "CSRRS: CSR #" log->SC_log(Log::INFO) << "CSRRS: CSR #"
<< csr << "(" << aux << ") -> x" << dec << rd << csr << "(0x" << hex << aux << ") -> x" << dec << rd
<< ". x" << rs1 << " & CSR #" << csr << endl; << ". x" << rs1 << " & CSR #" << csr
<< " <- 0x" << hex << aux2 << endl;
} }
void Execute::CSRRC(Instruction &inst) { void Execute::CSRRC(Instruction &inst) {
int rd, rs1; int rd, rs1;
int csr; int csr;
uint32_t bitmask, aux; uint32_t bitmask, aux, aux2;
rd = inst.get_rd(); rd = inst.get_rd();
rs1 = inst.get_rs1(); rs1 = inst.get_rs1();
@ -855,15 +857,17 @@ void Execute::CSRRC(Instruction &inst) {
/* These operations must be atomical */ /* These operations must be atomical */
aux = regs->getCSR(csr); aux = regs->getCSR(csr);
bitmask = regs->getValue(rs1);
regs->setValue(rd, aux); regs->setValue(rd, aux);
bitmask = regs->getValue(rs1); aux2 = aux & ~bitmask;
aux = aux & ~bitmask; regs->setCSR(csr, aux2);
regs->setCSR(csr, aux);
log->SC_log(Log::INFO) << "CSRRC: CSR #" log->SC_log(Log::INFO) << "CSRRC: CSR #"
<< csr << " -> x" << rd << csr << "(0x" << hex << aux << ") -> x" << dec << rd
<< ". x" << rs1 << " & CSR #" << csr << endl; << ". x" << rs1 << " & CSR #" << csr
<< " <- 0x" << hex << aux2 << endl;
} }
void Execute::CSRRWI(Instruction &inst) { void Execute::CSRRWI(Instruction &inst) {

View File

@ -6,6 +6,7 @@ Registers::Registers() {
memset(CSR, 0, sizeof(uint32_t)*4096); memset(CSR, 0, sizeof(uint32_t)*4096);
perf = Performance::getInstance(); perf = Performance::getInstance();
initCSR();
//register_bank[sp] = 1024-1; // SP points to end of memory //register_bank[sp] = 1024-1; // SP points to end of memory
register_bank[sp] = Memory::SIZE-4; register_bank[sp] = Memory::SIZE-4;
register_PC = 0x10000; // default _start address register_PC = 0x10000; // default _start address
@ -82,3 +83,17 @@ uint32_t Registers::getPC() {
void Registers::setPC(uint32_t new_pc) { void Registers::setPC(uint32_t new_pc) {
register_PC = new_pc; register_PC = new_pc;
} }
uint32_t Registers::getCSR(int csr) {
return CSR[csr];
}
void Registers::setCSR(int csr, uint32_t value) {
CSR[csr] = value;
}
void Registers::initCSR() {
CSR[0x301] = WARL_MXL | WARL_M_EXTENSION | WARL_C_EXTENSION | WARL_I_BASE;
}