changed IRQ line to TLM socket
This commit is contained in:
parent
0c25abdb00
commit
098aebc15d
33
inc/CPU.h
33
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<CPU> instr_bus;
|
||||
|
||||
//tlm_utils::simple_initiator_socket<cpu_base> data_bus;
|
||||
|
||||
sc_in<bool> interrupt;
|
||||
/**
|
||||
* @brief IRQ line socket
|
||||
* @param trans transction to perform (empty)
|
||||
* @param delay time to annotate
|
||||
*/
|
||||
tlm_utils::simple_target_socket<CPU> 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
|
||||
|
|
|
@ -34,7 +34,9 @@ class Timer: sc_module {
|
|||
public:
|
||||
// TLM-2 socket, defaults to 32-bits wide, base protocol
|
||||
tlm_utils::simple_target_socket<Timer> socket;
|
||||
sc_out<bool> timer_irq;
|
||||
|
||||
tlm_utils::simple_initiator_socket<Timer> irq_line;
|
||||
//sc_out<bool> timer_irq;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
14
src/CPU.cpp
14
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;
|
||||
}
|
||||
|
|
|
@ -40,12 +40,15 @@ SC_MODULE(Simulator)
|
|||
BusCtrl* Bus;
|
||||
Trace *trace;
|
||||
Timer *timer;
|
||||
Log *log;
|
||||
|
||||
uint32_t start_PC;
|
||||
sc_signal<bool> 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() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue