Register class changed to templated to prepare for rv64 code
This commit is contained in:
		
							parent
							
								
									a82938bb61
								
							
						
					
					
						commit
						d1fa3c752e
					
				| 
						 | 
					@ -52,7 +52,7 @@ namespace riscv_tlm {
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief Instruction decoding and fields access
 | 
					 * @brief Instruction decoding and fields access
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
    class A_extension : public extension_base {
 | 
					    class A_extension : public extension_base<std::uint32_t> {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -92,13 +92,13 @@ namespace riscv_tlm {
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief Risc_V execute module
 | 
					 * @brief Risc_V execute module
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
    class BASE_ISA : public extension_base {
 | 
					    class BASE_ISA : public extension_base<std::uint32_t> {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * @brief Constructor, same as base class
 | 
					         * @brief Constructor, same as base class
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        using extension_base::extension_base;
 | 
					        using extension_base<std::uint32_t>::extension_base;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * @brief Access to funct7 field
 | 
					         * @brief Access to funct7 field
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,10 +67,10 @@ namespace riscv_tlm {
 | 
				
			||||||
        bool CPU_step();
 | 
					        bool CPU_step();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Registers *getRegisterBank() { return register_bank; }
 | 
					        Registers<std::uint32_t> *getRegisterBank() { return register_bank; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
        Registers *register_bank;
 | 
					        Registers<std::uint32_t> *register_bank;
 | 
				
			||||||
        Performance *perf;
 | 
					        Performance *perf;
 | 
				
			||||||
        std::shared_ptr<spdlog::logger> logger;
 | 
					        std::shared_ptr<spdlog::logger> logger;
 | 
				
			||||||
        C_extension *c_inst;
 | 
					        C_extension *c_inst;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -95,7 +95,7 @@ namespace riscv_tlm {
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief Instruction decoding and fields access
 | 
					 * @brief Instruction decoding and fields access
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
    class C_extension : public extension_base {
 | 
					 class C_extension : public extension_base<std::uint32_t> {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,7 +43,7 @@ namespace riscv_tlm {
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief Instruction decoding and fields access
 | 
					 * @brief Instruction decoding and fields access
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
    class M_extension : public extension_base {
 | 
					    class M_extension : public extension_base<std::uint32_t> {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										173
									
								
								inc/Registers.h
								
								
								
								
							
							
						
						
									
										173
									
								
								inc/Registers.h
								
								
								
								
							| 
						 | 
					@ -112,6 +112,7 @@ namespace riscv_tlm {
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief Register file implementation
 | 
					 * @brief Register file implementation
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					    template<typename T>
 | 
				
			||||||
    class Registers {
 | 
					    class Registers {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -186,33 +187,56 @@ namespace riscv_tlm {
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * Default constructor
 | 
					         * Default constructor
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        Registers();
 | 
					        Registers() {
 | 
				
			||||||
 | 
					          perf = Performance::getInstance();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          initCSR();
 | 
				
			||||||
 | 
					          register_bank[sp] = Memory::SIZE - 4; // default stack at the end of the memory
 | 
				
			||||||
 | 
					          register_PC = 0x80000000;       // default _start address
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * Set value for a register
 | 
					         * Set value for a register
 | 
				
			||||||
         * @param reg_num register number
 | 
					         * @param reg_num register number
 | 
				
			||||||
         * @param value   register value
 | 
					         * @param value   register value
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        void setValue(int reg_num, std::int32_t value);
 | 
					        void setValue(int reg_num, T value) {
 | 
				
			||||||
 | 
					          if ((reg_num != 0) && (reg_num < 32)) {
 | 
				
			||||||
 | 
					              register_bank[reg_num] = value;
 | 
				
			||||||
 | 
					              perf->registerWrite();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * Returns register value
 | 
					         * Returns register value
 | 
				
			||||||
         * @param  reg_num register number
 | 
					         * @param  reg_num register number
 | 
				
			||||||
         * @return         register value
 | 
					         * @return         register value
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        std::uint32_t getValue(int reg_num) const;
 | 
					        T getValue(int reg_num) const {
 | 
				
			||||||
 | 
					          if ((reg_num >= 0) && (reg_num < 32)) {
 | 
				
			||||||
 | 
					              perf->registerRead();
 | 
				
			||||||
 | 
					              return register_bank[reg_num];
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					              /* TODO Exten sign for any possible T type */
 | 
				
			||||||
 | 
					              return static_cast<T>(0xFFFFFFFF);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * Returns PC value
 | 
					         * Returns PC value
 | 
				
			||||||
         * @return PC value
 | 
					         * @return PC value
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        std::uint32_t getPC() const;
 | 
					        T getPC() const {
 | 
				
			||||||
 | 
					          return register_PC;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * Sets arbitraty value to PC
 | 
					         * Sets arbitraty value to PC
 | 
				
			||||||
         * @param new_pc new address to PC
 | 
					         * @param new_pc new address to PC
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        void setPC(std::uint32_t new_pc);
 | 
					        void setPC(T new_pc) {
 | 
				
			||||||
 | 
					          register_PC = new_pc;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * Increments PC couunter to next address
 | 
					         * Increments PC couunter to next address
 | 
				
			||||||
| 
						 | 
					@ -230,40 +254,163 @@ namespace riscv_tlm {
 | 
				
			||||||
         * @param csr CSR number to access
 | 
					         * @param csr CSR number to access
 | 
				
			||||||
         * @return CSR value
 | 
					         * @return CSR value
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        std::uint32_t getCSR(int csr);
 | 
					        T getCSR(int csr) {
 | 
				
			||||||
 | 
					          T ret_value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          switch (csr) {
 | 
				
			||||||
 | 
					              case CSR_CYCLE:
 | 
				
			||||||
 | 
					              case CSR_MCYCLE:
 | 
				
			||||||
 | 
					                ret_value = static_cast<std::uint64_t>(sc_core::sc_time(
 | 
				
			||||||
 | 
					                    sc_core::sc_time_stamp()
 | 
				
			||||||
 | 
					                    - sc_core::sc_time(sc_core::SC_ZERO_TIME)).to_double())
 | 
				
			||||||
 | 
					                            & 0x00000000FFFFFFFF;
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					              case CSR_CYCLEH:
 | 
				
			||||||
 | 
					              case CSR_MCYCLEH:
 | 
				
			||||||
 | 
					                ret_value = static_cast<std::uint32_t>((std::uint64_t) (sc_core::sc_time(
 | 
				
			||||||
 | 
					                    sc_core::sc_time_stamp()
 | 
				
			||||||
 | 
					                    - sc_core::sc_time(sc_core::SC_ZERO_TIME)).to_double())
 | 
				
			||||||
 | 
					                                                           >> 32 & 0x00000000FFFFFFFF);
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					              case CSR_TIME:
 | 
				
			||||||
 | 
					                ret_value = static_cast<std::uint64_t>(sc_core::sc_time(
 | 
				
			||||||
 | 
					                    sc_core::sc_time_stamp()
 | 
				
			||||||
 | 
					                    - sc_core::sc_time(sc_core::SC_ZERO_TIME)).to_double())
 | 
				
			||||||
 | 
					                            & 0x00000000FFFFFFFF;
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					              case CSR_TIMEH:
 | 
				
			||||||
 | 
					                ret_value = static_cast<std::uint32_t>((std::uint64_t) (sc_core::sc_time(
 | 
				
			||||||
 | 
					                    sc_core::sc_time_stamp()
 | 
				
			||||||
 | 
					                    - sc_core::sc_time(sc_core::SC_ZERO_TIME)).to_double())
 | 
				
			||||||
 | 
					                                                           >> 32 & 0x00000000FFFFFFFF);
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					              [[likely]] default:
 | 
				
			||||||
 | 
					            ret_value = CSR[csr];
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          return ret_value;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * @brief Set CSR value
 | 
					         * @brief Set CSR value
 | 
				
			||||||
         * @param csr   CSR number to access
 | 
					         * @param csr   CSR number to access
 | 
				
			||||||
         * @param value new value to register
 | 
					         * @param value new value to register
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        void setCSR(int csr, std::uint32_t value);
 | 
					        void setCSR(int csr, T value) {
 | 
				
			||||||
 | 
					         /* @FIXME: rv32mi-p-ma_fetch tests doesn't allow MISA to be writable,
 | 
				
			||||||
 | 
					          * but Volume II: Privileged Architecture v1.10 says MISA is writable (?)
 | 
				
			||||||
 | 
					          */
 | 
				
			||||||
 | 
					          if (csr != CSR_MISA) {
 | 
				
			||||||
 | 
					              CSR[csr] = value;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * Dump register data to console
 | 
					         * Dump register data to console
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        void dump();
 | 
					        void dump() {
 | 
				
			||||||
 | 
					          std::cout << "************************************" << std::endl;
 | 
				
			||||||
 | 
					          std::cout << "Registers dump" << std::dec << std::endl;
 | 
				
			||||||
 | 
					          std::cout << std::setfill('0') << std::uppercase;
 | 
				
			||||||
 | 
					          std::cout << "x0 (zero):  0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[0];
 | 
				
			||||||
 | 
					          std::cout << " x1 (ra):    0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[1];
 | 
				
			||||||
 | 
					          std::cout << " x2 (sp):    0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[2];
 | 
				
			||||||
 | 
					          std::cout << " x3 (gp):    0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[3] << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          std::cout << "x4 (tp):    0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[4];
 | 
				
			||||||
 | 
					          std::cout << " x5 (t0):    0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[5];
 | 
				
			||||||
 | 
					          std::cout << " x6 (t1):    0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[6];
 | 
				
			||||||
 | 
					          std::cout << " x7 (t2):    0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[7] << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          std::cout << "x8 (s0/fp): 0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[8];
 | 
				
			||||||
 | 
					          std::cout << " x9 (s1):    0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[9];
 | 
				
			||||||
 | 
					          std::cout << " x10 (a0):   0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[10];
 | 
				
			||||||
 | 
					          std::cout << " x11 (a1):   0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[11] << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          std::cout << "x12 (a2):   0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[12];
 | 
				
			||||||
 | 
					          std::cout << " x13 (a3):   0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[13];
 | 
				
			||||||
 | 
					          std::cout << " x14 (a4):   0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[14];
 | 
				
			||||||
 | 
					          std::cout << " x15 (a5):   0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[15] << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          std::cout << "x16 (a6):   0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[16];
 | 
				
			||||||
 | 
					          std::cout << " x17 (a7):   0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[17];
 | 
				
			||||||
 | 
					          std::cout << " x18 (s2):   0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[18];
 | 
				
			||||||
 | 
					          std::cout << " x19 (s3):   0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[19] << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          std::cout << "x20 (s4):   0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[20];
 | 
				
			||||||
 | 
					          std::cout << " x21 (s5):   0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[21];
 | 
				
			||||||
 | 
					          std::cout << " x22 (s6):   0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[22];
 | 
				
			||||||
 | 
					          std::cout << " x23 (s7):   0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[23] << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          std::cout << "x24 (s8):   0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[24];
 | 
				
			||||||
 | 
					          std::cout << " x25 (s9):   0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[25];
 | 
				
			||||||
 | 
					          std::cout << " x26 (s10):  0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[26];
 | 
				
			||||||
 | 
					          std::cout << " x27 (s11):  0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[27] << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          std::cout << "x28 (t3):   0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[28];
 | 
				
			||||||
 | 
					          std::cout << " x29 (t4):   0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[29];
 | 
				
			||||||
 | 
					          std::cout << " x30 (t5):   0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[30];
 | 
				
			||||||
 | 
					          std::cout << " x31 (t6):   0x" << std::right << std::setw(8)
 | 
				
			||||||
 | 
					                    << std::hex << register_bank[31] << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          std::cout << "PC: 0x" << std::setw(8) << std::hex << register_PC << std::dec << std::endl;
 | 
				
			||||||
 | 
					          std::cout << "************************************" << std::endl;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * bank of registers (32 regs of 32bits each)
 | 
					         * bank of registers (32 regs of 32bits each)
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        std::array<std::uint32_t, 32> register_bank = {{0}};
 | 
					        std::array<T, 32> register_bank = {{0}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * Program counter (32 bits width)
 | 
					         * Program counter (32 bits width)
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        std::uint32_t register_PC;
 | 
					        T register_PC;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * CSR registers (4096 maximum)
 | 
					         * CSR registers (4096 maximum)
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        std::unordered_map<std::uint32_t, unsigned int> CSR;
 | 
					        std::unordered_map<T, unsigned int> CSR;
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Performance *perf;
 | 
					        Performance *perf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void initCSR();
 | 
					        void initCSR() {
 | 
				
			||||||
 | 
					          CSR[CSR_MISA] = MISA_MXL | MISA_M_EXTENSION | MISA_C_EXTENSION
 | 
				
			||||||
 | 
					                          | MISA_A_EXTENSION | MISA_I_BASE;
 | 
				
			||||||
 | 
					          CSR[CSR_MSTATUS] = MISA_MXL;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,19 +28,55 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace riscv_tlm {
 | 
					namespace riscv_tlm {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<typename T>
 | 
				
			||||||
    class extension_base {
 | 
					    class extension_base {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        extension_base(const sc_dt::sc_uint<32> &instr, Registers *register_bank,
 | 
					        extension_base(const T &instr, Registers<T> *register_bank,
 | 
				
			||||||
                       MemoryInterface *mem_interface);
 | 
					                       MemoryInterface *mem_interface) :
 | 
				
			||||||
 | 
					            m_instr(instr), regs(register_bank), mem_intf(mem_interface) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        virtual ~extension_base() = 0;
 | 
					          perf = Performance::getInstance();
 | 
				
			||||||
 | 
					          logger = spdlog::get("my_logger");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void setInstr(std::uint32_t p_instr);
 | 
					        virtual ~extension_base() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void RaiseException(std::uint32_t cause, std::uint32_t inst);
 | 
					        void setInstr(std::uint32_t p_instr) {
 | 
				
			||||||
 | 
					          m_instr = sc_dt::sc_uint<32>(p_instr);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bool NOP();
 | 
					        void RaiseException(std::uint32_t cause, std::uint32_t inst) {
 | 
				
			||||||
 | 
					          std::uint32_t new_pc, current_pc, m_cause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          current_pc = regs->getPC();
 | 
				
			||||||
 | 
					          m_cause = regs->getCSR(CSR_MSTATUS);
 | 
				
			||||||
 | 
					          m_cause |= cause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          new_pc = regs->getCSR(CSR_MTVEC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          regs->setCSR(CSR_MEPC, current_pc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if (cause == EXCEPTION_CAUSE_ILLEGAL_INSTRUCTION) {
 | 
				
			||||||
 | 
					              regs->setCSR(CSR_MTVAL, inst);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					              regs->setCSR(CSR_MTVAL, current_pc);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          regs->setCSR(CSR_MCAUSE, cause);
 | 
				
			||||||
 | 
					          regs->setCSR(CSR_MSTATUS, m_cause);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          regs->setPC(new_pc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          logger->debug("{} ns. PC: 0x{:x}. Exception! new PC 0x{:x} ", sc_core::sc_time_stamp().value(), regs->getPC(),
 | 
				
			||||||
 | 
					                        new_pc);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        bool NOP() {
 | 
				
			||||||
 | 
					          logger->debug("{} ns. PC: 0x{:x}. NOP! new PC 0x{:x} ", sc_core::sc_time_stamp().value(), regs->getPC());
 | 
				
			||||||
 | 
					          sc_core::sc_stop();
 | 
				
			||||||
 | 
					          return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* pure virtual functions */
 | 
					        /* pure virtual functions */
 | 
				
			||||||
        virtual std::int32_t opcode() const = 0;
 | 
					        virtual std::int32_t opcode() const = 0;
 | 
				
			||||||
| 
						 | 
					@ -77,11 +113,13 @@ namespace riscv_tlm {
 | 
				
			||||||
            m_instr.range(14, 12) = value;
 | 
					            m_instr.range(14, 12) = value;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        virtual void dump() const;
 | 
					        virtual void dump() const {
 | 
				
			||||||
 | 
					          std::cout << std::hex << "0x" << m_instr << std::dec << std::endl;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected:
 | 
					    protected:
 | 
				
			||||||
        sc_dt::sc_uint<32> m_instr;
 | 
					        sc_dt::sc_uint<32> m_instr;
 | 
				
			||||||
        Registers *regs;
 | 
					        Registers<T> *regs;
 | 
				
			||||||
        Performance *perf;
 | 
					        Performance *perf;
 | 
				
			||||||
        MemoryInterface *mem_intf;
 | 
					        MemoryInterface *mem_intf;
 | 
				
			||||||
        std::shared_ptr<spdlog::logger> logger;
 | 
					        std::shared_ptr<spdlog::logger> logger;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -126,7 +126,7 @@ namespace riscv_tlm {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        rd = get_rd();
 | 
					        rd = get_rd();
 | 
				
			||||||
        mem_addr = get_imm_J();
 | 
					        mem_addr = get_imm_J();
 | 
				
			||||||
        old_pc = static_cast<std::uint32_t>(regs->getPC());
 | 
					        old_pc = regs->getPC();
 | 
				
			||||||
        new_pc = old_pc + mem_addr;
 | 
					        new_pc = old_pc + mem_addr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        regs->setPC(new_pc);
 | 
					        regs->setPC(new_pc);
 | 
				
			||||||
| 
						 | 
					@ -150,7 +150,7 @@ namespace riscv_tlm {
 | 
				
			||||||
        rs1 = get_rs1();
 | 
					        rs1 = get_rs1();
 | 
				
			||||||
        mem_addr = get_imm_I();
 | 
					        mem_addr = get_imm_I();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        old_pc = static_cast<std::uint32_t>(regs->getPC());
 | 
					        old_pc = regs->getPC();
 | 
				
			||||||
        regs->setValue(rd, old_pc + 4);
 | 
					        regs->setValue(rd, old_pc + 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        new_pc = static_cast<std::uint32_t>((regs->getValue(rs1) + mem_addr) & 0xFFFFFFFE);
 | 
					        new_pc = static_cast<std::uint32_t>((regs->getValue(rs1) + mem_addr) & 0xFFFFFFFE);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,13 +14,13 @@ namespace riscv_tlm {
 | 
				
			||||||
    CPU::CPU(sc_core::sc_module_name const &name, std::uint32_t PC, bool debug) :
 | 
					    CPU::CPU(sc_core::sc_module_name const &name, std::uint32_t PC, bool debug) :
 | 
				
			||||||
            sc_module(name), instr_bus("instr_bus"), inst(0), default_time(10,
 | 
					            sc_module(name), instr_bus("instr_bus"), inst(0), default_time(10,
 | 
				
			||||||
                                                                           sc_core::SC_NS), INSTR(0) {
 | 
					                                                                           sc_core::SC_NS), INSTR(0) {
 | 
				
			||||||
        register_bank = new Registers();
 | 
					        register_bank = new Registers<std::uint32_t>();
 | 
				
			||||||
        mem_intf = new MemoryInterface();
 | 
					        mem_intf = new MemoryInterface();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        perf = Performance::getInstance();
 | 
					        perf = Performance::getInstance();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register_bank->setPC(PC);
 | 
					        register_bank->setPC(PC);
 | 
				
			||||||
        register_bank->setValue(Registers::sp, (Memory::SIZE / 4) - 1);
 | 
					        register_bank->setValue(Registers<std::uint32_t>::sp, (Memory::SIZE / 4) - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        irq_line_socket.register_b_transport(this, &CPU::call_interrupt);
 | 
					        irq_line_socket.register_b_transport(this, &CPU::call_interrupt);
 | 
				
			||||||
        interrupt = false;
 | 
					        interrupt = false;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -77,7 +77,7 @@ namespace riscv_tlm {
 | 
				
			||||||
    void Debug::handle_gdb_loop() {
 | 
					    void Debug::handle_gdb_loop() {
 | 
				
			||||||
        std::cout << "Handle_GDB_Loop\n";
 | 
					        std::cout << "Handle_GDB_Loop\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Registers *register_bank = dbg_cpu->getRegisterBank();
 | 
					        Registers<std::uint32_t> *register_bank = dbg_cpu->getRegisterBank();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        while (true) {
 | 
					        while (true) {
 | 
				
			||||||
            std::string msg = receive_packet();
 | 
					            std::string msg = receive_packet();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,171 +6,4 @@
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
// SPDX-License-Identifier: GPL-3.0-or-later
 | 
					// SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Registers.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace riscv_tlm {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Registers::Registers() {
 | 
					 | 
				
			||||||
        perf = Performance::getInstance();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        initCSR();
 | 
					 | 
				
			||||||
        register_bank[sp] = Memory::SIZE - 4; // default stack at the end of the memory
 | 
					 | 
				
			||||||
        register_PC = 0x80000000;       // default _start address
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void Registers::dump() {
 | 
					 | 
				
			||||||
        std::cout << "************************************" << std::endl;
 | 
					 | 
				
			||||||
        std::cout << "Registers dump" << std::dec << std::endl;
 | 
					 | 
				
			||||||
        std::cout << std::setfill('0') << std::uppercase;
 | 
					 | 
				
			||||||
        std::cout << "x0 (zero):  0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[0];
 | 
					 | 
				
			||||||
        std::cout << " x1 (ra):    0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[1];
 | 
					 | 
				
			||||||
        std::cout << " x2 (sp):    0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[2];
 | 
					 | 
				
			||||||
        std::cout << " x3 (gp):    0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[3] << std::endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        std::cout << "x4 (tp):    0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[4];
 | 
					 | 
				
			||||||
        std::cout << " x5 (t0):    0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[5];
 | 
					 | 
				
			||||||
        std::cout << " x6 (t1):    0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[6];
 | 
					 | 
				
			||||||
        std::cout << " x7 (t2):    0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[7] << std::endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        std::cout << "x8 (s0/fp): 0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[8];
 | 
					 | 
				
			||||||
        std::cout << " x9 (s1):    0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[9];
 | 
					 | 
				
			||||||
        std::cout << " x10 (a0):   0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[10];
 | 
					 | 
				
			||||||
        std::cout << " x11 (a1):   0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[11] << std::endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        std::cout << "x12 (a2):   0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[12];
 | 
					 | 
				
			||||||
        std::cout << " x13 (a3):   0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[13];
 | 
					 | 
				
			||||||
        std::cout << " x14 (a4):   0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[14];
 | 
					 | 
				
			||||||
        std::cout << " x15 (a5):   0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[15] << std::endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        std::cout << "x16 (a6):   0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[16];
 | 
					 | 
				
			||||||
        std::cout << " x17 (a7):   0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[17];
 | 
					 | 
				
			||||||
        std::cout << " x18 (s2):   0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[18];
 | 
					 | 
				
			||||||
        std::cout << " x19 (s3):   0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[19] << std::endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        std::cout << "x20 (s4):   0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[20];
 | 
					 | 
				
			||||||
        std::cout << " x21 (s5):   0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[21];
 | 
					 | 
				
			||||||
        std::cout << " x22 (s6):   0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[22];
 | 
					 | 
				
			||||||
        std::cout << " x23 (s7):   0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[23] << std::endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        std::cout << "x24 (s8):   0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[24];
 | 
					 | 
				
			||||||
        std::cout << " x25 (s9):   0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[25];
 | 
					 | 
				
			||||||
        std::cout << " x26 (s10):  0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[26];
 | 
					 | 
				
			||||||
        std::cout << " x27 (s11):  0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[27] << std::endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        std::cout << "x28 (t3):   0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[28];
 | 
					 | 
				
			||||||
        std::cout << " x29 (t4):   0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[29];
 | 
					 | 
				
			||||||
        std::cout << " x30 (t5):   0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[30];
 | 
					 | 
				
			||||||
        std::cout << " x31 (t6):   0x" << std::right << std::setw(8)
 | 
					 | 
				
			||||||
                  << std::hex << register_bank[31] << std::endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        std::cout << "PC: 0x" << std::setw(8) << std::hex << register_PC << std::dec << std::endl;
 | 
					 | 
				
			||||||
        std::cout << "************************************" << std::endl;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void Registers::setValue(int reg_num, std::int32_t value) {
 | 
					 | 
				
			||||||
        if ((reg_num != 0) && (reg_num < 32)) {
 | 
					 | 
				
			||||||
            register_bank[reg_num] = value;
 | 
					 | 
				
			||||||
            perf->registerWrite();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    std::uint32_t Registers::getValue(int reg_num) const {
 | 
					 | 
				
			||||||
        if ((reg_num >= 0) && (reg_num < 32)) {
 | 
					 | 
				
			||||||
            perf->registerRead();
 | 
					 | 
				
			||||||
            return register_bank[reg_num];
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            return static_cast<std::int32_t>(0xFFFFFFFF);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    std::uint32_t Registers::getPC() const {
 | 
					 | 
				
			||||||
        return register_PC;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void Registers::setPC(std::uint32_t new_pc) {
 | 
					 | 
				
			||||||
        register_PC = new_pc;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    std::uint32_t Registers::getCSR(const int csr) {
 | 
					 | 
				
			||||||
        std::uint32_t ret_value;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        switch (csr) {
 | 
					 | 
				
			||||||
            case CSR_CYCLE:
 | 
					 | 
				
			||||||
            case CSR_MCYCLE:
 | 
					 | 
				
			||||||
                ret_value = static_cast<std::uint64_t>(sc_core::sc_time(
 | 
					 | 
				
			||||||
                        sc_core::sc_time_stamp()
 | 
					 | 
				
			||||||
                        - sc_core::sc_time(sc_core::SC_ZERO_TIME)).to_double())
 | 
					 | 
				
			||||||
                            & 0x00000000FFFFFFFF;
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case CSR_CYCLEH:
 | 
					 | 
				
			||||||
            case CSR_MCYCLEH:
 | 
					 | 
				
			||||||
                ret_value = static_cast<std::uint32_t>((std::uint64_t) (sc_core::sc_time(
 | 
					 | 
				
			||||||
                        sc_core::sc_time_stamp()
 | 
					 | 
				
			||||||
                        - sc_core::sc_time(sc_core::SC_ZERO_TIME)).to_double())
 | 
					 | 
				
			||||||
                                                               >> 32 & 0x00000000FFFFFFFF);
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case CSR_TIME:
 | 
					 | 
				
			||||||
                ret_value = static_cast<std::uint64_t>(sc_core::sc_time(
 | 
					 | 
				
			||||||
                        sc_core::sc_time_stamp()
 | 
					 | 
				
			||||||
                        - sc_core::sc_time(sc_core::SC_ZERO_TIME)).to_double())
 | 
					 | 
				
			||||||
                            & 0x00000000FFFFFFFF;
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case CSR_TIMEH:
 | 
					 | 
				
			||||||
                ret_value = static_cast<std::uint32_t>((std::uint64_t) (sc_core::sc_time(
 | 
					 | 
				
			||||||
                        sc_core::sc_time_stamp()
 | 
					 | 
				
			||||||
                        - sc_core::sc_time(sc_core::SC_ZERO_TIME)).to_double())
 | 
					 | 
				
			||||||
                                                               >> 32 & 0x00000000FFFFFFFF);
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
                [[likely]] default:
 | 
					 | 
				
			||||||
                ret_value = CSR[csr];
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return ret_value;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void Registers::setCSR(int csr, std::uint32_t value) {
 | 
					 | 
				
			||||||
        /* @FIXME: rv32mi-p-ma_fetch tests doesn't allow MISA to be writable,
 | 
					 | 
				
			||||||
         * but Volume II: Privileged Architecture v1.10 says MISA is writable (?)
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
        if (csr != CSR_MISA) {
 | 
					 | 
				
			||||||
            CSR[csr] = value;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void Registers::initCSR() {
 | 
					 | 
				
			||||||
        CSR[CSR_MISA] = MISA_MXL | MISA_M_EXTENSION | MISA_C_EXTENSION
 | 
					 | 
				
			||||||
                        | MISA_A_EXTENSION | MISA_I_BASE;
 | 
					 | 
				
			||||||
        CSR[CSR_MSTATUS] = MISA_MXL;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -7,57 +7,3 @@
 | 
				
			||||||
// SPDX-License-Identifier: GPL-3.0-or-later
 | 
					// SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "extension_base.h"
 | 
					#include "extension_base.h"
 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace riscv_tlm {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    extension_base::extension_base(const sc_dt::sc_uint<32> &instr,
 | 
					 | 
				
			||||||
                                   Registers *register_bank, MemoryInterface *mem_interface) :
 | 
					 | 
				
			||||||
            m_instr(instr), regs(register_bank), mem_intf(mem_interface) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        perf = Performance::getInstance();
 | 
					 | 
				
			||||||
        logger = spdlog::get("my_logger");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    extension_base::~extension_base() = default;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void extension_base::setInstr(std::uint32_t p_instr) {
 | 
					 | 
				
			||||||
        m_instr = sc_dt::sc_uint<32>(p_instr);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void extension_base::dump() const {
 | 
					 | 
				
			||||||
        std::cout << std::hex << "0x" << m_instr << std::dec << std::endl;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void extension_base::RaiseException(std::uint32_t cause, std::uint32_t inst) {
 | 
					 | 
				
			||||||
        std::uint32_t new_pc, current_pc, m_cause;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        current_pc = regs->getPC();
 | 
					 | 
				
			||||||
        m_cause = regs->getCSR(CSR_MSTATUS);
 | 
					 | 
				
			||||||
        m_cause |= cause;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        new_pc = regs->getCSR(CSR_MTVEC);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        regs->setCSR(CSR_MEPC, current_pc);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (cause == EXCEPTION_CAUSE_ILLEGAL_INSTRUCTION) {
 | 
					 | 
				
			||||||
            regs->setCSR(CSR_MTVAL, inst);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            regs->setCSR(CSR_MTVAL, current_pc);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        regs->setCSR(CSR_MCAUSE, cause);
 | 
					 | 
				
			||||||
        regs->setCSR(CSR_MSTATUS, m_cause);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        regs->setPC(new_pc);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        logger->debug("{} ns. PC: 0x{:x}. Exception! new PC 0x{:x} ", sc_core::sc_time_stamp().value(), regs->getPC(),
 | 
					 | 
				
			||||||
                      new_pc);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool extension_base::NOP() {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        logger->debug("{} ns. PC: 0x{:x}. NOP! new PC 0x{:x} ", sc_core::sc_time_stamp().value(), regs->getPC());
 | 
					 | 
				
			||||||
        sc_core::sc_stop();
 | 
					 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Loading…
	
		Reference in New Issue