diff --git a/asm/Memoryaccess.asm b/asm/Memoryaccess.asm new file mode 100644 index 0000000..ef5b0f9 --- /dev/null +++ b/asm/Memoryaccess.asm @@ -0,0 +1,6 @@ +li t1, 150 +li t2, 300 +li t3, -250 +sw t1, -4(t2) +li t1, 500 +lw t1, -4(t2) diff --git a/inc/CPU.h b/inc/CPU.h index c6d0fc2..f5471e3 100644 --- a/inc/CPU.h +++ b/inc/CPU.h @@ -40,9 +40,10 @@ public: CPU(sc_module_name name); ~CPU(); + RISC_V_execute *exec; + private: Registers *register_bank; - RISC_V_execute *exec; Performance *perf; Log *log; diff --git a/inc/Memory.h b/inc/Memory.h index eddf4c7..191333d 100644 --- a/inc/Memory.h +++ b/inc/Memory.h @@ -34,7 +34,7 @@ public: const sc_time LATENCY; Memory(sc_module_name name, string filename); - + Memory(sc_module_name name, bool use_file); // TLM-2 blocking transport method virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ); diff --git a/inc/RISC_V_execute.h b/inc/RISC_V_execute.h index 41b82b4..b15270d 100644 --- a/inc/RISC_V_execute.h +++ b/inc/RISC_V_execute.h @@ -37,6 +37,8 @@ public: RISC_V_execute(sc_module_name name, Registers *register_bank); + /* Quick & dirty way to publish a socket though modules */ + tlm_utils::simple_initiator_socket data_bus; void LUI(Instruction &inst); void AUIPC(Instruction &inst); @@ -93,9 +95,10 @@ public: void CSRRCI(Instruction &inst); void NOP(Instruction &inst); -private: - uint32_t readDataMem(uint32_t addr); +private: + uint32_t readDataMem(uint32_t addr, int size); + void writeDataMem(uint32_t addr, uint32_t data, int size); Registers *regs; Performance *perf; Log *log; diff --git a/src/CPU.cpp b/src/CPU.cpp index 3c48f86..f67a0dc 100644 --- a/src/CPU.cpp +++ b/src/CPU.cpp @@ -4,9 +4,7 @@ SC_HAS_PROCESS(CPU); CPU::CPU(sc_module_name name): sc_module(name) , instr_bus("instr_bus") -//, exec("RISC_V_exec", ®ister_bank) -//, data_bus("data_bus") - { +{ register_bank = new Registers(); exec = new RISC_V_execute("RISC_V_execute", register_bank); perf = Performance::getInstance(); @@ -71,6 +69,12 @@ void CPU::CPU_thread(void) { case OP_BNE: exec->BNE(inst); break; + case OP_LW: + exec->LW(inst); + break; + case OP_SW: + exec->SW(inst); + break; case OP_ADDI: exec->ADDI(inst); break; diff --git a/src/Log.cpp b/src/Log.cpp index 2b4f6ad..64619e1 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -12,7 +12,7 @@ Log* Log::getInstance() Log::Log(const char* filename) { m_stream.open(filename); - currentLogLevel = Log::INFO; + currentLogLevel = Log::ERROR; } void Log::SC_log(std::string msg, enum LogLevel level) { diff --git a/src/Memory.cpp b/src/Memory.cpp index 8f62527..829880b 100644 --- a/src/Memory.cpp +++ b/src/Memory.cpp @@ -16,6 +16,17 @@ Memory::Memory(sc_module_name name, string filename): sc_module(name) SC_THREAD(invalidation_process); } +Memory::Memory(sc_module_name name, bool use_file): sc_module(name) + ,socket("socket") + ,LATENCY(SC_ZERO_TIME) { + socket.register_b_transport( this, &Memory::b_transport); + socket.register_get_direct_mem_ptr(this, &Memory::get_direct_mem_ptr); + socket.register_transport_dbg( this, &Memory::transport_dbg); + + memset(mem, 0, SIZE*sizeof(int)); + + SC_THREAD(invalidation_process); + } void Memory::b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ) { diff --git a/src/RISC_V_execute.cpp b/src/RISC_V_execute.cpp index 5876df4..efc3eb9 100644 --- a/src/RISC_V_execute.cpp +++ b/src/RISC_V_execute.cpp @@ -4,6 +4,7 @@ SC_HAS_PROCESS(RISC_V_execute); RISC_V_execute::RISC_V_execute(sc_module_name name , Registers *register_bank) : sc_module(name) + , data_bus("data_bus") , regs(register_bank) { perf = Performance::getInstance(); log = Log::getInstance(); @@ -69,7 +70,7 @@ void RISC_V_execute::JALR(Instruction &inst) { void RISC_V_execute::BEQ(Instruction &inst) { int rs1, rs2; - int new_pc; + int new_pc = 0; rs1 = inst.rs1(); rs2 = inst.rs2(); @@ -85,7 +86,7 @@ void RISC_V_execute::BEQ(Instruction &inst) { void RISC_V_execute::BNE(Instruction &inst) { int rs1, rs2; - int new_pc; + int new_pc = 0; rs1 = inst.rs1(); rs2 = inst.rs2(); @@ -100,7 +101,7 @@ void RISC_V_execute::BNE(Instruction &inst) { void RISC_V_execute::BLT(Instruction &inst) { int rs1, rs2; - int new_pc; + int new_pc = 0; rs1 = inst.rs1(); rs2 = inst.rs2(); @@ -115,7 +116,7 @@ void RISC_V_execute::BLT(Instruction &inst) { void RISC_V_execute::BGE(Instruction &inst) { int rs1, rs2; - int new_pc; + int new_pc = 0; rs1 = inst.rs1(); rs2 = inst.rs2(); @@ -130,7 +131,7 @@ void RISC_V_execute::BGE(Instruction &inst) { void RISC_V_execute::BLTU(Instruction &inst) { int rs1, rs2; - int new_pc; + int new_pc = 0; rs1 = inst.rs1(); rs2 = inst.rs2(); @@ -145,7 +146,7 @@ void RISC_V_execute::BLTU(Instruction &inst) { void RISC_V_execute::BGEU(Instruction &inst) { int rs1, rs2; - int new_pc; + int new_pc = 0; rs1 = inst.rs1(); rs2 = inst.rs2(); @@ -158,19 +159,43 @@ void RISC_V_execute::BGEU(Instruction &inst) { log->SC_log(Log::INFO) << "BGEU R" << rs1 << " > R" << rs2 << "? -> PC (" << new_pc << ")" << endl; } -void RISC_V_execute::LB(Instruction &inst) { +void RISC_V_execute::LW(Instruction &inst) { uint32_t mem_addr = 0; int rd, rs1; - uint32_t imm = 0; + int32_t imm = 0; uint32_t data; rd = inst.rd(); rs1 = inst.rs1(); - imm = inst.imm_U() << 12; + imm = inst.imm_I(); - mem_addr = imm + rs1; - data = readDataMem(mem_addr); + mem_addr = imm + regs->getValue(rs1); + data = readDataMem(mem_addr, 4); regs->setValue(rd, data); + + cout << "LW Data: " << data << endl; + log->SC_log(Log::INFO) << "LW: R" << rs1 << " + " << imm << " (@0x" + << hex < R" << rd << endl; +} + + +void RISC_V_execute::SW(Instruction &inst) { + uint32_t mem_addr = 0; + int rs1, rs2; + int32_t imm = 0; + uint32_t data; + + rs1 = inst.rs1(); + rs2 = inst.rs2(); + imm = inst.imm_S(); + + mem_addr = imm + regs->getValue(rs1); + data = regs->getValue(rs2); + + writeDataMem(mem_addr, data, 4); + + log->SC_log(Log::INFO) << "SW: R" << rs2 << " -> R" << rs1 << " + " + << imm << " (@0x" << hex <b_transport(*trans, delay); + trans.set_command( tlm::TLM_READ_COMMAND ); + trans.set_data_ptr( reinterpret_cast(&data) ); + 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 ); + trans.set_address( addr ); - return 0; + data_bus->b_transport( trans, delay); + cout << "RD addr: " << addr << " data: " << data << endl; + return data; +} + + +void RISC_V_execute::writeDataMem(uint32_t addr, uint32_t data, int size) { + tlm::tlm_generic_payload trans; + sc_time delay = SC_ZERO_TIME; + + trans.set_command( tlm::TLM_WRITE_COMMAND ); + trans.set_data_ptr( reinterpret_cast(&data) ); + trans.set_data_length( size ); + 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 ); + trans.set_address( addr ); + + data_bus->b_transport( trans, delay); + + cout << "WR addr: " << addr << " data: " << data << endl; } diff --git a/src/Simulator.cpp b/src/Simulator.cpp index a78f6f8..555681b 100644 --- a/src/Simulator.cpp +++ b/src/Simulator.cpp @@ -20,23 +20,27 @@ SC_MODULE(Top) { //Initiator *initiator; CPU *cpu; - Memory *memory; + Memory *InstrMemory; + Memory *DataMemory; sc_signal IRQ; SC_CTOR(Top) { cpu = new CPU("cpu"); - memory = new Memory("memory", filename); + InstrMemory = new Memory("InstrMemory", filename); + DataMemory = new Memory("Datamemory", false); - cpu->instr_bus.bind(memory->socket); + cpu->instr_bus.bind(InstrMemory->socket); + cpu->exec->data_bus.bind(DataMemory->socket); //cpu->interrupt.bind(IRQ); } ~Top() { cout << "Top destructor" << endl; delete cpu; - delete memory; + delete InstrMemory; + delete DataMemory; } };