first implementation supporting exceptions

This commit is contained in:
mariusmonton 2018-11-22 14:38:31 +01:00
parent 6726b59c3c
commit b9e26e4dea
5 changed files with 51 additions and 4 deletions

View File

@ -73,7 +73,7 @@ public:
void XORI(Instruction &inst); void XORI(Instruction &inst);
void ORI(Instruction &inst); void ORI(Instruction &inst);
void ANDI(Instruction &inst); void ANDI(Instruction &inst);
void SLLI(Instruction &inst); bool SLLI(Instruction &inst);
void SRLI(Instruction &inst); void SRLI(Instruction &inst);
void SRAI(Instruction &inst); void SRAI(Instruction &inst);
@ -138,6 +138,9 @@ public:
private: private:
uint32_t readDataMem(uint32_t addr, int size); uint32_t readDataMem(uint32_t addr, int size);
void writeDataMem(uint32_t addr, uint32_t data, int size); void writeDataMem(uint32_t addr, uint32_t data, int size);
void RaiseException(uint32_t cause);
Registers *regs; Registers *regs;
Performance *perf; Performance *perf;
Log *log; Log *log;

View File

@ -167,6 +167,13 @@ typedef enum {
CSRRCI = 0b111, CSRRCI = 0b111,
} Codes; } Codes;
#define EXCEPTION_CAUSE_INSTRUCTION_MISALIGN 0
#define EXCEPTION_CAUSE_INSTRUCTION_ACCESS 1
#define EXCEPTION_CAUSE_ILLEGAL_INSTRUCTION 2
#define EXCEPTION_CAUSE_BREAKPOINT 3
#define EXCEPTION_CAUSE_LOAD_ADDR_MISALIGN 4
#define EXCEPTION_CAUSE_LOAD_ACCESS_FAULT 5
/** /**
* @brief Instruction decoding and fields access * @brief Instruction decoding and fields access
*/ */

View File

@ -22,6 +22,11 @@
#define WARL_MXL (1 << 30) #define WARL_MXL (1 << 30)
#define CSR_MVENDORID (0xF11)
#define CSR_MARCHID (0xF12)
#define CSR_MIMPID (0xF13)
#define CSR_MHARTID (0xF14)
#define CSR_MSTATUS (0x300) #define CSR_MSTATUS (0x300)
#define CSR_MISA (0x301) #define CSR_MISA (0x301)
#define CSR_MEDELEG (0x302) #define CSR_MEDELEG (0x302)
@ -30,6 +35,12 @@
#define CSR_MTVEC (0x305) #define CSR_MTVEC (0x305)
#define CSR_MCOUNTEREN (0x306) #define CSR_MCOUNTEREN (0x306)
#define CSR_MSCRATCH (0x340)
#define CSR_MEPC (0x341)
#define CSR_MCAUSE (0x342)
#define CSR_MTVAL (0x343)
#define CSR_MIP (0x344)
using namespace sc_core; using namespace sc_core;
using namespace sc_dt; using namespace sc_dt;

View File

@ -242,7 +242,7 @@ bool CPU::process_base_instruction(Instruction &inst) {
exec->ANDI(inst); exec->ANDI(inst);
break; break;
case OP_SLLI: case OP_SLLI:
exec->SLLI(inst); PC_not_affected = exec->SLLI(inst);
break; break;
case OP_SRLI: case OP_SRLI:
exec->SRLI(inst); exec->SRLI(inst);

View File

@ -535,7 +535,7 @@ void Execute::ANDI(Instruction &inst) {
<< rd << endl; << rd << endl;
} }
void Execute::SLLI(Instruction &inst) { bool Execute::SLLI(Instruction &inst) {
int rd, rs1, rs2; int rd, rs1, rs2;
uint32_t shift; uint32_t shift;
uint32_t calc; uint32_t calc;
@ -547,6 +547,9 @@ void Execute::SLLI(Instruction &inst) {
if (rs2 >= 0x20) { if (rs2 >= 0x20) {
// raise an exception, but how? // raise an exception, but how?
cout << "ILEGAL INSTRUCTION, shamt[5] != 0" << endl; cout << "ILEGAL INSTRUCTION, shamt[5] != 0" << endl;
RaiseException(EXCEPTION_CAUSE_ILLEGAL_INSTRUCTION);
return false;
} }
shift = rs2 & 0x1F; shift = rs2 & 0x1F;
@ -557,6 +560,8 @@ void Execute::SLLI(Instruction &inst) {
log->SC_log(Log::INFO) << "SLLI: x" log->SC_log(Log::INFO) << "SLLI: x"
<< rs1 << " << " << shift << " -> x" << rs1 << " << " << shift << " -> x"
<< rd << "(0x" << hex << calc << ")" << endl; << rd << "(0x" << hex << calc << ")" << endl;
return true;
} }
void Execute::SRLI(Instruction &inst) { void Execute::SRLI(Instruction &inst) {
@ -951,7 +956,7 @@ void Execute::CSRRCI(Instruction &inst) {
void Execute::MRET(Instruction &inst) { void Execute::MRET(Instruction &inst) {
uint32_t new_pc = 0; uint32_t new_pc = 0;
new_pc = regs->getCSR(0x341); new_pc = regs->getCSR(CSR_MEPC);
regs->setPC(new_pc); regs->setPC(new_pc);
log->SC_log(Log::INFO) << "MRET: PC <- 0x" << hex << new_pc << endl; log->SC_log(Log::INFO) << "MRET: PC <- 0x" << hex << new_pc << endl;
@ -1611,3 +1616,24 @@ void Execute::writeDataMem(uint32_t addr, uint32_t data, int size) {
data_bus->b_transport( trans, delay); data_bus->b_transport( trans, delay);
} }
void Execute::RaiseException(uint32_t cause) {
uint32_t new_pc, current_pc, m_cause;
current_pc = regs->getPC();
m_cause = regs->getCSR(CSR_MSTATUS);
m_cause |= cause;
new_pc = regs->getCSR(CSR_MTVEC);
regs->setCSR(CSR_MEPC, current_pc );
regs->setCSR(CSR_MTVAL, current_pc );
regs->setCSR(CSR_MCAUSE, cause);
regs->setCSR(CSR_MSTATUS, m_cause);
regs->setPC( new_pc);
log->SC_log(Log::INFO) << "Exception! new PC " << hex << new_pc << endl;
}