Added Data Memory bus. Implemented LW & SW instructions.
This commit is contained in:
		
							parent
							
								
									c5ec56ec08
								
							
						
					
					
						commit
						1c9bfe8c60
					
				|  | @ -0,0 +1,6 @@ | |||
| li t1, 150 | ||||
| li t2, 300 | ||||
| li t3, -250 | ||||
| sw t1, -4(t2) | ||||
| li t1, 500 | ||||
| lw t1, -4(t2) | ||||
|  | @ -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; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 ); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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<RISC_V_execute> 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; | ||||
|  |  | |||
							
								
								
									
										10
									
								
								src/CPU.cpp
								
								
								
								
							
							
						
						
									
										10
									
								
								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; | ||||
|  |  | |||
|  | @ -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) { | ||||
|  |  | |||
|  | @ -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 ) | ||||
| { | ||||
|  |  | |||
|  | @ -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 <<mem_addr << dec << ") -> 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 <<mem_addr << dec << ")" <<  endl; | ||||
| } | ||||
| 
 | ||||
| void RISC_V_execute::ADDI(Instruction &inst) { | ||||
|  | @ -581,12 +606,41 @@ void RISC_V_execute::NOP(Instruction &inst) { | |||
|  * @param  addr address to access to | ||||
|  * @return      data value read | ||||
|  */ | ||||
| uint32_t RISC_V_execute::readDataMem(uint32_t addr) { | ||||
|   // tlm::tlm_generic_payload* trans = new tlm::tlm_generic_payload;
 | ||||
|   // sc_time delay = SC_ZERO_TIME;
 | ||||
| uint32_t RISC_V_execute::readDataMem(uint32_t addr, int size) { | ||||
|   uint32_t data; | ||||
|   tlm::tlm_generic_payload trans; | ||||
|   sc_time delay = SC_ZERO_TIME; | ||||
| 
 | ||||
| //  data_bus->b_transport(*trans, delay);
 | ||||
|   trans.set_command( tlm::TLM_READ_COMMAND ); | ||||
|   trans.set_data_ptr( reinterpret_cast<unsigned char*>(&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<unsigned char*>(&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; | ||||
| } | ||||
|  |  | |||
|  | @ -20,23 +20,27 @@ SC_MODULE(Top) | |||
| { | ||||
|   //Initiator *initiator;
 | ||||
|   CPU    *cpu; | ||||
|   Memory    *memory; | ||||
|   Memory    *InstrMemory; | ||||
|   Memory *DataMemory; | ||||
| 
 | ||||
|   sc_signal<bool> 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; | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue