first implementation supporting exceptions
This commit is contained in:
parent
6726b59c3c
commit
b9e26e4dea
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue