first implementation supporting exceptions
This commit is contained in:
		
							parent
							
								
									6726b59c3c
								
							
						
					
					
						commit
						b9e26e4dea
					
				|  | @ -73,7 +73,7 @@ public: | |||
|   void XORI(Instruction &inst); | ||||
|   void ORI(Instruction &inst); | ||||
|   void ANDI(Instruction &inst); | ||||
|   void SLLI(Instruction &inst); | ||||
|   bool SLLI(Instruction &inst); | ||||
|   void SRLI(Instruction &inst); | ||||
|   void SRAI(Instruction &inst); | ||||
| 
 | ||||
|  | @ -138,6 +138,9 @@ public: | |||
| private: | ||||
|   uint32_t readDataMem(uint32_t addr, int size); | ||||
|   void writeDataMem(uint32_t addr, uint32_t data, int size); | ||||
| 
 | ||||
|   void RaiseException(uint32_t cause); | ||||
| 
 | ||||
|   Registers *regs; | ||||
|   Performance *perf; | ||||
|   Log *log; | ||||
|  |  | |||
|  | @ -167,6 +167,13 @@ typedef enum { | |||
|   CSRRCI  = 0b111, | ||||
| } 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 | ||||
|  */ | ||||
|  |  | |||
|  | @ -22,6 +22,11 @@ | |||
| #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_MISA (0x301) | ||||
| #define CSR_MEDELEG (0x302) | ||||
|  | @ -30,6 +35,12 @@ | |||
| #define CSR_MTVEC (0x305) | ||||
| #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_dt; | ||||
|  |  | |||
|  | @ -242,7 +242,7 @@ bool CPU::process_base_instruction(Instruction &inst) { | |||
|       exec->ANDI(inst); | ||||
|       break; | ||||
|     case OP_SLLI: | ||||
|       exec->SLLI(inst); | ||||
|       PC_not_affected = exec->SLLI(inst); | ||||
|       break; | ||||
|     case OP_SRLI: | ||||
|       exec->SRLI(inst); | ||||
|  |  | |||
|  | @ -535,7 +535,7 @@ void Execute::ANDI(Instruction &inst) { | |||
|           << rd  << endl; | ||||
| } | ||||
| 
 | ||||
| void Execute::SLLI(Instruction &inst) { | ||||
| bool Execute::SLLI(Instruction &inst) { | ||||
|   int rd, rs1, rs2; | ||||
|   uint32_t shift; | ||||
|   uint32_t calc; | ||||
|  | @ -547,6 +547,9 @@ void Execute::SLLI(Instruction &inst) { | |||
|   if (rs2 >= 0x20) { | ||||
|     // raise an exception, but how?
 | ||||
|     cout << "ILEGAL INSTRUCTION, shamt[5] != 0" << endl; | ||||
|     RaiseException(EXCEPTION_CAUSE_ILLEGAL_INSTRUCTION); | ||||
| 
 | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   shift = rs2 & 0x1F; | ||||
|  | @ -557,6 +560,8 @@ void Execute::SLLI(Instruction &inst) { | |||
|   log->SC_log(Log::INFO) << "SLLI: x" | ||||
|           << rs1 << " << " << shift << " -> x" | ||||
|           << rd << "(0x" << hex << calc << ")" << endl; | ||||
| 
 | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| void Execute::SRLI(Instruction &inst) { | ||||
|  | @ -951,7 +956,7 @@ void Execute::CSRRCI(Instruction &inst) { | |||
| void Execute::MRET(Instruction &inst) { | ||||
|   uint32_t new_pc = 0; | ||||
| 
 | ||||
|   new_pc = regs->getCSR(0x341); | ||||
|   new_pc = regs->getCSR(CSR_MEPC); | ||||
|   regs->setPC(new_pc); | ||||
| 
 | ||||
|   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); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 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