diff --git a/inc/CPU.h b/inc/CPU.h index ef329d6..66a6541 100644 --- a/inc/CPU.h +++ b/inc/CPU.h @@ -34,13 +34,30 @@ using namespace std; class CPU: sc_module { public: + /** + * @brief Instruction Memory bus socket + * @param trans transction to perfoem + * @param delay time to annotate + */ tlm_utils::simple_initiator_socket instr_bus; - //tlm_utils::simple_initiator_socket data_bus; - - sc_in interrupt; + /** + * @brief IRQ line socket + * @param trans transction to perform (empty) + * @param delay time to annotate + */ + tlm_utils::simple_target_socket irq_line_socket; + /** + * @brief Constructor + * @param name Module name + * @param PC Program Counter initialize value + */ CPU(sc_module_name name, uint32_t PC); + + /** + * @brief Destructor + */ ~CPU(); Execute *exec; @@ -50,12 +67,15 @@ private: Performance *perf; Log *log; + bool interrupt; + /** * * @brief Process and triggers IRQ if all conditions memory_socket * @return true if IRQ is triggered, false otherwise */ bool cpu_process_IRQ(); + /** * @brief Executes default ISA instruction * @param inst instruction to execute @@ -70,6 +90,13 @@ private: bool process_a_instruction(Instruction inst); void CPU_thread(void); + + /** + * @brief callback for IRQ simple socket + * @param trans transaction to perform (empty) + * @param delay time to annotate + */ + void call_interrupt(tlm::tlm_generic_payload &trans, sc_time &delay); }; #endif diff --git a/inc/Timer.h b/inc/Timer.h index 7f3de2f..25ce2f5 100644 --- a/inc/Timer.h +++ b/inc/Timer.h @@ -34,7 +34,9 @@ class Timer: sc_module { public: // TLM-2 socket, defaults to 32-bits wide, base protocol tlm_utils::simple_target_socket socket; - sc_out timer_irq; + + tlm_utils::simple_initiator_socket irq_line; + //sc_out timer_irq; /** * diff --git a/src/CPU.cpp b/src/CPU.cpp index 49c61c3..d000db9 100644 --- a/src/CPU.cpp +++ b/src/CPU.cpp @@ -10,6 +10,13 @@ CPU::CPU(sc_module_name name, uint32_t PC): sc_module(name) 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, &CPU::call_interrupt); + interrupt = false; + SC_THREAD(CPU_thread); } @@ -33,7 +40,7 @@ bool CPU::cpu_process_IRQ() { csr_temp |= (1 << 11); // MEIP bit in MIP register (11th bit) register_bank->setCSR(CSR_MIP, csr_temp); // cout << "time: " << sc_time_stamp() << ". CPU: interrupt" << endl; - log->SC_log(Log::INFO) << "Interrupt!" << endl; + log->SC_log(Log::DEBUG) << "Interrupt!" << endl; /* updated MEPC register */ old_pc = register_bank->getPC(); @@ -50,6 +57,7 @@ bool CPU::cpu_process_IRQ() { register_bank->setPC(new_pc); ret_value = true; + interrupt = false; } } else { csr_temp = register_bank->getCSR(CSR_MIP); @@ -500,3 +508,7 @@ void CPU::CPU_thread(void) { } // while(1) } // CPU_thread + +void CPU::call_interrupt(tlm::tlm_generic_payload &trans, sc_time &delay) { + interrupt = true; +} diff --git a/src/Simulator.cpp b/src/Simulator.cpp index c20b278..bd5dc9d 100644 --- a/src/Simulator.cpp +++ b/src/Simulator.cpp @@ -40,12 +40,15 @@ SC_MODULE(Simulator) BusCtrl* Bus; Trace *trace; Timer *timer; + Log *log; uint32_t start_PC; - sc_signal IRQ; SC_CTOR(Simulator) { + log = Log::getInstance(); + log->setLogLevel(Log::ERROR); + MainMemory = new Memory("Main_Memory", filename); start_PC = MainMemory->getPCfromHEX(); @@ -61,8 +64,10 @@ SC_MODULE(Simulator) Bus->memory_socket.bind(MainMemory->socket); Bus->trace_socket.bind(trace->socket); Bus->timer_socket.bind(timer->socket); - timer->timer_irq.bind(IRQ); - cpu->interrupt.bind(IRQ); + + //timer->timer_irq.bind(IRQ); + // cpu->interrupt.bind(IRQ); + timer->irq_line.bind(cpu->irq_line_socket); } ~Simulator() { diff --git a/src/Timer.cpp b/src/Timer.cpp index 60f528f..53c0afa 100644 --- a/src/Timer.cpp +++ b/src/Timer.cpp @@ -10,19 +10,22 @@ Timer::Timer(sc_module_name name): sc_module(name) } void Timer::run() { + + tlm::tlm_generic_payload* irq_trans = new tlm::tlm_generic_payload; + sc_time delay = SC_ZERO_TIME; + + irq_trans->set_command(tlm::TLM_WRITE_COMMAND); + irq_trans->set_data_ptr(NULL); + irq_trans->set_data_length(0); + irq_trans->set_streaming_width(0); + irq_trans->set_byte_enable_ptr(0); + irq_trans->set_dmi_allowed(false); + irq_trans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); + irq_trans->set_address( 0x01); + while(true) { - wait(timer_event); - - if (timer_irq.read() == true) { - timer_irq.write(false); - // cout << "time: " << sc_time_stamp() <<". bla bla " << endl; - } else { - timer_irq.write(true); - cout << "time: " << sc_time_stamp() << ". Timer interrupt!" << endl; - // notify in 20 ns to low irq signal - timer_event.notify( sc_time(20, SC_NS)); - } + irq_line->b_transport(*irq_trans, delay); } } @@ -30,12 +33,13 @@ void Timer::b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ) { tlm::tlm_command cmd = trans.get_command(); sc_dt::uint64 addr = trans.get_address(); unsigned char* ptr = trans.get_data_ptr(); - uint32_t aux_value = 0; - uint64_t notify_time = 0; unsigned int len = trans.get_data_length(); //unsigned char* byt = trans.get_byte_enable_ptr(); //unsigned int wid = trans.get_streaming_width(); + uint32_t aux_value = 0; + uint64_t notify_time = 0; + // cout << "accessing TIMER 0x" << hex << addr << endl; if (cmd == tlm::TLM_WRITE_COMMAND) { memcpy(&aux_value, ptr, len); @@ -48,12 +52,14 @@ void Timer::b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ) { break; case TIMERCMP_MEMORY_ADDRESS_LO: m_mtimecmp.range(31,0) = aux_value; - // timer_event.notify(SC_ZERO_TIME); break; case TIMERCMP_MEMORY_ADDRESS_HI: m_mtimecmp.range(63,32) = aux_value; + // notify needs relative time, mtimecmp works in absolute time notify_time = m_mtimecmp - m_mtime; + // cout << "time: " << sc_time_stamp() << ". Timer: IRQ will be at " + // << dec << notify_time + m_mtime << " ns." << endl; timer_event.notify( sc_time(notify_time, SC_NS) ); break; }