Merge branch 'master' of https://github.com/mariusmm/RISC-V-TLM
This commit is contained in:
commit
9636a53624
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
#include "systemc"
|
#include "systemc"
|
||||||
|
|
||||||
#include <set>
|
#include <unordered_set>
|
||||||
|
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Registers.h"
|
#include "Registers.h"
|
||||||
|
@ -133,13 +133,13 @@ public:
|
||||||
bool Exec_A_AMOMINU();
|
bool Exec_A_AMOMINU();
|
||||||
bool Exec_A_AMOMAXU();
|
bool Exec_A_AMOMAXU();
|
||||||
|
|
||||||
bool process_instruction(Instruction &inst);
|
bool process_instruction(Instruction *inst);
|
||||||
|
|
||||||
void TLB_reserve(uint32_t address);
|
void TLB_reserve(uint32_t address);
|
||||||
bool TLB_reserved(uint32_t address);
|
bool TLB_reserved(uint32_t address);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::set<uint32_t> TLB_A_Entries;
|
std::unordered_set<uint32_t> TLB_A_Entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -411,7 +411,7 @@ public:
|
||||||
* @param inst instruction to execute
|
* @param inst instruction to execute
|
||||||
* @return true if PC is affected by instruction
|
* @return true if PC is affected by instruction
|
||||||
*/
|
*/
|
||||||
bool process_instruction(Instruction &inst);
|
bool process_instruction(Instruction *inst);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Decodes opcode of instruction
|
* @brief Decodes opcode of instruction
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*!
|
||||||
|
\file CPU.h
|
||||||
|
\brief Main CPU class
|
||||||
|
\author Màrius Montón
|
||||||
|
\date July 2020
|
||||||
|
*/
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#ifndef CPU_BASE_H
|
||||||
|
#define CPU_BASE_H
|
||||||
|
|
||||||
|
#define SC_INCLUDE_DYNAMIC_PROCESSES
|
||||||
|
|
||||||
|
#include "systemc"
|
||||||
|
|
||||||
|
#include "tlm.h"
|
||||||
|
#include "tlm_utils/simple_initiator_socket.h"
|
||||||
|
#include "tlm_utils/tlm_quantumkeeper.h"
|
||||||
|
|
||||||
|
#include "memory.h"
|
||||||
|
#include "MemoryInterface.h"
|
||||||
|
#include "BASE_ISA.h"
|
||||||
|
#include "Registers.h"
|
||||||
|
#include "Log.h"
|
||||||
|
#include "Instruction.h"
|
||||||
|
#include "C_extension.h"
|
||||||
|
#include "M_extension.h"
|
||||||
|
#include "A_extension.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ISC_V CPU 64 bitsmodel
|
||||||
|
* @param name name of the module
|
||||||
|
*/
|
||||||
|
class CPU64: sc_core::sc_module {
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Instruction Memory bus socket
|
||||||
|
* @param trans transction to perfoem
|
||||||
|
* @param delay time to annotate
|
||||||
|
*/
|
||||||
|
tlm_utils::simple_initiator_socket<CPU64> instr_bus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief IRQ line socket
|
||||||
|
* @param trans transction to perform (empty)
|
||||||
|
* @param delay time to annotate
|
||||||
|
*/
|
||||||
|
tlm_utils::simple_target_socket<CPU64> irq_line_socket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
* @param name Module name
|
||||||
|
* @param PC Program Counter initialize value
|
||||||
|
*/
|
||||||
|
CPU64(sc_core::sc_module_name name, uint32_t PC);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor
|
||||||
|
*/
|
||||||
|
~CPU64();
|
||||||
|
|
||||||
|
MemoryInterface *mem_intf;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Registers *register_bank;
|
||||||
|
Performance *perf;
|
||||||
|
Log *log;
|
||||||
|
Instruction *inst;
|
||||||
|
C_extension *c_inst;
|
||||||
|
M_extension *m_inst;
|
||||||
|
A_extension *a_inst;
|
||||||
|
BASE_ISA *exec;
|
||||||
|
|
||||||
|
tlm_utils::tlm_quantumkeeper *m_qk;
|
||||||
|
|
||||||
|
bool interrupt;
|
||||||
|
uint32_t int_cause;
|
||||||
|
bool irq_already_down;
|
||||||
|
sc_core::sc_time default_time;
|
||||||
|
bool dmi_ptr_valid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Process and triggers IRQ if all conditions met
|
||||||
|
* @return true if IRQ is triggered, false otherwise
|
||||||
|
*/
|
||||||
|
bool cpu_process_IRQ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* main thread for CPU simulation
|
||||||
|
* @brief CPU mai thread
|
||||||
|
*/
|
||||||
|
void CPU_thread(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief callback for IRQ simple socket
|
||||||
|
* @param trans transaction to perform (empty)
|
||||||
|
* @param delay time to annotate
|
||||||
|
*
|
||||||
|
* it triggers an IRQ when called
|
||||||
|
*/
|
||||||
|
void call_interrupt(tlm::tlm_generic_payload &trans,
|
||||||
|
sc_core::sc_time &delay);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DMI pointer is not longer valid
|
||||||
|
* @param start memory address region start
|
||||||
|
* @param end memory address region end
|
||||||
|
*/
|
||||||
|
void invalidate_direct_mem_ptr(sc_dt::uint64 start, sc_dt::uint64 end);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -416,7 +416,7 @@ public:
|
||||||
bool Exec_C_SW();
|
bool Exec_C_SW();
|
||||||
bool Exec_C_JAL(int m_rd);
|
bool Exec_C_JAL(int m_rd);
|
||||||
|
|
||||||
bool process_instruction(Instruction &inst);
|
bool process_instruction(Instruction *inst);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -35,7 +35,7 @@ typedef enum {
|
||||||
class Instruction {
|
class Instruction {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Instruction(sc_dt::sc_uint<32> instr);
|
Instruction(uint32_t instr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief returns what instruction extension
|
* @brief returns what instruction extension
|
||||||
|
@ -59,7 +59,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sc_dt::sc_uint<32> m_instr;
|
uint32_t m_instr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -69,7 +69,7 @@ public:
|
||||||
bool Exec_M_REM();
|
bool Exec_M_REM();
|
||||||
bool Exec_M_REMU();
|
bool Exec_M_REMU();
|
||||||
|
|
||||||
bool process_instruction(Instruction &inst);
|
bool process_instruction(Instruction *inst);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -87,13 +87,13 @@ private:
|
||||||
static Performance *instance;
|
static Performance *instance;
|
||||||
Performance();
|
Performance();
|
||||||
|
|
||||||
uint64_t data_memory_read;
|
uint_fast64_t data_memory_read;
|
||||||
uint64_t data_memory_write;
|
uint_fast64_t data_memory_write;
|
||||||
uint64_t code_memory_read;
|
uint_fast64_t code_memory_read;
|
||||||
uint64_t code_memory_write;
|
uint_fast64_t code_memory_write;
|
||||||
uint64_t register_read;
|
uint_fast64_t register_read;
|
||||||
uint64_t register_write;
|
uint_fast64_t register_write;
|
||||||
uint64_t instructions_executed;
|
uint_fast64_t instructions_executed;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#define SC_INCLUDE_DYNAMIC_PROCESSES
|
#define SC_INCLUDE_DYNAMIC_PROCESSES
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "systemc"
|
#include "systemc"
|
||||||
#include "tlm.h"
|
#include "tlm.h"
|
||||||
|
@ -244,7 +245,7 @@ private:
|
||||||
/**
|
/**
|
||||||
* bank of registers (32 regs of 32bits each)
|
* bank of registers (32 regs of 32bits each)
|
||||||
*/
|
*/
|
||||||
int32_t register_bank[32];
|
std::array<int,32> register_bank{0};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program counter (32 bits width)
|
* Program counter (32 bits width)
|
||||||
|
@ -254,7 +255,10 @@ private:
|
||||||
/**
|
/**
|
||||||
* CSR registers (4096 maximum)
|
* CSR registers (4096 maximum)
|
||||||
*/
|
*/
|
||||||
uint32_t CSR[4096];
|
//uint32_t CSR[4096];
|
||||||
|
std::unordered_map<unsigned int, uint32_t> CSR{0};
|
||||||
|
|
||||||
|
|
||||||
Performance *perf;
|
Performance *perf;
|
||||||
|
|
||||||
void initCSR(void);
|
void initCSR(void);
|
||||||
|
|
|
@ -44,7 +44,7 @@ op_A_Codes A_extension::decode() {
|
||||||
case A_AMOMAXU:
|
case A_AMOMAXU:
|
||||||
return OP_A_AMOMAXU;
|
return OP_A_AMOMAXU;
|
||||||
break;
|
break;
|
||||||
default:
|
[[unlikely]] default:
|
||||||
return OP_A_ERROR;
|
return OP_A_ERROR;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -235,6 +235,7 @@ bool A_extension::Exec_A_AMOOR() {
|
||||||
log->SC_log(Log::INFO) << std::dec << "AMOOR " << std::endl;
|
log->SC_log(Log::INFO) << std::dec << "AMOOR " << std::endl;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool A_extension::Exec_A_AMOMIN() {
|
bool A_extension::Exec_A_AMOMIN() {
|
||||||
uint32_t mem_addr = 0;
|
uint32_t mem_addr = 0;
|
||||||
int rd, rs1, rs2;
|
int rd, rs1, rs2;
|
||||||
|
@ -366,10 +367,10 @@ bool A_extension::TLB_reserved(uint32_t address) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool A_extension::process_instruction(Instruction &inst) {
|
bool A_extension::process_instruction(Instruction *inst) {
|
||||||
bool PC_not_affected = true;
|
bool PC_not_affected = true;
|
||||||
|
|
||||||
setInstr(inst.getInstr());
|
setInstr(inst->getInstr());
|
||||||
|
|
||||||
switch (decode()) {
|
switch (decode()) {
|
||||||
case OP_A_LR:
|
case OP_A_LR:
|
||||||
|
@ -405,9 +406,9 @@ bool A_extension::process_instruction(Instruction &inst) {
|
||||||
case OP_A_AMOMAXU:
|
case OP_A_AMOMAXU:
|
||||||
Exec_A_AMOMAXU();
|
Exec_A_AMOMAXU();
|
||||||
break;
|
break;
|
||||||
default:
|
[[unlikely]] default:
|
||||||
std::cout << "A instruction not implemented yet" << std::endl;
|
std::cout << "A instruction not implemented yet" << std::endl;
|
||||||
inst.dump();
|
inst->dump();
|
||||||
NOP();
|
NOP();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
140
src/BASE_ISA.cpp
140
src/BASE_ISA.cpp
|
@ -92,7 +92,7 @@ bool BASE_ISA::Exec_LUI() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "LUI x" << std::dec << rd << " <- 0x" << std::hex
|
log->SC_log(Log::INFO) << "LUI x" << std::dec << rd << " <- 0x" << std::hex
|
||||||
<< imm << std::endl;
|
<< imm << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -111,7 +111,7 @@ bool BASE_ISA::Exec_AUIPC() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "AUIPC x" << std::dec << rd << " <- 0x"
|
log->SC_log(Log::INFO) << "AUIPC x" << std::dec << rd << " <- 0x"
|
||||||
<< std::hex << imm << " + PC (0x" << new_pc << ")" << std::endl;
|
<< std::hex << imm << " + PC (0x" << new_pc << ")" << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -135,7 +135,7 @@ bool BASE_ISA::Exec_JAL() {
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "JAL: x" << std::dec << rd << " <- 0x" << std::hex
|
log->SC_log(Log::INFO) << "JAL: x" << std::dec << rd << " <- 0x" << std::hex
|
||||||
<< old_pc << std::dec << ". PC + 0x" << std::hex << mem_addr
|
<< old_pc << std::dec << ". PC + 0x" << std::hex << mem_addr
|
||||||
<< " -> PC (0x" << new_pc << ")" << std::endl;
|
<< " -> PC (0x" << new_pc << ")" << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -158,7 +158,7 @@ bool BASE_ISA::Exec_JALR() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "JALR: x" << std::dec << rd << " <- 0x"
|
log->SC_log(Log::INFO) << "JALR: x" << std::dec << rd << " <- 0x"
|
||||||
<< std::hex << old_pc + 4 << " PC <- 0x" << new_pc << std::endl;
|
<< std::hex << old_pc + 4 << " PC <- 0x" << new_pc << "\n";
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,7 @@ bool BASE_ISA::Exec_BEQ() {
|
||||||
log->SC_log(Log::INFO) << "BEQ x" << std::dec << rs1 << "(0x" << std::hex
|
log->SC_log(Log::INFO) << "BEQ x" << std::dec << rs1 << "(0x" << std::hex
|
||||||
<< regs->getValue(rs1) << ") == x" << std::dec << rs2 << "(0x"
|
<< regs->getValue(rs1) << ") == x" << std::dec << rs2 << "(0x"
|
||||||
<< std::hex << regs->getValue(rs2) << ")? -> PC (0x" << std::hex
|
<< std::hex << regs->getValue(rs2) << ")? -> PC (0x" << std::hex
|
||||||
<< new_pc << ")" << std::dec << std::endl;
|
<< new_pc << ")" << std::dec << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -211,7 +211,7 @@ bool BASE_ISA::Exec_BNE() {
|
||||||
log->SC_log(Log::INFO) << "BNE: x" << std::dec << rs1 << "(0x" << std::hex
|
log->SC_log(Log::INFO) << "BNE: x" << std::dec << rs1 << "(0x" << std::hex
|
||||||
<< val1 << ") == x" << std::dec << rs2 << "(0x" << std::hex << val2
|
<< val1 << ") == x" << std::dec << rs2 << "(0x" << std::hex << val2
|
||||||
<< ")? -> PC (0x" << std::hex << new_pc << ")" << std::dec
|
<< ")? -> PC (0x" << std::hex << new_pc << ")" << std::dec
|
||||||
<< std::endl;
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -236,7 +236,7 @@ bool BASE_ISA::Exec_BLT() {
|
||||||
<< (int32_t) regs->getValue(rs1) << ") < x" << std::dec << rs2
|
<< (int32_t) regs->getValue(rs1) << ") < x" << std::dec << rs2
|
||||||
<< "(0x" << std::hex << (int32_t) regs->getValue(rs2)
|
<< "(0x" << std::hex << (int32_t) regs->getValue(rs2)
|
||||||
<< ")? -> PC (0x" << std::hex << new_pc << ")" << std::dec
|
<< ")? -> PC (0x" << std::hex << new_pc << ")" << std::dec
|
||||||
<< std::endl;
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -261,7 +261,7 @@ bool BASE_ISA::Exec_BGE() {
|
||||||
<< (int32_t) regs->getValue(rs1) << ") > x" << std::dec << rs2
|
<< (int32_t) regs->getValue(rs1) << ") > x" << std::dec << rs2
|
||||||
<< "(0x" << std::hex << (int32_t) regs->getValue(rs2)
|
<< "(0x" << std::hex << (int32_t) regs->getValue(rs2)
|
||||||
<< ")? -> PC (0x" << std::hex << new_pc << ")" << std::dec
|
<< ")? -> PC (0x" << std::hex << new_pc << ")" << std::dec
|
||||||
<< std::endl;
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -286,7 +286,7 @@ bool BASE_ISA::Exec_BLTU() {
|
||||||
log->SC_log(Log::INFO) << "BLTU x" << std::dec << rs1 << "(0x" << std::hex
|
log->SC_log(Log::INFO) << "BLTU x" << std::dec << rs1 << "(0x" << std::hex
|
||||||
<< regs->getValue(rs1) << ") < x" << std::dec << rs2 << "(0x"
|
<< regs->getValue(rs1) << ") < x" << std::dec << rs2 << "(0x"
|
||||||
<< std::hex << regs->getValue(rs2) << ")? -> PC (0x" << std::hex
|
<< std::hex << regs->getValue(rs2) << ")? -> PC (0x" << std::hex
|
||||||
<< new_pc << ")" << std::dec << std::endl;
|
<< new_pc << ")" << std::dec << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -310,7 +310,7 @@ bool BASE_ISA::Exec_BGEU() {
|
||||||
log->SC_log(Log::INFO) << "BGEU x" << std::dec << rs1 << "(0x" << std::hex
|
log->SC_log(Log::INFO) << "BGEU x" << std::dec << rs1 << "(0x" << std::hex
|
||||||
<< regs->getValue(rs1) << ") > x" << std::dec << rs2 << "(0x"
|
<< regs->getValue(rs1) << ") > x" << std::dec << rs2 << "(0x"
|
||||||
<< std::hex << regs->getValue(rs2) << ")? -> PC (0x" << std::hex
|
<< std::hex << regs->getValue(rs2) << ")? -> PC (0x" << std::hex
|
||||||
<< new_pc << ")" << std::dec << std::endl;
|
<< new_pc << ")" << std::dec << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -332,7 +332,7 @@ bool BASE_ISA::Exec_LB() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "LB: x" << rs1 << " + " << imm << " (@0x"
|
log->SC_log(Log::INFO) << "LB: x" << rs1 << " + " << imm << " (@0x"
|
||||||
<< std::hex << mem_addr << std::dec << ") -> x" << rd << std::endl;
|
<< std::hex << mem_addr << std::dec << ") -> x" << rd << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -354,7 +354,7 @@ bool BASE_ISA::Exec_LH() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "LH: x" << rs1 << " + " << imm << " (@0x"
|
log->SC_log(Log::INFO) << "LH: x" << rs1 << " + " << imm << " (@0x"
|
||||||
<< std::hex << mem_addr << std::dec << ") -> x" << rd << std::endl;
|
<< std::hex << mem_addr << std::dec << ") -> x" << rd << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -378,7 +378,7 @@ bool BASE_ISA::Exec_LW() {
|
||||||
log->SC_log(Log::INFO) << std::dec << "LW: x" << rs1 << "(0x" << std::hex
|
log->SC_log(Log::INFO) << std::dec << "LW: x" << rs1 << "(0x" << std::hex
|
||||||
<< regs->getValue(rs1) << ") + " << std::dec << imm << " (@0x"
|
<< regs->getValue(rs1) << ") + " << std::dec << imm << " (@0x"
|
||||||
<< std::hex << mem_addr << std::dec << ") -> x" << rd << std::hex
|
<< std::hex << mem_addr << std::dec << ") -> x" << rd << std::hex
|
||||||
<< " (0x" << data << ")" << std::endl;
|
<< " (0x" << data << ")" << "\n";
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -399,7 +399,7 @@ bool BASE_ISA::Exec_LBU() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "LBU: x" << rs1 << " + " << imm << " (@0x"
|
log->SC_log(Log::INFO) << "LBU: x" << rs1 << " + " << imm << " (@0x"
|
||||||
<< std::hex << mem_addr << std::dec << ") -> x" << rd << std::endl;
|
<< std::hex << mem_addr << std::dec << ") -> x" << rd << "\n";
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -421,7 +421,7 @@ bool BASE_ISA::Exec_LHU() {
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "LHU: x" << std::dec << rs1 << " + " << imm
|
log->SC_log(Log::INFO) << "LHU: x" << std::dec << rs1 << " + " << imm
|
||||||
<< " (@0x" << std::hex << mem_addr << std::dec << ") -> x" << rd
|
<< " (@0x" << std::hex << mem_addr << std::dec << ") -> x" << rd
|
||||||
<< "(0x" << std::hex << data << ")" << std::endl;
|
<< "(0x" << std::hex << data << ")" << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -445,7 +445,7 @@ bool BASE_ISA::Exec_SB() {
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "SB: x" << std::dec << rs2 << " -> x" << rs1
|
log->SC_log(Log::INFO) << "SB: x" << std::dec << rs2 << " -> x" << rs1
|
||||||
<< " + 0x" << std::hex << imm << " (@0x" << std::hex << mem_addr
|
<< " + 0x" << std::hex << imm << " (@0x" << std::hex << mem_addr
|
||||||
<< std::dec << ")" << std::endl;
|
<< std::dec << ")" << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -469,7 +469,7 @@ bool BASE_ISA::Exec_SH() {
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "SH: x" << std::dec << rs2 << " -> x" << rs1
|
log->SC_log(Log::INFO) << "SH: x" << std::dec << rs2 << " -> x" << rs1
|
||||||
<< " + 0x" << std::hex << imm << " (@0x" << std::hex << mem_addr
|
<< " + 0x" << std::hex << imm << " (@0x" << std::hex << mem_addr
|
||||||
<< std::dec << ")" << std::endl;
|
<< std::dec << ")" << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -493,7 +493,7 @@ bool BASE_ISA::Exec_SW() {
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "SW: x" << std::dec << rs2 << "(0x" << std::hex
|
log->SC_log(Log::INFO) << "SW: x" << std::dec << rs2 << "(0x" << std::hex
|
||||||
<< data << ") -> x" << std::dec << rs1 << " + 0x" << std::hex << imm
|
<< data << ") -> x" << std::dec << rs1 << " + 0x" << std::hex << imm
|
||||||
<< " (@0x" << std::hex << mem_addr << std::dec << ")" << std::endl;
|
<< " (@0x" << std::hex << mem_addr << std::dec << ")" << "\n";
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -513,7 +513,7 @@ bool BASE_ISA::Exec_ADDI() {
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "ADDI: x" << std::dec << rs1 << " + " << imm
|
log->SC_log(Log::INFO) << "ADDI: x" << std::dec << rs1 << " + " << imm
|
||||||
<< " -> x" << std::dec << rd << "(0x" << std::hex << calc << ")"
|
<< " -> x" << std::dec << rd << "(0x" << std::hex << calc << ")"
|
||||||
<< std::endl;
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -530,11 +530,11 @@ bool BASE_ISA::Exec_SLTI() {
|
||||||
if (regs->getValue(rs1) < imm) {
|
if (regs->getValue(rs1) < imm) {
|
||||||
regs->setValue(rd, 1);
|
regs->setValue(rd, 1);
|
||||||
log->SC_log(Log::INFO) << "SLTI: x" << rs1 << " < " << imm << " => "
|
log->SC_log(Log::INFO) << "SLTI: x" << rs1 << " < " << imm << " => "
|
||||||
<< "1 -> x" << rd << std::endl;
|
<< "1 -> x" << rd << "\n";
|
||||||
} else {
|
} else {
|
||||||
regs->setValue(rd, 0);
|
regs->setValue(rd, 0);
|
||||||
log->SC_log(Log::INFO) << "SLTI: x" << rs1 << " < " << imm << " => "
|
log->SC_log(Log::INFO) << "SLTI: x" << rs1 << " < " << imm << " => "
|
||||||
<< "0 -> x" << rd << std::endl;
|
<< "0 -> x" << rd << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -551,11 +551,11 @@ bool BASE_ISA::Exec_SLTIU() {
|
||||||
if ((uint32_t) regs->getValue(rs1) < (uint32_t) imm) {
|
if ((uint32_t) regs->getValue(rs1) < (uint32_t) imm) {
|
||||||
regs->setValue(rd, 1);
|
regs->setValue(rd, 1);
|
||||||
log->SC_log(Log::INFO) << "SLTIU: x" << rs1 << " < " << imm << " => "
|
log->SC_log(Log::INFO) << "SLTIU: x" << rs1 << " < " << imm << " => "
|
||||||
<< "1 -> x" << rd << std::endl;
|
<< "1 -> x" << rd << "\n";
|
||||||
} else {
|
} else {
|
||||||
regs->setValue(rd, 0);
|
regs->setValue(rd, 0);
|
||||||
log->SC_log(Log::INFO) << "SLTIU: x" << rs1 << " < " << imm << " => "
|
log->SC_log(Log::INFO) << "SLTIU: x" << rs1 << " < " << imm << " => "
|
||||||
<< "0 -> x" << rd << std::endl;
|
<< "0 -> x" << rd << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -575,7 +575,7 @@ bool BASE_ISA::Exec_XORI() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "XORI: x" << rs1 << " XOR " << imm << "-> x" << rd
|
log->SC_log(Log::INFO) << "XORI: x" << rs1 << " XOR " << imm << "-> x" << rd
|
||||||
<< std::endl;
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -595,7 +595,7 @@ bool BASE_ISA::Exec_ORI() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "ORI: x" << rs1 << " OR " << imm << "-> x" << rd
|
log->SC_log(Log::INFO) << "ORI: x" << rs1 << " OR " << imm << "-> x" << rd
|
||||||
<< std::endl;
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -618,7 +618,7 @@ bool BASE_ISA::Exec_ANDI() {
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "ANDI: x" << rs1 << "(0x" << std::hex << aux
|
log->SC_log(Log::INFO) << "ANDI: x" << rs1 << "(0x" << std::hex << aux
|
||||||
<< ") AND 0x" << imm << " -> x" << std::dec << rd << "(0x"
|
<< ") AND 0x" << imm << " -> x" << std::dec << rd << "(0x"
|
||||||
<< std::hex << calc << ")" << std::endl;
|
<< std::hex << calc << ")" << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -634,7 +634,7 @@ bool BASE_ISA::Exec_SLLI() {
|
||||||
rs2 = get_shamt();
|
rs2 = get_shamt();
|
||||||
|
|
||||||
if (rs2 >= 0x20) {
|
if (rs2 >= 0x20) {
|
||||||
std::cout << "ILEGAL INSTRUCTION, shamt[5] != 0" << std::endl;
|
std::cout << "ILEGAL INSTRUCTION, shamt[5] != 0" << "\n";
|
||||||
RaiseException(EXCEPTION_CAUSE_ILLEGAL_INSTRUCTION, m_instr);
|
RaiseException(EXCEPTION_CAUSE_ILLEGAL_INSTRUCTION, m_instr);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -647,7 +647,7 @@ bool BASE_ISA::Exec_SLLI() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "SLLI: x" << std::dec << rs1 << " << " << shift
|
log->SC_log(Log::INFO) << "SLLI: x" << std::dec << rs1 << " << " << shift
|
||||||
<< " -> x" << rd << "(0x" << std::hex << calc << ")" << std::endl;
|
<< " -> x" << rd << "(0x" << std::hex << calc << ")" << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -669,7 +669,7 @@ bool BASE_ISA::Exec_SRLI() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "SRLI: x" << std::dec << rs1 << " >> " << shift
|
log->SC_log(Log::INFO) << "SRLI: x" << std::dec << rs1 << " >> " << shift
|
||||||
<< " -> x" << rd << std::endl;
|
<< " -> x" << rd << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -691,7 +691,7 @@ bool BASE_ISA::Exec_SRAI() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "SRAI: x" << std::dec << rs1 << " >> " << shift
|
log->SC_log(Log::INFO) << "SRAI: x" << std::dec << rs1 << " >> " << shift
|
||||||
<< " -> x" << rd << std::endl;
|
<< " -> x" << rd << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -710,7 +710,7 @@ bool BASE_ISA::Exec_ADD() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "ADD: x" << std::dec << rs1 << " + x" << rs2
|
log->SC_log(Log::INFO) << "ADD: x" << std::dec << rs1 << " + x" << rs2
|
||||||
<< " -> x" << rd << std::hex << "(0x" << calc << ")" << std::endl;
|
<< " -> x" << rd << std::hex << "(0x" << calc << ")" << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -728,7 +728,7 @@ bool BASE_ISA::Exec_SUB() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "SUB: x" << rs1 << " - x" << rs2 << " -> x" << rd
|
log->SC_log(Log::INFO) << "SUB: x" << rs1 << " - x" << rs2 << " -> x" << rd
|
||||||
<< "(" << calc << ")" << std::endl;
|
<< "(" << calc << ")" << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -750,7 +750,7 @@ bool BASE_ISA::Exec_SLL() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "SLL: x" << rs1 << " << " << shift << " -> x"
|
log->SC_log(Log::INFO) << "SLL: x" << rs1 << " << " << shift << " -> x"
|
||||||
<< rd << std::endl;
|
<< rd << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -766,11 +766,11 @@ bool BASE_ISA::Exec_SLT() {
|
||||||
if (regs->getValue(rs1) < regs->getValue(rs2)) {
|
if (regs->getValue(rs1) < regs->getValue(rs2)) {
|
||||||
regs->setValue(rd, 1);
|
regs->setValue(rd, 1);
|
||||||
log->SC_log(Log::INFO) << "SLT: x" << rs1 << " < x" << rs2 << " => "
|
log->SC_log(Log::INFO) << "SLT: x" << rs1 << " < x" << rs2 << " => "
|
||||||
<< "1 -> x" << rd << std::endl;
|
<< "1 -> x" << rd << "\n";
|
||||||
} else {
|
} else {
|
||||||
regs->setValue(rd, 0);
|
regs->setValue(rd, 0);
|
||||||
log->SC_log(Log::INFO) << "SLT: x" << rs1 << " < x" << rs2 << " => "
|
log->SC_log(Log::INFO) << "SLT: x" << rs1 << " < x" << rs2 << " => "
|
||||||
<< "0 -> x" << rd << std::endl;
|
<< "0 -> x" << rd << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -786,11 +786,11 @@ bool BASE_ISA::Exec_SLTU() {
|
||||||
if ((uint32_t) regs->getValue(rs1) < (uint32_t) regs->getValue(rs2)) {
|
if ((uint32_t) regs->getValue(rs1) < (uint32_t) regs->getValue(rs2)) {
|
||||||
regs->setValue(rd, 1);
|
regs->setValue(rd, 1);
|
||||||
log->SC_log(Log::INFO) << "SLTU: x" << rs1 << " < x" << rs2 << " => "
|
log->SC_log(Log::INFO) << "SLTU: x" << rs1 << " < x" << rs2 << " => "
|
||||||
<< "1 -> x" << rd << std::endl;
|
<< "1 -> x" << rd << "\n";
|
||||||
} else {
|
} else {
|
||||||
regs->setValue(rd, 0);
|
regs->setValue(rd, 0);
|
||||||
log->SC_log(Log::INFO) << "SLTU: x" << rs1 << " < x" << rs2 << " => "
|
log->SC_log(Log::INFO) << "SLTU: x" << rs1 << " < x" << rs2 << " => "
|
||||||
<< "0 -> x" << rd << std::endl;
|
<< "0 -> x" << rd << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -809,7 +809,7 @@ bool BASE_ISA::Exec_XOR() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "XOR: x" << rs1 << " XOR x" << rs2 << "-> x" << rd
|
log->SC_log(Log::INFO) << "XOR: x" << rs1 << " XOR x" << rs2 << "-> x" << rd
|
||||||
<< std::endl;
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -831,7 +831,7 @@ bool BASE_ISA::Exec_SRL() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "SRL: x" << rs1 << " >> " << shift << " -> x"
|
log->SC_log(Log::INFO) << "SRL: x" << rs1 << " >> " << shift << " -> x"
|
||||||
<< rd << std::endl;
|
<< rd << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -853,7 +853,7 @@ bool BASE_ISA::Exec_SRA() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "SRA: x" << rs1 << " >> " << shift << " -> x"
|
log->SC_log(Log::INFO) << "SRA: x" << rs1 << " >> " << shift << " -> x"
|
||||||
<< rd << std::endl;
|
<< rd << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -872,7 +872,7 @@ bool BASE_ISA::Exec_OR() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "OR: x" << rs1 << " OR x" << rs2 << "-> x" << rd
|
log->SC_log(Log::INFO) << "OR: x" << rs1 << " OR x" << rs2 << "-> x" << rd
|
||||||
<< std::endl;
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -891,32 +891,32 @@ bool BASE_ISA::Exec_AND() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "AND: x" << rs1 << " AND x" << rs2 << "-> x" << rd
|
log->SC_log(Log::INFO) << "AND: x" << rs1 << " AND x" << rs2 << "-> x" << rd
|
||||||
<< std::endl;
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BASE_ISA::Exec_FENCE() {
|
bool BASE_ISA::Exec_FENCE() {
|
||||||
log->SC_log(Log::INFO) << "FENCE" << std::endl;
|
log->SC_log(Log::INFO) << "FENCE" << "\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BASE_ISA::Exec_ECALL() {
|
bool BASE_ISA::Exec_ECALL() {
|
||||||
|
|
||||||
log->SC_log(Log::INFO) << "ECALL" << std::endl;
|
log->SC_log(Log::INFO) << "ECALL" << "\n";
|
||||||
std::cout << std::endl << "ECALL Instruction called, stopping simulation"
|
std::cout << "\n" << "ECALL Instruction called, stopping simulation"
|
||||||
<< std::endl;
|
<< "\n";
|
||||||
regs->dump();
|
regs->dump();
|
||||||
std::cout << "Simulation time " << sc_core::sc_time_stamp() << std::endl;
|
std::cout << "Simulation time " << sc_core::sc_time_stamp() << "\n";
|
||||||
perf->dump();
|
perf->dump();
|
||||||
|
|
||||||
uint32_t gp_value = regs->getValue(Registers::gp);
|
uint32_t gp_value = regs->getValue(Registers::gp);
|
||||||
if (gp_value == 1) {
|
if (gp_value == 1) {
|
||||||
std::cout << "GP value is 1, test result is OK" << std::endl;
|
std::cout << "GP value is 1, test result is OK" << "\n";
|
||||||
} else {
|
} else {
|
||||||
std::cout << "GP value is " << gp_value << std::endl;
|
std::cout << "GP value is " << gp_value << "\n";
|
||||||
}
|
}
|
||||||
//SC_REPORT_ERROR("Execute", "ECALL");
|
//SC_REPORT_ERROR("Execute", "ECALL");
|
||||||
sc_core::sc_stop();
|
sc_core::sc_stop();
|
||||||
|
@ -925,11 +925,11 @@ bool BASE_ISA::Exec_ECALL() {
|
||||||
|
|
||||||
bool BASE_ISA::Exec_EBREAK() {
|
bool BASE_ISA::Exec_EBREAK() {
|
||||||
|
|
||||||
log->SC_log(Log::INFO) << "EBREAK" << std::endl;
|
log->SC_log(Log::INFO) << "EBREAK" << "\n";
|
||||||
std::cout << std::endl << "EBRAK Instruction called, dumping information"
|
std::cout << "\n" << "EBRAK Instruction called, dumping information"
|
||||||
<< std::endl;
|
<< "\n";
|
||||||
regs->dump();
|
regs->dump();
|
||||||
std::cout << "Simulation time " << sc_core::sc_time_stamp() << std::endl;
|
std::cout << "Simulation time " << sc_core::sc_time_stamp() << "\n";
|
||||||
perf->dump();
|
perf->dump();
|
||||||
|
|
||||||
RaiseException(EXCEPTION_CAUSE_BREAKPOINT, m_instr);
|
RaiseException(EXCEPTION_CAUSE_BREAKPOINT, m_instr);
|
||||||
|
@ -957,7 +957,7 @@ bool BASE_ISA::Exec_CSRRW() {
|
||||||
|
|
||||||
log->SC_log(Log::INFO) << std::hex << "CSRRW: CSR #" << csr << " -> x"
|
log->SC_log(Log::INFO) << std::hex << "CSRRW: CSR #" << csr << " -> x"
|
||||||
<< std::dec << rd << ". x" << rs1 << "-> CSR #" << std::hex << csr
|
<< std::dec << rd << ". x" << rs1 << "-> CSR #" << std::hex << csr
|
||||||
<< " (0x" << aux << ")" << std::endl;
|
<< " (0x" << aux << ")" << "\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -973,7 +973,7 @@ bool BASE_ISA::Exec_CSRRS() {
|
||||||
|
|
||||||
if (rd == 0) {
|
if (rd == 0) {
|
||||||
log->SC_log(Log::INFO) << "CSRRS with rd1 == 0, doing nothing."
|
log->SC_log(Log::INFO) << "CSRRS with rd1 == 0, doing nothing."
|
||||||
<< std::endl;
|
<< "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -988,7 +988,7 @@ bool BASE_ISA::Exec_CSRRS() {
|
||||||
|
|
||||||
log->SC_log(Log::INFO) << "CSRRS: CSR #" << csr << "(0x" << std::hex << aux
|
log->SC_log(Log::INFO) << "CSRRS: CSR #" << csr << "(0x" << std::hex << aux
|
||||||
<< ") -> x" << std::dec << rd << ". x" << rs1 << " & CSR #" << csr
|
<< ") -> x" << std::dec << rd << ". x" << rs1 << " & CSR #" << csr
|
||||||
<< " <- 0x" << std::hex << aux2 << std::endl;
|
<< " <- 0x" << std::hex << aux2 << "\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1004,7 +1004,7 @@ bool BASE_ISA::Exec_CSRRC() {
|
||||||
|
|
||||||
if (rd == 0) {
|
if (rd == 0) {
|
||||||
log->SC_log(Log::INFO) << "CSRRC with rd1 == 0, doing nothing."
|
log->SC_log(Log::INFO) << "CSRRC with rd1 == 0, doing nothing."
|
||||||
<< std::endl;
|
<< "\n";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1019,7 +1019,7 @@ bool BASE_ISA::Exec_CSRRC() {
|
||||||
|
|
||||||
log->SC_log(Log::INFO) << "CSRRC: CSR #" << csr << "(0x" << std::hex << aux
|
log->SC_log(Log::INFO) << "CSRRC: CSR #" << csr << "(0x" << std::hex << aux
|
||||||
<< ") -> x" << std::dec << rd << ". x" << rs1 << " & CSR #" << csr
|
<< ") -> x" << std::dec << rd << ". x" << rs1 << " & CSR #" << csr
|
||||||
<< " <- 0x" << std::hex << aux2 << std::endl;
|
<< " <- 0x" << std::hex << aux2 << "\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1042,7 +1042,7 @@ bool BASE_ISA::Exec_CSRRWI() {
|
||||||
regs->setCSR(csr, aux);
|
regs->setCSR(csr, aux);
|
||||||
|
|
||||||
log->SC_log(Log::INFO) << "CSRRWI: CSR #" << csr << " -> x" << rd << ". x"
|
log->SC_log(Log::INFO) << "CSRRWI: CSR #" << csr << " -> x" << rd << ". x"
|
||||||
<< rs1 << "-> CSR #" << csr << std::endl;
|
<< rs1 << "-> CSR #" << csr << "\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1070,7 +1070,7 @@ bool BASE_ISA::Exec_CSRRSI() {
|
||||||
|
|
||||||
log->SC_log(Log::INFO) << "CSRRSI: CSR #" << csr << " -> x" << rd << ". x"
|
log->SC_log(Log::INFO) << "CSRRSI: CSR #" << csr << " -> x" << rd << ". x"
|
||||||
<< rs1 << " & CSR #" << csr << "(0x" << std::hex << aux << ")"
|
<< rs1 << " & CSR #" << csr << "(0x" << std::hex << aux << ")"
|
||||||
<< std::endl;
|
<< "\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1098,7 +1098,7 @@ bool BASE_ISA::Exec_CSRRCI() {
|
||||||
|
|
||||||
log->SC_log(Log::INFO) << "CSRRCI: CSR #" << csr << " -> x" << rd << ". x"
|
log->SC_log(Log::INFO) << "CSRRCI: CSR #" << csr << " -> x" << rd << ". x"
|
||||||
<< rs1 << " & CSR #" << csr << "(0x" << std::hex << aux << ")"
|
<< rs1 << " & CSR #" << csr << "(0x" << std::hex << aux << ")"
|
||||||
<< std::endl;
|
<< "\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1112,7 +1112,7 @@ bool BASE_ISA::Exec_MRET() {
|
||||||
regs->setPC(new_pc);
|
regs->setPC(new_pc);
|
||||||
|
|
||||||
log->SC_log(Log::INFO) << "MRET: PC <- 0x" << std::hex << new_pc
|
log->SC_log(Log::INFO) << "MRET: PC <- 0x" << std::hex << new_pc
|
||||||
<< std::endl;
|
<< "\n";
|
||||||
|
|
||||||
// update mstatus
|
// update mstatus
|
||||||
uint32_t csr_temp;
|
uint32_t csr_temp;
|
||||||
|
@ -1133,27 +1133,27 @@ bool BASE_ISA::Exec_SRET() {
|
||||||
regs->setPC(new_pc);
|
regs->setPC(new_pc);
|
||||||
|
|
||||||
log->SC_log(Log::INFO) << "SRET: PC <- 0x" << std::hex << new_pc
|
log->SC_log(Log::INFO) << "SRET: PC <- 0x" << std::hex << new_pc
|
||||||
<< std::endl;
|
<< "\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BASE_ISA::Exec_WFI() {
|
bool BASE_ISA::Exec_WFI() {
|
||||||
log->SC_log(Log::INFO) << "WFI" << std::endl;
|
log->SC_log(Log::INFO) << "WFI" << "\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BASE_ISA::Exec_SFENCE() {
|
bool BASE_ISA::Exec_SFENCE() {
|
||||||
log->SC_log(Log::INFO) << "SFENCE" << std::endl;
|
log->SC_log(Log::INFO) << "SFENCE" << "\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BASE_ISA::process_instruction(Instruction &inst) {
|
bool BASE_ISA::process_instruction(Instruction *inst) {
|
||||||
bool PC_not_affected = true;
|
bool PC_not_affected = true;
|
||||||
|
|
||||||
setInstr(inst.getInstr());
|
setInstr(inst->getInstr());
|
||||||
|
|
||||||
switch (decode()) {
|
switch (decode()) {
|
||||||
case OP_LUI:
|
case OP_LUI:
|
||||||
|
@ -1316,9 +1316,9 @@ bool BASE_ISA::process_instruction(Instruction &inst) {
|
||||||
case OP_SFENCE:
|
case OP_SFENCE:
|
||||||
Exec_SFENCE();
|
Exec_SFENCE();
|
||||||
break;
|
break;
|
||||||
default:
|
[[unlikely]] default:
|
||||||
std::cout << "Wrong instruction" << std::endl;
|
std::cout << "Wrong instruction" << "\n";
|
||||||
inst.dump();
|
inst->dump();
|
||||||
NOP();
|
NOP();
|
||||||
//sc_stop();
|
//sc_stop();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -24,7 +24,7 @@ BusCtrl::BusCtrl(sc_core::sc_module_name name) :
|
||||||
|
|
||||||
void BusCtrl::b_transport(tlm::tlm_generic_payload &trans,
|
void BusCtrl::b_transport(tlm::tlm_generic_payload &trans,
|
||||||
sc_core::sc_time &delay) {
|
sc_core::sc_time &delay) {
|
||||||
//tlm::tlm_command cmd = trans.get_command();
|
|
||||||
sc_dt::uint64 adr = trans.get_address() / 4;
|
sc_dt::uint64 adr = trans.get_address() / 4;
|
||||||
|
|
||||||
switch (adr) {
|
switch (adr) {
|
||||||
|
@ -37,7 +37,7 @@ void BusCtrl::b_transport(tlm::tlm_generic_payload &trans,
|
||||||
case TRACE_MEMORY_ADDRESS / 4:
|
case TRACE_MEMORY_ADDRESS / 4:
|
||||||
trace_socket->b_transport(trans, delay);
|
trace_socket->b_transport(trans, delay);
|
||||||
break;
|
break;
|
||||||
default:
|
[[likely]] default:
|
||||||
memory_socket->b_transport(trans, delay);
|
memory_socket->b_transport(trans, delay);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
16
src/CPU.cpp
16
src/CPU.cpp
|
@ -162,23 +162,23 @@ void CPU::CPU_thread(void) {
|
||||||
|
|
||||||
/* check what type of instruction is and execute it */
|
/* check what type of instruction is and execute it */
|
||||||
switch (inst->check_extension()) {
|
switch (inst->check_extension()) {
|
||||||
case BASE_EXTENSION:
|
[[likely]] case BASE_EXTENSION:
|
||||||
PC_not_affected = exec->process_instruction(*inst);
|
PC_not_affected = exec->process_instruction(inst);
|
||||||
incPCby2 = false;
|
incPCby2 = false;
|
||||||
break;
|
break;
|
||||||
case C_EXTENSION:
|
case C_EXTENSION:
|
||||||
PC_not_affected = c_inst->process_instruction(*inst);
|
PC_not_affected = c_inst->process_instruction(inst);
|
||||||
incPCby2 = true;
|
incPCby2 = true;
|
||||||
break;
|
break;
|
||||||
case M_EXTENSION:
|
case M_EXTENSION:
|
||||||
PC_not_affected = m_inst->process_instruction(*inst);
|
PC_not_affected = m_inst->process_instruction(inst);
|
||||||
incPCby2 = false;
|
incPCby2 = false;
|
||||||
break;
|
break;
|
||||||
case A_EXTENSION:
|
case A_EXTENSION:
|
||||||
PC_not_affected = a_inst->process_instruction(*inst);
|
PC_not_affected = a_inst->process_instruction(inst);
|
||||||
incPCby2 = false;
|
incPCby2 = false;
|
||||||
break;
|
break;
|
||||||
default:
|
[[unlikely]] default:
|
||||||
std::cout << "Extension not implemented yet" << std::endl;
|
std::cout << "Extension not implemented yet" << std::endl;
|
||||||
inst->dump();
|
inst->dump();
|
||||||
exec->NOP();
|
exec->NOP();
|
||||||
|
@ -202,10 +202,8 @@ void CPU::CPU_thread(void) {
|
||||||
m_qk->sync();
|
m_qk->sync();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
sc_core::wait(10, sc_core::SC_NS);
|
//sc_core::wait(10, sc_core::SC_NS);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // while(1)
|
} // while(1)
|
||||||
} // CPU_thread
|
} // CPU_thread
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,221 @@
|
||||||
|
/*!
|
||||||
|
\file CPU.cpp
|
||||||
|
\brief Main CPU class
|
||||||
|
\author Màrius Montón
|
||||||
|
\date August 2018
|
||||||
|
*/
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include "CPU64.h"
|
||||||
|
|
||||||
|
SC_HAS_PROCESS(CPU64);
|
||||||
|
CPU64::CPU64(sc_core::sc_module_name name, uint32_t PC) :
|
||||||
|
sc_module(name), instr_bus("instr_bus"), default_time(10,
|
||||||
|
sc_core::SC_NS) {
|
||||||
|
register_bank = new Registers();
|
||||||
|
mem_intf = new MemoryInterface();
|
||||||
|
|
||||||
|
perf = Performance::getInstance();
|
||||||
|
log = Log::getInstance();
|
||||||
|
|
||||||
|
register_bank->setPC(PC);
|
||||||
|
|
||||||
|
//register_bank->setValue(Registers::sp, (0xD0000 / 4) - 1);
|
||||||
|
register_bank->setValue(Registers::sp, (0x10000000 / 4) - 1);
|
||||||
|
|
||||||
|
irq_line_socket.register_b_transport(this, &CPU64::call_interrupt);
|
||||||
|
interrupt = false;
|
||||||
|
|
||||||
|
int_cause = 0;
|
||||||
|
irq_already_down = false;
|
||||||
|
|
||||||
|
dmi_ptr_valid = false;
|
||||||
|
instr_bus.register_invalidate_direct_mem_ptr(this,
|
||||||
|
&CPU64::invalidate_direct_mem_ptr);
|
||||||
|
|
||||||
|
inst = new Instruction(0);
|
||||||
|
exec = new BASE_ISA(0, register_bank, mem_intf);
|
||||||
|
c_inst = new C_extension(0, register_bank, mem_intf);
|
||||||
|
m_inst = new M_extension(0, register_bank, mem_intf);
|
||||||
|
a_inst = new A_extension(0, register_bank, mem_intf);
|
||||||
|
|
||||||
|
m_qk = new tlm_utils::tlm_quantumkeeper();
|
||||||
|
|
||||||
|
SC_THREAD(CPU_thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
CPU64::~CPU64() {
|
||||||
|
std::cout << "*********************************************" << std::endl;
|
||||||
|
register_bank->dump();
|
||||||
|
std::cout << "end time: " << sc_core::sc_time_stamp() << std::endl;
|
||||||
|
perf->dump();
|
||||||
|
std::cout << "*********************************************" << std::endl;
|
||||||
|
delete register_bank;
|
||||||
|
delete mem_intf;
|
||||||
|
delete inst;
|
||||||
|
delete exec;
|
||||||
|
delete c_inst;
|
||||||
|
delete m_inst;
|
||||||
|
delete a_inst;
|
||||||
|
delete m_qk;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPU64::cpu_process_IRQ() {
|
||||||
|
uint32_t csr_temp;
|
||||||
|
uint32_t new_pc, old_pc;
|
||||||
|
bool ret_value = false;
|
||||||
|
|
||||||
|
if (interrupt == true) {
|
||||||
|
csr_temp = register_bank->getCSR(CSR_MSTATUS);
|
||||||
|
if ((csr_temp & MSTATUS_MIE) == 0) {
|
||||||
|
log->SC_log(Log::DEBUG) << "interrupt delayed" << std::endl;
|
||||||
|
return ret_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
csr_temp = register_bank->getCSR(CSR_MIP);
|
||||||
|
|
||||||
|
if ((csr_temp & MIP_MEIP) == 0) {
|
||||||
|
csr_temp |= MIP_MEIP; // MEIP bit in MIP register (11th bit)
|
||||||
|
register_bank->setCSR(CSR_MIP, csr_temp);
|
||||||
|
log->SC_log(Log::DEBUG) << "Interrupt!" << std::endl;
|
||||||
|
|
||||||
|
/* updated MEPC register */
|
||||||
|
old_pc = register_bank->getPC();
|
||||||
|
register_bank->setCSR(CSR_MEPC, old_pc);
|
||||||
|
log->SC_log(Log::INFO) << "Old PC Value 0x" << std::hex << old_pc
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
/* update MCAUSE register */
|
||||||
|
register_bank->setCSR(CSR_MCAUSE, 0x80000000);
|
||||||
|
|
||||||
|
/* set new PC address */
|
||||||
|
new_pc = register_bank->getCSR(CSR_MTVEC);
|
||||||
|
//new_pc = new_pc & 0xFFFFFFFC; // last two bits always to 0
|
||||||
|
log->SC_log(Log::DEBUG) << "NEW PC Value 0x" << std::hex << new_pc
|
||||||
|
<< std::endl;
|
||||||
|
register_bank->setPC(new_pc);
|
||||||
|
|
||||||
|
ret_value = true;
|
||||||
|
interrupt = false;
|
||||||
|
irq_already_down = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (irq_already_down == false) {
|
||||||
|
csr_temp = register_bank->getCSR(CSR_MIP);
|
||||||
|
csr_temp &= ~MIP_MEIP;
|
||||||
|
register_bank->setCSR(CSR_MIP, csr_temp);
|
||||||
|
irq_already_down = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPU64::CPU_thread(void) {
|
||||||
|
|
||||||
|
tlm::tlm_generic_payload *trans = new tlm::tlm_generic_payload;
|
||||||
|
uint32_t INSTR;
|
||||||
|
sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
|
||||||
|
bool PC_not_affected = false;
|
||||||
|
bool incPCby2 = false;
|
||||||
|
tlm::tlm_dmi dmi_data;
|
||||||
|
unsigned char *dmi_ptr = NULL;
|
||||||
|
|
||||||
|
trans->set_command(tlm::TLM_READ_COMMAND);
|
||||||
|
trans->set_data_ptr(reinterpret_cast<unsigned char*>(&INSTR));
|
||||||
|
trans->set_data_length(4);
|
||||||
|
trans->set_streaming_width(4); // = data_length to indicate no streaming
|
||||||
|
trans->set_byte_enable_ptr(0); // 0 indicates unused
|
||||||
|
trans->set_dmi_allowed(false); // Mandatory initial value
|
||||||
|
trans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
|
||||||
|
|
||||||
|
m_qk->reset();
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
/* Get new PC value */
|
||||||
|
if (dmi_ptr_valid == true) {
|
||||||
|
/* if memory_offset at Memory module is set, this won't work */
|
||||||
|
memcpy(&INSTR, dmi_ptr + register_bank->getPC(), 4);
|
||||||
|
} else {
|
||||||
|
trans->set_address(register_bank->getPC());
|
||||||
|
instr_bus->b_transport(*trans, delay);
|
||||||
|
|
||||||
|
if (trans->is_response_error()) {
|
||||||
|
SC_REPORT_ERROR("CPU base", "Read memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trans->is_dmi_allowed()) {
|
||||||
|
dmi_ptr_valid = instr_bus->get_direct_mem_ptr(*trans, dmi_data);
|
||||||
|
if (dmi_ptr_valid) {
|
||||||
|
std::cout << "Get DMI_PTR " << std::endl;
|
||||||
|
dmi_ptr = dmi_data.get_dmi_ptr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
perf->codeMemoryRead();
|
||||||
|
|
||||||
|
log->SC_log(Log::INFO) << "PC: 0x" << std::hex << register_bank->getPC()
|
||||||
|
<< ". ";
|
||||||
|
|
||||||
|
inst->setInstr(INSTR);
|
||||||
|
|
||||||
|
/* check what type of instruction is and execute it */
|
||||||
|
switch (inst->check_extension()) {
|
||||||
|
[[likely]] case BASE_EXTENSION:
|
||||||
|
PC_not_affected = exec->process_instruction(inst);
|
||||||
|
incPCby2 = false;
|
||||||
|
break;
|
||||||
|
case C_EXTENSION:
|
||||||
|
PC_not_affected = c_inst->process_instruction(inst);
|
||||||
|
incPCby2 = true;
|
||||||
|
break;
|
||||||
|
case M_EXTENSION:
|
||||||
|
PC_not_affected = m_inst->process_instruction(inst);
|
||||||
|
incPCby2 = false;
|
||||||
|
break;
|
||||||
|
case A_EXTENSION:
|
||||||
|
PC_not_affected = a_inst->process_instruction(inst);
|
||||||
|
incPCby2 = false;
|
||||||
|
break;
|
||||||
|
[[unlikely]] default:
|
||||||
|
std::cout << "Extension not implemented yet" << std::endl;
|
||||||
|
inst->dump();
|
||||||
|
exec->NOP();
|
||||||
|
}
|
||||||
|
|
||||||
|
perf->instructionsInc();
|
||||||
|
|
||||||
|
if (PC_not_affected == true) {
|
||||||
|
register_bank->incPC(incPCby2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process IRQ (if any) */
|
||||||
|
cpu_process_IRQ();
|
||||||
|
|
||||||
|
/* Fixed instruction time to 10 ns (i.e. 100 MHz) */
|
||||||
|
//#define USE_QK
|
||||||
|
#ifdef USE_QK
|
||||||
|
// Model time used for additional processing
|
||||||
|
m_qk->inc(default_time);
|
||||||
|
if (m_qk->need_sync()) {
|
||||||
|
m_qk->sync();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
sc_core::wait(10, sc_core::SC_NS);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // while(1)
|
||||||
|
} // CPU_thread
|
||||||
|
|
||||||
|
void CPU64::call_interrupt(tlm::tlm_generic_payload &trans,
|
||||||
|
sc_core::sc_time &delay) {
|
||||||
|
interrupt = true;
|
||||||
|
/* Socket caller send a cause (its id) */
|
||||||
|
memcpy(&int_cause, trans.get_data_ptr(), sizeof(uint32_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPU64::invalidate_direct_mem_ptr(sc_dt::uint64 start, sc_dt::uint64 end) {
|
||||||
|
dmi_ptr_valid = false;
|
||||||
|
}
|
|
@ -33,7 +33,7 @@ op_C_Codes C_extension::decode() {
|
||||||
case C_FSW:
|
case C_FSW:
|
||||||
return OP_C_FSW;
|
return OP_C_FSW;
|
||||||
break;
|
break;
|
||||||
default:
|
[[unlikely]] default:
|
||||||
return OP_C_ERROR;
|
return OP_C_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ op_C_Codes C_extension::decode() {
|
||||||
case C_BNEZ:
|
case C_BNEZ:
|
||||||
return OP_C_BNEZ;
|
return OP_C_BNEZ;
|
||||||
break;
|
break;
|
||||||
default:
|
[[unlikely]] default:
|
||||||
return OP_C_ERROR;
|
return OP_C_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -131,13 +131,13 @@ op_C_Codes C_extension::decode() {
|
||||||
return OP_C_SWSP;
|
return OP_C_SWSP;
|
||||||
break;
|
break;
|
||||||
case C_FWWSP:
|
case C_FWWSP:
|
||||||
default:
|
[[unlikely]] default:
|
||||||
return OP_C_ERROR;
|
return OP_C_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
[[unlikely]] default:
|
||||||
return OP_C_ERROR;
|
return OP_C_ERROR;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ bool C_extension::Exec_C_JR() {
|
||||||
regs->setPC(new_pc);
|
regs->setPC(new_pc);
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "JR: PC <- 0x" << std::hex << new_pc << std::endl;
|
log->SC_log(Log::INFO) << "JR: PC <- 0x" << std::hex << new_pc << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -179,7 +179,7 @@ bool C_extension::Exec_C_MV() {
|
||||||
log->SC_log(Log::INFO) << "C.MV: x" << std::dec << rs1 << "(0x" << std::hex
|
log->SC_log(Log::INFO) << "C.MV: x" << std::dec << rs1 << "(0x" << std::hex
|
||||||
<< regs->getValue(rs1) << ") + x" << std::dec << rs2 << "(0x"
|
<< regs->getValue(rs1) << ") + x" << std::dec << rs2 << "(0x"
|
||||||
<< std::hex << regs->getValue(rs2) << ") -> x" << std::dec << rd
|
<< std::hex << regs->getValue(rs2) << ") -> x" << std::dec << rd
|
||||||
<< "(0x" << std::hex << calc << ")" << std::endl;
|
<< "(0x" << std::hex << calc << ")" << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -198,7 +198,7 @@ bool C_extension::Exec_C_ADD() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "C.ADD: x" << std::dec << rs1 << " + x" << rs2
|
log->SC_log(Log::INFO) << "C.ADD: x" << std::dec << rs1 << " + x" << rs2
|
||||||
<< " -> x" << rd << "(0x" << std::hex << calc << ")" << std::endl;
|
<< " -> x" << rd << "(0x" << std::hex << calc << ")" << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -224,7 +224,7 @@ bool C_extension::Exec_C_LWSP() {
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "C.LWSP: x" << std::dec << rs1 << " + " << imm
|
log->SC_log(Log::INFO) << "C.LWSP: x" << std::dec << rs1 << " + " << imm
|
||||||
<< " (@0x" << std::hex << mem_addr << std::dec << ") -> x" << rd
|
<< " (@0x" << std::hex << mem_addr << std::dec << ") -> x" << rd
|
||||||
<< "(" << std::hex << data << ")" << std::dec << std::endl;
|
<< "(" << std::hex << data << ")" << std::dec << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -250,7 +250,7 @@ bool C_extension::Exec_C_ADDI4SPN() {
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << std::dec << "C.ADDI4SPN: x" << rs1 << "(0x"
|
log->SC_log(Log::INFO) << std::dec << "C.ADDI4SPN: x" << rs1 << "(0x"
|
||||||
<< std::hex << regs->getValue(rs1) << ") + " << std::dec << imm
|
<< std::hex << regs->getValue(rs1) << ") + " << std::dec << imm
|
||||||
<< " -> x" << rd << "(0x" << std::hex << calc << ")" << std::endl;
|
<< " -> x" << rd << "(0x" << std::hex << calc << ")" << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -272,14 +272,14 @@ bool C_extension::Exec_C_ADDI16SP() {
|
||||||
|
|
||||||
log->SC_log(Log::INFO) << std::dec << "C.ADDI16SP: x" << rs1 << " + "
|
log->SC_log(Log::INFO) << std::dec << "C.ADDI16SP: x" << rs1 << " + "
|
||||||
<< std::dec << imm << " -> x" << rd << "(0x" << std::hex << calc
|
<< std::dec << imm << " -> x" << rd << "(0x" << std::hex << calc
|
||||||
<< ")" << std::endl;
|
<< ")" << "\n";
|
||||||
} else {
|
} else {
|
||||||
/* C.LUI OPCODE */
|
/* C.LUI OPCODE */
|
||||||
rd = get_rd();
|
rd = get_rd();
|
||||||
imm = get_imm_LUI();
|
imm = get_imm_LUI();
|
||||||
regs->setValue(rd, imm);
|
regs->setValue(rd, imm);
|
||||||
log->SC_log(Log::INFO) << std::dec << "C.LUI x" << rd << " <- 0x"
|
log->SC_log(Log::INFO) << std::dec << "C.LUI x" << rd << " <- 0x"
|
||||||
<< std::hex << imm << std::endl;
|
<< std::hex << imm << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -304,7 +304,7 @@ bool C_extension::Exec_C_SWSP() {
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << std::dec << "C.SWSP: x" << rs2 << "(0x"
|
log->SC_log(Log::INFO) << std::dec << "C.SWSP: x" << rs2 << "(0x"
|
||||||
<< std::hex << data << ") -> x" << std::dec << rs1 << " + " << imm
|
<< std::hex << data << ") -> x" << std::dec << rs1 << " + " << imm
|
||||||
<< " (@0x" << std::hex << mem_addr << std::dec << ")" << std::endl;
|
<< " (@0x" << std::hex << mem_addr << std::dec << ")" << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -329,7 +329,7 @@ bool C_extension::Exec_C_BEQZ() {
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "C.BEQZ: x" << std::dec << rs1 << "(" << val1
|
log->SC_log(Log::INFO) << "C.BEQZ: x" << std::dec << rs1 << "(" << val1
|
||||||
<< ") == 0? -> PC (0x" << std::hex << new_pc << ")" << std::dec
|
<< ") == 0? -> PC (0x" << std::hex << new_pc << ")" << std::dec
|
||||||
<< std::endl;
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -354,7 +354,7 @@ bool C_extension::Exec_C_BNEZ() {
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "C.BNEZ: x" << std::dec << rs1 << "(0x"
|
log->SC_log(Log::INFO) << "C.BNEZ: x" << std::dec << rs1 << "(0x"
|
||||||
<< std::hex << val1 << ") != 0? -> PC (0x" << std::hex << new_pc
|
<< std::hex << val1 << ") != 0? -> PC (0x" << std::hex << new_pc
|
||||||
<< ")" << std::dec << std::endl;
|
<< ")" << std::dec << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -375,7 +375,7 @@ bool C_extension::Exec_C_LI() {
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << std::dec << "C.LI: x" << rs1 << "("
|
log->SC_log(Log::INFO) << std::dec << "C.LI: x" << rs1 << "("
|
||||||
<< regs->getValue(rs1) << ") + " << imm << " -> x" << rd << "("
|
<< regs->getValue(rs1) << ") + " << imm << " -> x" << rd << "("
|
||||||
<< calc << ")" << std::endl;
|
<< calc << ")" << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -397,7 +397,7 @@ bool C_extension::Exec_C_SRLI() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "C.SRLI: x" << rs1 << " >> " << shift << " -> x"
|
log->SC_log(Log::INFO) << "C.SRLI: x" << rs1 << " >> " << shift << " -> x"
|
||||||
<< rd << std::endl;
|
<< rd << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -419,7 +419,7 @@ bool C_extension::Exec_C_SRAI() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "C.SRAI: x" << rs1 << " >> " << std::dec << shift
|
log->SC_log(Log::INFO) << "C.SRAI: x" << rs1 << " >> " << std::dec << shift
|
||||||
<< " -> x" << rd << "(" << calc << ")" << std::endl;
|
<< " -> x" << rd << "(" << calc << ")" << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -441,7 +441,7 @@ bool C_extension::Exec_C_SLLI() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "C.SLLI: x" << std::dec << rs1 << " << " << shift
|
log->SC_log(Log::INFO) << "C.SLLI: x" << std::dec << rs1 << " << " << shift
|
||||||
<< " -> x" << rd << "(0x" << calc << ")" << std::endl;
|
<< " -> x" << rd << "(0x" << calc << ")" << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -463,7 +463,7 @@ bool C_extension::Exec_C_ANDI() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "C.ANDI: x" << rs1 << "(" << aux << ") AND "
|
log->SC_log(Log::INFO) << "C.ANDI: x" << rs1 << "(" << aux << ") AND "
|
||||||
<< imm << " -> x" << rd << std::endl;
|
<< imm << " -> x" << rd << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -482,7 +482,7 @@ bool C_extension::Exec_C_SUB() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "C.SUB: x" << std::dec << rs1 << " - x" << rs2
|
log->SC_log(Log::INFO) << "C.SUB: x" << std::dec << rs1 << " - x" << rs2
|
||||||
<< " -> x" << rd << std::endl;
|
<< " -> x" << rd << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -501,7 +501,7 @@ bool C_extension::Exec_C_XOR() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "C.XOR: x" << std::dec << rs1 << " XOR x" << rs2
|
log->SC_log(Log::INFO) << "C.XOR: x" << std::dec << rs1 << " XOR x" << rs2
|
||||||
<< "-> x" << rd << std::endl;
|
<< "-> x" << rd << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -520,7 +520,7 @@ bool C_extension::Exec_C_OR() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "C_OR: x" << std::dec << rs1 << " OR x" << rs2
|
log->SC_log(Log::INFO) << "C_OR: x" << std::dec << rs1 << " OR x" << rs2
|
||||||
<< "-> x" << rd << std::endl;
|
<< "-> x" << rd << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -539,7 +539,7 @@ bool C_extension::Exec_C_AND() {
|
||||||
|
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "C.AND: x" << std::dec << rs1 << " AND x" << rs2
|
log->SC_log(Log::INFO) << "C.AND: x" << std::dec << rs1 << " AND x" << rs2
|
||||||
<< "-> x" << rd << std::endl;
|
<< "-> x" << rd << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -560,7 +560,7 @@ bool C_extension::Exec_C_ADDI() {
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "C.ADDI: x" << std::dec << rs1 << " + " << imm
|
log->SC_log(Log::INFO) << "C.ADDI: x" << std::dec << rs1 << " + " << imm
|
||||||
<< " -> x" << std::dec << rd << "(0x" << std::hex << calc << ")"
|
<< " -> x" << std::dec << rd << "(0x" << std::hex << calc << ")"
|
||||||
<< std::endl;
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -583,7 +583,7 @@ bool C_extension::Exec_C_JALR() {
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "C.JALR: x" << std::dec << rd << " <- 0x"
|
log->SC_log(Log::INFO) << "C.JALR: x" << std::dec << rd << " <- 0x"
|
||||||
<< std::hex << old_pc + 4 << " PC <- 0x" << std::hex << new_pc
|
<< std::hex << old_pc + 4 << " PC <- 0x" << std::hex << new_pc
|
||||||
<< std::endl;
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -607,7 +607,7 @@ bool C_extension::Exec_C_LW() {
|
||||||
log->SC_log(Log::INFO) << std::dec << "C.LW: x" << rs1 << "(0x" << std::hex
|
log->SC_log(Log::INFO) << std::dec << "C.LW: x" << rs1 << "(0x" << std::hex
|
||||||
<< regs->getValue(rs1) << ") + " << std::dec << imm << " (@0x"
|
<< regs->getValue(rs1) << ") + " << std::dec << imm << " (@0x"
|
||||||
<< std::hex << mem_addr << std::dec << ") -> x" << rd << std::hex
|
<< std::hex << mem_addr << std::dec << ") -> x" << rd << std::hex
|
||||||
<< " (0x" << data << ")" << std::endl;
|
<< " (0x" << data << ")" << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -631,7 +631,7 @@ bool C_extension::Exec_C_SW() {
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "C.SW: x" << std::dec << rs2 << "(0x" << std::hex
|
log->SC_log(Log::INFO) << "C.SW: x" << std::dec << rs2 << "(0x" << std::hex
|
||||||
<< data << ") -> x" << std::dec << rs1 << " + 0x" << std::hex << imm
|
<< data << ") -> x" << std::dec << rs1 << " + 0x" << std::hex << imm
|
||||||
<< " (@0x" << std::hex << mem_addr << std::dec << ")" << std::endl;
|
<< " (@0x" << std::hex << mem_addr << std::dec << ")" << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -655,16 +655,16 @@ bool C_extension::Exec_C_JAL(int m_rd) {
|
||||||
if (log->getLogLevel() >= Log::INFO) {
|
if (log->getLogLevel() >= Log::INFO) {
|
||||||
log->SC_log(Log::INFO) << "C.JAL: x" << std::dec << rd << " <- 0x"
|
log->SC_log(Log::INFO) << "C.JAL: x" << std::dec << rd << " <- 0x"
|
||||||
<< std::hex << old_pc << std::dec << ". PC + 0x" << std::hex
|
<< std::hex << old_pc << std::dec << ". PC + 0x" << std::hex
|
||||||
<< mem_addr << " -> PC (0x" << new_pc << ")" << std::endl;
|
<< mem_addr << " -> PC (0x" << new_pc << ")" << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool C_extension::process_instruction(Instruction &inst) {
|
bool C_extension::process_instruction(Instruction *inst) {
|
||||||
bool PC_not_affected = true;
|
bool PC_not_affected = true;
|
||||||
|
|
||||||
setInstr(inst.getInstr());
|
setInstr(inst->getInstr());
|
||||||
|
|
||||||
switch (decode()) {
|
switch (decode()) {
|
||||||
case OP_C_ADDI4SPN:
|
case OP_C_ADDI4SPN:
|
||||||
|
@ -745,9 +745,9 @@ bool C_extension::process_instruction(Instruction &inst) {
|
||||||
case OP_C_AND:
|
case OP_C_AND:
|
||||||
Exec_C_AND();
|
Exec_C_AND();
|
||||||
break;
|
break;
|
||||||
default:
|
[[unlikely]] default:
|
||||||
std::cout << "C instruction not implemented yet" << std::endl;
|
std::cout << "C instruction not implemented yet" << "\n";
|
||||||
inst.dump();
|
inst->dump();
|
||||||
NOP();
|
NOP();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,26 +8,29 @@
|
||||||
|
|
||||||
#include "Instruction.h"
|
#include "Instruction.h"
|
||||||
|
|
||||||
Instruction::Instruction(sc_dt::sc_uint<32> instr) {
|
Instruction::Instruction(uint32_t instr) {
|
||||||
m_instr = instr;
|
m_instr = instr;
|
||||||
}
|
}
|
||||||
|
|
||||||
extension_t Instruction::check_extension() {
|
extension_t Instruction::check_extension() {
|
||||||
if ((m_instr.range(6, 0) == 0b0110011)
|
if (((m_instr & 0x0000007F) == 0b0110011)
|
||||||
&& (m_instr.range(31, 25) == 0b0000001)) {
|
&& ( ((m_instr & 0x7F000000) >> 25) == 0b0000001)) {
|
||||||
return M_EXTENSION;
|
return M_EXTENSION;
|
||||||
} else if (m_instr.range(6, 0) == 0b0101111) {
|
} else if ((m_instr & 0x0000007F) == 0b0101111) {
|
||||||
return A_EXTENSION;
|
return A_EXTENSION;
|
||||||
} else if (m_instr.range(1, 0) == 0b11) {
|
} else if ((m_instr & 0x00000003) == 0b11) {
|
||||||
return BASE_EXTENSION;
|
return BASE_EXTENSION;
|
||||||
} else if (m_instr.range(1, 0) == 0b00) {
|
} else if ((m_instr & 0x00000003) == 0b00) {
|
||||||
return C_EXTENSION;
|
return C_EXTENSION;
|
||||||
} else if (m_instr.range(1, 0) == 0b01) {
|
} else if ((m_instr & 0x00000003) == 0b01) {
|
||||||
return C_EXTENSION;
|
return C_EXTENSION;
|
||||||
} else if (m_instr.range(1, 0) == 0b10) {
|
} else if ((m_instr & 0x00000003) == 0b10) {
|
||||||
return C_EXTENSION;
|
return C_EXTENSION;
|
||||||
} else {
|
} else {
|
||||||
|
std::cout << "Unknown\n";
|
||||||
return UNKNOWN_EXTENSION;
|
return UNKNOWN_EXTENSION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ void Log::SC_log(std::string msg, enum LogLevel level) {
|
||||||
|
|
||||||
if (level <= currentLogLevel) {
|
if (level <= currentLogLevel) {
|
||||||
m_stream << "time " << sc_core::sc_time_stamp() << ": " << msg
|
m_stream << "time " << sc_core::sc_time_stamp() << ": " << msg
|
||||||
<< std::endl;
|
<< "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ std::ofstream& Log::SC_log(enum LogLevel level) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Log::setLogLevel(enum LogLevel newLevel) {
|
void Log::setLogLevel(enum LogLevel newLevel) {
|
||||||
std::cout << "LogLevel set to " << newLevel << std::endl;
|
std::cout << "LogLevel set to " << newLevel << "\n";
|
||||||
currentLogLevel = newLevel;
|
currentLogLevel = newLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ op_M_Codes M_extension::decode() {
|
||||||
case M_REMU:
|
case M_REMU:
|
||||||
return OP_M_REMU;
|
return OP_M_REMU;
|
||||||
break;
|
break;
|
||||||
default:
|
[[unlikely]] default:
|
||||||
return OP_M_ERROR;
|
return OP_M_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ bool M_extension::Exec_M_MUL() {
|
||||||
regs->setValue(rd, result);
|
regs->setValue(rd, result);
|
||||||
|
|
||||||
log->SC_log(Log::INFO) << std::dec << "MUL: x" << rs1 << " * x" << rs2
|
log->SC_log(Log::INFO) << std::dec << "MUL: x" << rs1 << " * x" << rs2
|
||||||
<< " -> x" << rd << "(" << result << ")" << std::endl;
|
<< " -> x" << rd << "(" << result << ")" << "\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ bool M_extension::Exec_M_MULH() {
|
||||||
regs->setValue(rd, ret_value);
|
regs->setValue(rd, ret_value);
|
||||||
|
|
||||||
log->SC_log(Log::INFO) << std::dec << "MULH: x" << rs1 << " * x" << rs2
|
log->SC_log(Log::INFO) << std::dec << "MULH: x" << rs1 << " * x" << rs2
|
||||||
<< " -> x" << rd << "(" << result << ")" << std::endl;
|
<< " -> x" << rd << "(" << result << ")" << "\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ bool M_extension::Exec_M_MULHSU() {
|
||||||
regs->setValue(rd, result);
|
regs->setValue(rd, result);
|
||||||
|
|
||||||
log->SC_log(Log::INFO) << std::dec << "MULHSU: x" << rs1 << " * x" << rs2
|
log->SC_log(Log::INFO) << std::dec << "MULHSU: x" << rs1 << " * x" << rs2
|
||||||
<< " -> x" << rd << "(" << result << ")" << std::endl;
|
<< " -> x" << rd << "(" << result << ")" << "\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ bool M_extension::Exec_M_MULHU() {
|
||||||
regs->setValue(rd, ret_value);
|
regs->setValue(rd, ret_value);
|
||||||
|
|
||||||
log->SC_log(Log::INFO) << std::dec << "MULHU: x" << rs1 << " * x" << rs2
|
log->SC_log(Log::INFO) << std::dec << "MULHU: x" << rs1 << " * x" << rs2
|
||||||
<< " -> x" << rd << "(" << ret_value << ")" << std::endl;
|
<< " -> x" << rd << "(" << ret_value << ")" << "\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,7 @@ bool M_extension::Exec_M_DIV() {
|
||||||
regs->setValue(rd, result);
|
regs->setValue(rd, result);
|
||||||
|
|
||||||
log->SC_log(Log::INFO) << std::dec << "DIV: x" << rs1 << " / x" << rs2
|
log->SC_log(Log::INFO) << std::dec << "DIV: x" << rs1 << " / x" << rs2
|
||||||
<< " -> x" << rd << "(" << result << ")" << std::endl;
|
<< " -> x" << rd << "(" << result << ")" << "\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -186,7 +186,7 @@ bool M_extension::Exec_M_DIVU() {
|
||||||
regs->setValue(rd, result);
|
regs->setValue(rd, result);
|
||||||
|
|
||||||
log->SC_log(Log::INFO) << std::dec << "DIVU: x" << rs1 << " / x" << rs2
|
log->SC_log(Log::INFO) << std::dec << "DIVU: x" << rs1 << " / x" << rs2
|
||||||
<< " -> x" << rd << "(" << result << ")" << std::endl;
|
<< " -> x" << rd << "(" << result << ")" << "\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ bool M_extension::Exec_M_REM() {
|
||||||
regs->setValue(rd, result);
|
regs->setValue(rd, result);
|
||||||
|
|
||||||
log->SC_log(Log::INFO) << std::dec << "REM: x" << rs1 << " / x" << rs2
|
log->SC_log(Log::INFO) << std::dec << "REM: x" << rs1 << " / x" << rs2
|
||||||
<< " -> x" << rd << "(" << result << ")" << std::endl;
|
<< " -> x" << rd << "(" << result << ")" << "\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -240,15 +240,15 @@ bool M_extension::Exec_M_REMU() {
|
||||||
regs->setValue(rd, result);
|
regs->setValue(rd, result);
|
||||||
|
|
||||||
log->SC_log(Log::INFO) << std::dec << "REMU: x" << rs1 << " / x" << rs2
|
log->SC_log(Log::INFO) << std::dec << "REMU: x" << rs1 << " / x" << rs2
|
||||||
<< " -> x" << rd << "(" << result << ")" << std::endl;
|
<< " -> x" << rd << "(" << result << ")" << "\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool M_extension::process_instruction(Instruction &inst) {
|
bool M_extension::process_instruction(Instruction *inst) {
|
||||||
bool PC_not_affected = true;
|
bool PC_not_affected = true;
|
||||||
|
|
||||||
setInstr(inst.getInstr());
|
setInstr(inst->getInstr());
|
||||||
|
|
||||||
switch (decode()) {
|
switch (decode()) {
|
||||||
case OP_M_MUL:
|
case OP_M_MUL:
|
||||||
|
@ -275,9 +275,9 @@ bool M_extension::process_instruction(Instruction &inst) {
|
||||||
case OP_M_REMU:
|
case OP_M_REMU:
|
||||||
Exec_M_REMU();
|
Exec_M_REMU();
|
||||||
break;
|
break;
|
||||||
default:
|
[[unlikely]] default:
|
||||||
std::cout << "M instruction not implemented yet" << std::endl;
|
std::cout << "M instruction not implemented yet" << "\n";
|
||||||
inst.dump();
|
inst->dump();
|
||||||
//NOP(inst);
|
//NOP(inst);
|
||||||
sc_core::sc_stop();
|
sc_core::sc_stop();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -58,6 +58,7 @@ void Memory::b_transport(tlm::tlm_generic_payload &trans,
|
||||||
unsigned int wid = trans.get_streaming_width();
|
unsigned int wid = trans.get_streaming_width();
|
||||||
|
|
||||||
adr = adr - memory_offset;
|
adr = adr - memory_offset;
|
||||||
|
|
||||||
// Obliged to check address range and check for unsupported features,
|
// Obliged to check address range and check for unsupported features,
|
||||||
// i.e. byte enables, streaming, and bursts
|
// i.e. byte enables, streaming, and bursts
|
||||||
// Can ignore extensions
|
// Can ignore extensions
|
||||||
|
@ -65,7 +66,6 @@ void Memory::b_transport(tlm::tlm_generic_payload &trans,
|
||||||
// *********************************************
|
// *********************************************
|
||||||
// Generate the appropriate error response
|
// Generate the appropriate error response
|
||||||
// *********************************************
|
// *********************************************
|
||||||
|
|
||||||
if (adr >= sc_dt::uint64(SIZE)) {
|
if (adr >= sc_dt::uint64(SIZE)) {
|
||||||
trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE);
|
trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE);
|
||||||
return;
|
return;
|
||||||
|
@ -79,6 +79,7 @@ void Memory::b_transport(tlm::tlm_generic_payload &trans,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Obliged to implement read and write commands
|
// Obliged to implement read and write commands
|
||||||
if (cmd == tlm::TLM_READ_COMMAND)
|
if (cmd == tlm::TLM_READ_COMMAND)
|
||||||
memcpy(ptr, &mem[adr], len);
|
memcpy(ptr, &mem[adr], len);
|
||||||
|
@ -86,7 +87,7 @@ void Memory::b_transport(tlm::tlm_generic_payload &trans,
|
||||||
memcpy(&mem[adr], ptr, len);
|
memcpy(&mem[adr], ptr, len);
|
||||||
|
|
||||||
// Illustrates that b_transport may block
|
// Illustrates that b_transport may block
|
||||||
wait(delay);
|
//sc_core::wait(delay);
|
||||||
|
|
||||||
// Reset timing annotation after waiting
|
// Reset timing annotation after waiting
|
||||||
delay = sc_core::SC_ZERO_TIME;
|
delay = sc_core::SC_ZERO_TIME;
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
|
|
||||||
Registers::Registers() {
|
Registers::Registers() {
|
||||||
|
|
||||||
memset(register_bank, 0, sizeof(uint32_t) * 32); // 32 registers of 32 bits each
|
|
||||||
memset(CSR, 0, sizeof(uint32_t) * 4096);
|
|
||||||
perf = Performance::getInstance();
|
perf = Performance::getInstance();
|
||||||
|
|
||||||
initCSR();
|
initCSR();
|
||||||
|
@ -156,7 +154,7 @@ uint32_t Registers::getCSR(int csr) {
|
||||||
- sc_core::sc_time(sc_core::SC_ZERO_TIME)).to_double())
|
- sc_core::sc_time(sc_core::SC_ZERO_TIME)).to_double())
|
||||||
>> 32 & 0x00000000FFFFFFFF);
|
>> 32 & 0x00000000FFFFFFFF);
|
||||||
break;
|
break;
|
||||||
default:
|
[[likely]] default:
|
||||||
ret_value = CSR[csr];
|
ret_value = CSR[csr];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -165,7 +163,7 @@ uint32_t Registers::getCSR(int csr) {
|
||||||
|
|
||||||
void Registers::setCSR(int csr, uint32_t value) {
|
void Registers::setCSR(int csr, uint32_t value) {
|
||||||
/* @FIXME: rv32mi-p-ma_fetch tests doesn't allow MISA to writable,
|
/* @FIXME: rv32mi-p-ma_fetch tests doesn't allow MISA to writable,
|
||||||
* but Volume II: Privileged Architectura v1.10 says MISRA is writable (?)
|
* but Volume II: Privileged Architecture v1.10 says MISA is writable (?)
|
||||||
*/
|
*/
|
||||||
if (csr != CSR_MISA) {
|
if (csr != CSR_MISA) {
|
||||||
CSR[csr] = value;
|
CSR[csr] = value;
|
||||||
|
@ -176,5 +174,4 @@ void Registers::initCSR() {
|
||||||
CSR[CSR_MISA] = MISA_MXL | MISA_M_EXTENSION | MISA_C_EXTENSION
|
CSR[CSR_MISA] = MISA_MXL | MISA_M_EXTENSION | MISA_C_EXTENSION
|
||||||
| MISA_A_EXTENSION | MISA_I_BASE;
|
| MISA_A_EXTENSION | MISA_I_BASE;
|
||||||
CSR[CSR_MSTATUS] = MISA_MXL;
|
CSR[CSR_MSTATUS] = MISA_MXL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ CFLAGS = -Wall -I. -O0 -nostdlib -march=rv32i -mabi=ilp32 --entry main
|
||||||
#CFLAGS = -Wall -I. -O0 -nodefaultlibs -march=rv32i -mabi=ilp32
|
#CFLAGS = -Wall -I. -O0 -nodefaultlibs -march=rv32i -mabi=ilp32
|
||||||
|
|
||||||
|
|
||||||
LINKER = riscv32-unknown-linux-gnu-gcc
|
|
||||||
# linking flags here
|
# linking flags here
|
||||||
LFLAGS = -I. --entry main
|
LFLAGS = -I. --entry main
|
||||||
LIBS = $(EXTRA_LIBS)
|
LIBS = $(EXTRA_LIBS)
|
||||||
|
|
|
@ -7,7 +7,6 @@ CC = riscv32-unknown-elf-gcc
|
||||||
CFLAGS = -Wall -L. -O0 -g -static
|
CFLAGS = -Wall -L. -O0 -g -static
|
||||||
|
|
||||||
|
|
||||||
LINKER = riscv32-unknown-linux-gnu-gcc
|
|
||||||
# linking flags here
|
# linking flags here
|
||||||
LFLAGS = -I. --entry main
|
LFLAGS = -I. --entry main
|
||||||
LIBS = $(EXTRA_LIBS)
|
LIBS = $(EXTRA_LIBS)
|
||||||
|
|
|
@ -6,8 +6,6 @@ CC = riscv32-unknown-elf-gcc
|
||||||
# compiling flags here
|
# compiling flags here
|
||||||
CFLAGS = -Wall -I. -O0 -march=rv32i -mabi=ilp32
|
CFLAGS = -Wall -I. -O0 -march=rv32i -mabi=ilp32
|
||||||
|
|
||||||
|
|
||||||
LINKER = riscv32-unknown-linux-gnu-gcc
|
|
||||||
# linking flags here
|
# linking flags here
|
||||||
LFLAGS = -I. --entry main
|
LFLAGS = -I. --entry main
|
||||||
LIBS = $(EXTRA_LIBS)
|
LIBS = $(EXTRA_LIBS)
|
||||||
|
@ -28,8 +26,7 @@ rm = rm -f
|
||||||
|
|
||||||
|
|
||||||
$(BINDIR)/$(TARGET): $(OBJECTS)
|
$(BINDIR)/$(TARGET): $(OBJECTS)
|
||||||
# $(LINKER) $(OBJECTS) $(LFLAGS) $(LIBS) $(LIBDIR) -o $@
|
riscv32-unknown-elf-objdump -d $< > dump
|
||||||
riscv32-unknown-linux-gnu-objdump -d $< > dump
|
|
||||||
objcopy -Oihex $< $(TARGET).hex
|
objcopy -Oihex $< $(TARGET).hex
|
||||||
# @echo "Linking complete!"
|
# @echo "Linking complete!"
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ CC = riscv32-unknown-elf-gcc
|
||||||
# compiling flags here
|
# compiling flags here
|
||||||
CFLAGS = -Wall -I. -O0 -static -march=rv32imac -mabi=ilp32 --specs=nosys.specs
|
CFLAGS = -Wall -I. -O0 -static -march=rv32imac -mabi=ilp32 --specs=nosys.specs
|
||||||
|
|
||||||
LINKER = riscv32-unknown-linux-gnu-gcc
|
|
||||||
LIBS = $(EXTRA_LIBS)
|
LIBS = $(EXTRA_LIBS)
|
||||||
|
|
||||||
# change these to proper directories where each file should be
|
# change these to proper directories where each file should be
|
||||||
|
@ -24,7 +23,7 @@ rm = rm -f
|
||||||
|
|
||||||
$(BINDIR)/$(TARGET): $(OBJECTS)
|
$(BINDIR)/$(TARGET): $(OBJECTS)
|
||||||
# $(LINKER) $(OBJECTS) $(LDFLAGS) $(LIBS) $(LIBDIR) -o $@
|
# $(LINKER) $(OBJECTS) $(LDFLAGS) $(LIBS) $(LIBDIR) -o $@
|
||||||
riscv32-unknown-linux-gnu-objdump -d $< > dump
|
riscv32-unknown-elf-objdump -d $< > dump
|
||||||
objcopy -Oihex $< $(TARGET).hex
|
objcopy -Oihex $< $(TARGET).hex
|
||||||
@echo "Linking complete!"
|
@echo "Linking complete!"
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ CC = riscv32-unknown-elf-gcc
|
||||||
CFLAGS = -Wall -I. -O0 -Xlinker --gc-sections -lgcc -lc -static --specs=nano.specs
|
CFLAGS = -Wall -I. -O0 -Xlinker --gc-sections -lgcc -lc -static --specs=nano.specs
|
||||||
|
|
||||||
|
|
||||||
LINKER = riscv32-unknown-linux-gnu-gcc
|
|
||||||
# linking flags here
|
# linking flags here
|
||||||
LDFLAGS = -I. --entry main -L/opt/riscv/riscv32-unknown-elf/lib/ -T ld_script.ld
|
LDFLAGS = -I. --entry main -L/opt/riscv/riscv32-unknown-elf/lib/ -T ld_script.ld
|
||||||
LIBS = $(EXTRA_LIBS)
|
LIBS = $(EXTRA_LIBS)
|
||||||
|
|
|
@ -7,7 +7,6 @@ CC = riscv32-unknown-elf-gcc
|
||||||
# compiling flags here
|
# compiling flags here
|
||||||
CFLAGS = -Wall -I. -O0 -static --specs=nosys.specs
|
CFLAGS = -Wall -I. -O0 -static --specs=nosys.specs
|
||||||
|
|
||||||
LINKER = riscv32-unknown-linux-gnu-gcc
|
|
||||||
# linking flags here
|
# linking flags here
|
||||||
LDFLAGS = -I. --entry main -L/opt/riscv/riscv32-unknown-elf/lib/ -T ld_script.ld
|
LDFLAGS = -I. --entry main -L/opt/riscv/riscv32-unknown-elf/lib/ -T ld_script.ld
|
||||||
LIBS = $(EXTRA_LIBS)
|
LIBS = $(EXTRA_LIBS)
|
||||||
|
@ -28,7 +27,6 @@ rm = rm -f
|
||||||
|
|
||||||
|
|
||||||
$(BINDIR)/$(TARGET): $(OBJECTS)
|
$(BINDIR)/$(TARGET): $(OBJECTS)
|
||||||
# $(LINKER) $(OBJECTS) $(LDFLAGS) $(LIBS) $(LIBDIR) -o $@
|
|
||||||
riscv32-unknown-elf-objdump -d $< > dump
|
riscv32-unknown-elf-objdump -d $< > dump
|
||||||
objcopy -Oihex $< $(TARGET).hex
|
objcopy -Oihex $< $(TARGET).hex
|
||||||
# @echo "Linking complete!"
|
# @echo "Linking complete!"
|
||||||
|
|
|
@ -6,8 +6,6 @@ CC = riscv32-unknown-elf-gcc
|
||||||
# compiling flags here
|
# compiling flags here
|
||||||
CFLAGS = -Wall -I. -O0 -march=rv32i -mabi=ilp32 --specs=nosys.specs
|
CFLAGS = -Wall -I. -O0 -march=rv32i -mabi=ilp32 --specs=nosys.specs
|
||||||
|
|
||||||
|
|
||||||
LINKER = riscv32-unknown-linux-gnu-gcc
|
|
||||||
# linking flags here
|
# linking flags here
|
||||||
LFLAGS = -I.
|
LFLAGS = -I.
|
||||||
LIBS = $(EXTRA_LIBS)
|
LIBS = $(EXTRA_LIBS)
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
TARGET = timer
|
|
||||||
|
|
||||||
TARGET_ARCH=riscv32
|
|
||||||
|
|
||||||
CC = riscv32-unknown-elf-gcc
|
|
||||||
|
|
||||||
# compiling flags here
|
|
||||||
CFLAGS = -Wall -I. -O0 -static --specs=nosys.specs
|
|
||||||
|
|
||||||
LINKER = riscv32-unknown-linux-gnu-gcc
|
|
||||||
# linking flags here
|
|
||||||
LDFLAGS = -I. --entry main -L/opt/riscv/riscv32-unknown-elf/lib/ -T ld_script.ld
|
|
||||||
LIBS = $(EXTRA_LIBS)
|
|
||||||
|
|
||||||
|
|
||||||
# change these to proper directories where each file should be
|
|
||||||
SRCDIR = ./
|
|
||||||
OBJDIR = .
|
|
||||||
BINDIR = ./
|
|
||||||
INCDIR = -I.
|
|
||||||
LIBDIR = -L.
|
|
||||||
|
|
||||||
|
|
||||||
SOURCES := $(wildcard $(SRCDIR)/*.c)
|
|
||||||
INCLUDES := $(wildcard $(INCDIR)/*.h)
|
|
||||||
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
|
|
||||||
rm = rm -f
|
|
||||||
|
|
||||||
|
|
||||||
$(BINDIR)/$(TARGET): $(OBJECTS)
|
|
||||||
# $(LINKER) $(OBJECTS) $(LDFLAGS) $(LIBS) $(LIBDIR) -o $@
|
|
||||||
riscv32-unknown-linux-gnu-objdump -d $< > dump
|
|
||||||
objcopy -Oihex $< $(TARGET).hex
|
|
||||||
# @echo "Linking complete!"
|
|
||||||
|
|
||||||
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
|
|
||||||
@echo "Compiling "$<" ..."
|
|
||||||
# $(CC) $(CFLAGS) $(INCDIR) -c $< -o $@
|
|
||||||
$(CC) $(CFLAGS) $(INCDIR) $< -o $@
|
|
||||||
@echo "Done!"
|
|
||||||
|
|
||||||
#$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.S
|
|
||||||
# @echo "Assembling "$<" ..."
|
|
||||||
# $(CC) $(CFLAGS) $(INCDIR) -c $< -o $@
|
|
||||||
# $(CC) $(CFLAGS) $(INCDIR) $< -o $@
|
|
||||||
# @echo "Done!"
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean:
|
|
||||||
@$(rm) $(OBJECTS) *.hex dump
|
|
||||||
@echo "Cleanup complete!"
|
|
||||||
|
|
||||||
.PHONY: remove
|
|
||||||
remove: clean
|
|
||||||
@$(rm) $(BINDIR)/$(TARGET)
|
|
||||||
@echo "Executable removed!"
|
|
|
@ -31,7 +31,7 @@ rm = rm -f
|
||||||
|
|
||||||
$(BINDIR)/$(TARGET): $(OBJECTS)
|
$(BINDIR)/$(TARGET): $(OBJECTS)
|
||||||
# $(LINKER) $(OBJECTS) $(LFLAGS) $(LIBS) $(LIBDIR) -o $@
|
# $(LINKER) $(OBJECTS) $(LFLAGS) $(LIBS) $(LIBDIR) -o $@
|
||||||
riscv32-unknown-linux-gnu-objdump -d $< > dump
|
riscv32-unknown-elf-objdump -d $< > dump
|
||||||
objcopy -Oihex $< $(TARGET).hex
|
objcopy -Oihex $< $(TARGET).hex
|
||||||
# @echo "Linking complete!"
|
# @echo "Linking complete!"
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ rm = rm -f
|
||||||
|
|
||||||
$(BINDIR)/$(TARGET): $(OBJECTS)
|
$(BINDIR)/$(TARGET): $(OBJECTS)
|
||||||
# $(LINKER) $(OBJECTS) $(LFLAGS) $(LIBS) $(LIBDIR) -o $@
|
# $(LINKER) $(OBJECTS) $(LFLAGS) $(LIBS) $(LIBDIR) -o $@
|
||||||
riscv32-unknown-linux-gnu-objdump -d $< > dump
|
riscv32-unknown-elf-objdump -d $< > dump
|
||||||
objcopy -Oihex $< $(TARGET).hex
|
objcopy -Oihex $< $(TARGET).hex
|
||||||
# @echo "Linking complete!"
|
# @echo "Linking complete!"
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ rm = rm -f
|
||||||
|
|
||||||
$(BINDIR)/$(TARGET): $(OBJECTS)
|
$(BINDIR)/$(TARGET): $(OBJECTS)
|
||||||
# $(LINKER) $(OBJECTS) $(LFLAGS) $(LIBS) $(LIBDIR) -o $@
|
# $(LINKER) $(OBJECTS) $(LFLAGS) $(LIBS) $(LIBDIR) -o $@
|
||||||
riscv32-unknown-linux-gnu-objdump -d $< > dump
|
riscv32-unknown-elf-objdump -d $< > dump
|
||||||
objcopy -Oihex $< $(TARGET).hex
|
objcopy -Oihex $< $(TARGET).hex
|
||||||
# @echo "Linking complete!"
|
# @echo "Linking complete!"
|
||||||
|
|
||||||
|
|
|
@ -8,3 +8,4 @@ loop:
|
||||||
SUB t1, t1, t2
|
SUB t1, t1, t2
|
||||||
BNE t1, zero, loop
|
BNE t1, zero, loop
|
||||||
# END
|
# END
|
||||||
|
ECALL
|
||||||
|
|
|
@ -9,3 +9,4 @@ ADD t4, t1, t2
|
||||||
ADD t5, t2, t3
|
ADD t5, t2, t3
|
||||||
SUB t6, t2, t1
|
SUB t6, t2, t1
|
||||||
#SUB t7, t1, t2
|
#SUB t7, t1, t2
|
||||||
|
ECALL
|
||||||
|
|
|
@ -6,3 +6,4 @@ sb t3, -13(t2)
|
||||||
li t1, 23
|
li t1, 23
|
||||||
lbu t1, -6(t2)
|
lbu t1, -6(t2)
|
||||||
lbu t3, -13(t2)
|
lbu t3, -13(t2)
|
||||||
|
ecall
|
||||||
|
|
|
@ -32,3 +32,4 @@ _start:
|
||||||
sb t0, 0(a2)
|
sb t0, 0(a2)
|
||||||
li t0, '\n'
|
li t0, '\n'
|
||||||
sb t0, 0(a2)
|
sb t0, 0(a2)
|
||||||
|
ecall
|
||||||
|
|
Loading…
Reference in New Issue