adding M extensions to simulator
This commit is contained in:
parent
bdf261cbc6
commit
d449ea5502
|
@ -20,6 +20,7 @@
|
|||
#include "Log.h"
|
||||
#include "Instruction.h"
|
||||
#include "C_Instruction.h"
|
||||
#include "M_Instruction.h"
|
||||
|
||||
using namespace sc_core;
|
||||
using namespace sc_dt;
|
||||
|
@ -57,6 +58,7 @@ private:
|
|||
|
||||
bool process_c_instruction(Instruction &inst);
|
||||
|
||||
bool process_m_instruction(Instruction &inst);
|
||||
|
||||
void CPU_thread(void);
|
||||
};
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "memory.h"
|
||||
#include "Instruction.h"
|
||||
#include "C_Instruction.h"
|
||||
#include "M_Instruction.h"
|
||||
#include "Registers.h"
|
||||
#include "Log.h"
|
||||
|
||||
|
@ -111,6 +112,16 @@ public:
|
|||
void C_BNEZ(Instruction &inst);
|
||||
void C_LI(Instruction &inst);
|
||||
|
||||
/* M Extensinos */
|
||||
void M_MUL(Instruction &inst);
|
||||
void M_MULH(Instruction &inst);
|
||||
void M_MULHSU(Instruction &inst);
|
||||
void M_MULHU(Instruction &inst);
|
||||
void M_DIV(Instruction &inst);
|
||||
void M_DIVU(Instruction &inst);
|
||||
void M_REM(Instruction &inst);
|
||||
void M_REMU(Instruction &inst);
|
||||
|
||||
void NOP(Instruction &inst);
|
||||
|
||||
private:
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
/*!
|
||||
\file M_Instruction.h
|
||||
\brief Decode M extensions part of the RISC-V
|
||||
\author Màrius Montón
|
||||
\date November 2018
|
||||
*/
|
||||
|
||||
#ifndef M_INSTRUCTION__H
|
||||
#define M_INSTRUCTION__H
|
||||
|
||||
#include "systemc"
|
||||
|
||||
using namespace sc_core;
|
||||
using namespace sc_dt;
|
||||
using namespace std;
|
||||
|
||||
typedef enum {
|
||||
OP_M_MUL,
|
||||
OP_M_MULH,
|
||||
OP_M_MULHSU,
|
||||
OP_M_MULHU,
|
||||
OP_M_DIV,
|
||||
OP_M_DIVU,
|
||||
OP_M_REM,
|
||||
OP_M_REMU,
|
||||
|
||||
OP_M_ERROR
|
||||
} op_M_Codes;
|
||||
|
||||
|
||||
typedef enum {
|
||||
M_MUL = 0b000,
|
||||
M_MULH = 0b001,
|
||||
M_MULHSU = 0b010,
|
||||
M_MULHU = 0b011,
|
||||
M_DIV = 0b100,
|
||||
M_DIVU = 0b101,
|
||||
M_REM = 0b110,
|
||||
M_REMU = 0b111,
|
||||
} M_Codes;
|
||||
|
||||
/**
|
||||
* @brief Instruction decoding and fields access
|
||||
*/
|
||||
class M_Instruction{
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param instr Instruction to decode
|
||||
*/
|
||||
M_Instruction(sc_uint<32> instr);
|
||||
|
||||
/**
|
||||
* @brief Access to opcode field
|
||||
* @return return opcode field
|
||||
*/
|
||||
inline int32_t opcode() {
|
||||
return m_instr.range(14,12);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Access to rd field
|
||||
* @return rd field
|
||||
*/
|
||||
inline int32_t get_rd() {
|
||||
return m_instr.range(11, 7);
|
||||
}
|
||||
|
||||
inline void set_rd(int32_t value) {
|
||||
m_instr.range(11,7) = value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Access to rs1 field
|
||||
* @return rs1 field
|
||||
*/
|
||||
inline int32_t get_rs1() {
|
||||
return m_instr.range(19, 5);
|
||||
}
|
||||
|
||||
inline void set_rs1(int32_t value) {
|
||||
m_instr.range(19,15) = value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Access to rs2 field
|
||||
* @return rs2 field
|
||||
*/
|
||||
inline int32_t get_rs2() {
|
||||
return m_instr.range(24, 20);
|
||||
}
|
||||
|
||||
inline void set_rs2(int32_t value) {
|
||||
m_instr.range(24,20) = value;
|
||||
}
|
||||
|
||||
|
||||
inline int32_t get_funct3() {
|
||||
return m_instr.range(14, 12);
|
||||
}
|
||||
|
||||
inline void set_funct3(int32_t value) {
|
||||
m_instr.range(14,12) = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Decodes opcode of instruction
|
||||
* @return opcode of instruction
|
||||
*/
|
||||
op_M_Codes decode();
|
||||
|
||||
inline void dump() {
|
||||
cout << hex << "0x" << m_instr << dec << endl;
|
||||
}
|
||||
private:
|
||||
sc_uint<32> m_instr;
|
||||
};
|
||||
|
||||
#endif
|
44
src/CPU.cpp
44
src/CPU.cpp
|
@ -83,6 +83,46 @@ bool CPU::process_c_instruction(Instruction &inst) {
|
|||
return PC_not_affected;
|
||||
}
|
||||
|
||||
bool CPU::process_m_instruction(Instruction &inst) {
|
||||
bool PC_not_affected = true;
|
||||
|
||||
M_Instruction m_inst(inst.getInstr());
|
||||
|
||||
switch(m_inst.decode()) {
|
||||
case OP_M_MUL:
|
||||
exec->M_MUL(inst);
|
||||
break;
|
||||
case OP_M_MULH:
|
||||
exec->M_MULH(inst);
|
||||
break;
|
||||
case OP_M_MULHSU:
|
||||
exec->M_MULHSU(inst);
|
||||
break;
|
||||
case OP_M_MULHU:
|
||||
exec->M_MULHU(inst);
|
||||
break;
|
||||
case OP_M_DIV:
|
||||
exec->M_DIV(inst);
|
||||
break;
|
||||
case OP_M_DIVU:
|
||||
exec->M_DIV(inst);
|
||||
break;
|
||||
case OP_M_REM:
|
||||
exec->M_REM(inst);
|
||||
break;
|
||||
case OP_M_REMU:
|
||||
exec->M_REMU(inst);
|
||||
break;
|
||||
default:
|
||||
std::cout << "M instruction not implemented yet" << endl;
|
||||
inst.dump();
|
||||
exec->NOP(inst);
|
||||
break;
|
||||
}
|
||||
|
||||
return PC_not_affected;
|
||||
}
|
||||
|
||||
bool CPU::process_base_instruction(Instruction &inst) {
|
||||
bool PC_not_affected = true;
|
||||
|
||||
|
@ -304,6 +344,10 @@ void CPU::CPU_thread(void) {
|
|||
PC_not_affected = process_c_instruction(inst);
|
||||
incPCby2 = true;
|
||||
break;
|
||||
case M_EXTENSION:
|
||||
PC_not_affected = process_m_instruction(inst);
|
||||
incPCby2 = false;
|
||||
break;
|
||||
default:
|
||||
std::cout << "Extension not implemented yet" << std::endl;
|
||||
inst.dump();
|
||||
|
|
|
@ -1112,7 +1112,57 @@ void Execute::C_LI(Instruction &inst) {
|
|||
<< imm << " -> x" << rd << "(" << calc << ")" << endl;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* M Extensions */
|
||||
/******************************************************************************/
|
||||
void Execute::M_MUL(Instruction &inst) {
|
||||
int rd, rs1, rs2;
|
||||
int32_t multiplier, multiplicand;
|
||||
int64_t result;
|
||||
|
||||
M_Instruction m_inst(inst.getInstr());
|
||||
|
||||
rd = m_inst.get_rd();
|
||||
rs1 = m_inst.get_rs1();
|
||||
rs2 = m_inst.get_rs2();
|
||||
|
||||
multiplier = regs->getValue(rs1);
|
||||
multiplicand = regs->getValue(rs2);
|
||||
|
||||
result = multiplier * multiplicand;
|
||||
regs->setValue(rd, result & 0x00000000FFFFFFFF);
|
||||
|
||||
log->SC_log(Log::INFO) << dec << "MUL: x" << rs1 << " * x" << rs2
|
||||
<< " -> x" << rd << "(" << result << ")" << endl;
|
||||
}
|
||||
|
||||
void Execute::M_MULH(Instruction &inst) {
|
||||
|
||||
}
|
||||
|
||||
void Execute::M_MULHSU(Instruction &inst) {
|
||||
|
||||
}
|
||||
|
||||
void Execute::M_MULHU(Instruction &inst) {
|
||||
|
||||
}
|
||||
|
||||
void Execute::M_DIV(Instruction &inst) {
|
||||
|
||||
}
|
||||
|
||||
void Execute::M_DIVU(Instruction &inst) {
|
||||
|
||||
}
|
||||
|
||||
void Execute::M_REM(Instruction &inst) {
|
||||
|
||||
}
|
||||
|
||||
void Execute::M_REMU(Instruction &inst) {
|
||||
|
||||
}
|
||||
|
||||
void Execute::NOP(Instruction &inst) {
|
||||
cout << endl;
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
#include "M_Instruction.h"
|
||||
|
||||
|
||||
M_Instruction::M_Instruction(sc_uint<32> instr) {
|
||||
m_instr = instr;
|
||||
}
|
||||
|
||||
op_M_Codes M_Instruction::decode() {
|
||||
|
||||
switch (opcode()) {
|
||||
case M_MUL:
|
||||
return OP_M_MUL;
|
||||
break;
|
||||
case M_MULH:
|
||||
return OP_M_MULH;
|
||||
break;
|
||||
case M_MULHSU:
|
||||
return OP_M_MULHSU;
|
||||
break;
|
||||
case M_MULHU:
|
||||
return OP_M_MULHU;
|
||||
break;
|
||||
case M_DIV:
|
||||
return OP_M_DIV;
|
||||
break;
|
||||
case M_DIVU:
|
||||
return OP_M_DIVU;
|
||||
break;
|
||||
case M_REM:
|
||||
return OP_M_REM;
|
||||
break;
|
||||
case M_REMU:
|
||||
return OP_M_REMU;
|
||||
break;
|
||||
default:
|
||||
return OP_M_ERROR;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return OP_M_ERROR;
|
||||
}
|
Loading…
Reference in New Issue