DMI access added (if available)

This commit is contained in:
mariusmonton 2019-03-28 22:52:36 +01:00
parent 24a27f39fe
commit d42d67b991
6 changed files with 516 additions and 472 deletions

View File

@ -86,6 +86,9 @@ public:
private: private:
Log *log; Log *log;
bool instr_direct_mem_ptr(tlm::tlm_generic_payload&, tlm::tlm_dmi& dmi_data);
void invalidate_direct_mem_ptr(sc_dt::uint64 start, sc_dt::uint64 end);
}; };
#endif #endif

View File

@ -70,6 +70,9 @@ private:
bool interrupt; bool interrupt;
uint32_t int_cause; uint32_t int_cause;
bool irq_already_down; bool irq_already_down;
bool dmi_ptr_valid;
/** /**
* *
* @brief Process and triggers IRQ if all conditions met * @brief Process and triggers IRQ if all conditions met
@ -100,6 +103,8 @@ private:
* When called it triggers an IRQ * When called it triggers an IRQ
*/ */
void call_interrupt(tlm::tlm_generic_payload &trans, sc_time &delay); void call_interrupt(tlm::tlm_generic_payload &trans, sc_time &delay);
void invalidate_direct_mem_ptr(sc_dt::uint64 start, sc_dt::uint64 end);
}; };
#endif #endif

View File

@ -10,6 +10,8 @@ BusCtrl::BusCtrl(sc_module_name name): sc_module(name)
cpu_instr_socket.register_b_transport(this, &BusCtrl::b_transport); cpu_instr_socket.register_b_transport(this, &BusCtrl::b_transport);
cpu_data_socket.register_b_transport(this, &BusCtrl::b_transport); cpu_data_socket.register_b_transport(this, &BusCtrl::b_transport);
log = Log::getInstance(); log = Log::getInstance();
cpu_instr_socket.register_get_direct_mem_ptr(this, &BusCtrl::instr_direct_mem_ptr);
memory_socket.register_invalidate_direct_mem_ptr( this, &BusCtrl::invalidate_direct_mem_ptr);
} }
@ -42,3 +44,12 @@ void BusCtrl::b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ) {
trans.set_response_status( tlm::TLM_OK_RESPONSE ); trans.set_response_status( tlm::TLM_OK_RESPONSE );
} }
bool BusCtrl::instr_direct_mem_ptr(tlm::tlm_generic_payload& gp, tlm::tlm_dmi& dmi_data) {
return memory_socket->get_direct_mem_ptr(gp, dmi_data);
}
void BusCtrl::invalidate_direct_mem_ptr(sc_dt::uint64 start, sc_dt::uint64 end) {
cpu_instr_socket->invalidate_direct_mem_ptr(start, end);
}

View File

@ -1,9 +1,8 @@
#include "CPU.h" #include "CPU.h"
SC_HAS_PROCESS(CPU); SC_HAS_PROCESS(CPU);
CPU::CPU(sc_module_name name, uint32_t PC): sc_module(name) CPU::CPU(sc_module_name name, uint32_t PC) :
, instr_bus("instr_bus") sc_module(name), instr_bus("instr_bus") {
{
register_bank = new Registers(); register_bank = new Registers();
exec = new Execute("Execute", register_bank); exec = new Execute("Execute", register_bank);
perf = Performance::getInstance(); perf = Performance::getInstance();
@ -20,6 +19,9 @@ CPU::CPU(sc_module_name name, uint32_t PC): sc_module(name)
int_cause = 0; int_cause = 0;
irq_already_down = false; irq_already_down = false;
dmi_ptr_valid = false;
instr_bus.register_invalidate_direct_mem_ptr( this, &CPU::invalidate_direct_mem_ptr);
SC_THREAD(CPU_thread); SC_THREAD(CPU_thread);
} }
@ -54,7 +56,8 @@ bool CPU::cpu_process_IRQ() {
/* updated MEPC register */ /* updated MEPC register */
old_pc = register_bank->getPC(); old_pc = register_bank->getPC();
register_bank->setCSR(CSR_MEPC, old_pc); register_bank->setCSR(CSR_MEPC, old_pc);
log->SC_log(Log::INFO) << "Old PC Value 0x" << hex << old_pc << endl; log->SC_log(Log::INFO) << "Old PC Value 0x" << hex << old_pc
<< endl;
/* update MCAUSE register */ /* update MCAUSE register */
register_bank->setCSR(CSR_MCAUSE, 0x80000000); register_bank->setCSR(CSR_MCAUSE, 0x80000000);
@ -62,7 +65,8 @@ bool CPU::cpu_process_IRQ() {
/* set new PC address */ /* set new PC address */
new_pc = register_bank->getCSR(CSR_MTVEC); new_pc = register_bank->getCSR(CSR_MTVEC);
//new_pc = new_pc & 0xFFFFFFFC; // last two bits always to 0 //new_pc = new_pc & 0xFFFFFFFC; // last two bits always to 0
log->SC_log(Log::DEBUG) << "NEW PC Value 0x" << hex << new_pc << endl; log->SC_log(Log::DEBUG) << "NEW PC Value 0x" << hex << new_pc
<< endl;
register_bank->setPC(new_pc); register_bank->setPC(new_pc);
ret_value = true; ret_value = true;
@ -217,7 +221,6 @@ bool CPU::process_m_instruction(Instruction &inst) {
return PC_not_affected; return PC_not_affected;
} }
bool CPU::process_a_instruction(Instruction inst) { bool CPU::process_a_instruction(Instruction inst) {
bool PC_not_affected = true; bool PC_not_affected = true;
@ -454,6 +457,8 @@ void CPU::CPU_thread(void) {
sc_time delay = SC_ZERO_TIME; sc_time delay = SC_ZERO_TIME;
bool PC_not_affected = false; bool PC_not_affected = false;
bool incPCby2 = false; bool incPCby2 = false;
tlm::tlm_dmi dmi_data;
unsigned char* dmi_ptr = NULL;
trans->set_command(tlm::TLM_READ_COMMAND); trans->set_command(tlm::TLM_READ_COMMAND);
trans->set_data_ptr(reinterpret_cast<unsigned char*>(&INSTR)); trans->set_data_ptr(reinterpret_cast<unsigned char*>(&INSTR));
@ -463,21 +468,39 @@ void CPU::CPU_thread(void) {
trans->set_dmi_allowed(false); // Mandatory initial value trans->set_dmi_allowed(false); // Mandatory initial value
trans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); trans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
//if (trans->is_dmi_allowed() ) {
// if (true) {
// dmi_ptr_valid = instr_bus->get_direct_mem_ptr(*trans, dmi_data);
// dmi_ptr = dmi_data.get_dmi_ptr();
// }
//register_bank->dump(); //register_bank->dump();
while (1) { while (1) {
/* Get new PC value */ /* Get new PC value */
//cout << "CPU: PC 0x" << hex << (uint32_t) register_bank->getPC() << endl; //cout << "CPU: PC 0x" << hex << (uint32_t) register_bank->getPC() << endl;
//dmi_ptr_valid = true;
if (dmi_ptr_valid == true) {
/* if memory_offset at Memory module is set, this won't work */
memcpy(&INSTR, dmi_ptr + register_bank->getPC(), 4);
} else {
cout << "No DMI access" << endl;
trans->set_address(register_bank->getPC()); trans->set_address(register_bank->getPC());
instr_bus->b_transport(*trans, delay); instr_bus->b_transport(*trans, delay);
perf->codeMemoryRead();
if (trans->is_response_error()) { if (trans->is_response_error()) {
SC_REPORT_ERROR("CPU base", "Read memory"); SC_REPORT_ERROR("CPU base", "Read memory");
} else { }
log->SC_log(Log::INFO) << "PC: 0x" << hex
<< register_bank->getPC() << ". "; dmi_ptr_valid = instr_bus->get_direct_mem_ptr(*trans, dmi_data);
if (dmi_ptr_valid) {
dmi_ptr = dmi_data.get_dmi_ptr();
}
}
perf->codeMemoryRead();
log->SC_log(Log::INFO) << "PC: 0x" << hex << register_bank->getPC()
<< ". ";
Instruction inst(INSTR); Instruction inst(INSTR);
@ -504,7 +527,6 @@ void CPU::CPU_thread(void) {
inst.dump(); inst.dump();
exec->NOP(inst); exec->NOP(inst);
} // switch (inst.check_extension()) } // switch (inst.check_extension())
}
perf->instructionsInc(); perf->instructionsInc();
@ -520,9 +542,13 @@ void CPU::CPU_thread(void) {
} // while(1) } // while(1)
} // CPU_thread } // CPU_thread
void CPU::call_interrupt(tlm::tlm_generic_payload &trans, sc_time &delay) { void CPU::call_interrupt(tlm::tlm_generic_payload &trans, sc_time &delay) {
interrupt = true; interrupt = true;
/* Socket caller send a cause (its id) */ /* Socket caller send a cause (its id) */
memcpy(&int_cause, trans.get_data_ptr(), sizeof(int)); memcpy(&int_cause, trans.get_data_ptr(), sizeof(int));
} }
void CPU::invalidate_direct_mem_ptr(sc_dt::uint64 start, sc_dt::uint64 end)
{
dmi_ptr_valid = false;
}

View File

@ -26,7 +26,8 @@ Memory::Memory(sc_module_name name, bool use_file): sc_module(name)
socket.register_b_transport( this, &Memory::b_transport); socket.register_b_transport( this, &Memory::b_transport);
socket.register_get_direct_mem_ptr(this, &Memory::get_direct_mem_ptr); socket.register_get_direct_mem_ptr(this, &Memory::get_direct_mem_ptr);
socket.register_transport_dbg( this, &Memory::transport_dbg); socket.register_transport_dbg( this, &Memory::transport_dbg);
memory_offset = 0;
program_counter = 0;
//memset(mem, 0, SIZE*sizeof(uint8_t)); //memset(mem, 0, SIZE*sizeof(uint8_t));
} }
@ -82,7 +83,11 @@ void Memory::b_transport( tlm::tlm_generic_payload& trans, sc_time& delay )
// Set DMI hint to indicated that DMI is supported // Set DMI hint to indicated that DMI is supported
// ********************************************* // *********************************************
if (memory_offset == 0) {
trans.set_dmi_allowed(true); trans.set_dmi_allowed(true);
} else {
trans.set_dmi_allowed(false);
}
// Obliged to set response status to indicate successful completion // Obliged to set response status to indicate successful completion
trans.set_response_status( tlm::TLM_OK_RESPONSE ); trans.set_response_status( tlm::TLM_OK_RESPONSE );
@ -157,14 +162,12 @@ void Memory::readHexFile(string filename) {
cout << "03 PC set to 0x" << hex << program_counter << endl; cout << "03 PC set to 0x" << hex << program_counter << endl;
} else if (line.substr(7,2) == "04") { } else if (line.substr(7,2) == "04") {
/* Start segment address */ /* Start segment address */
//extended_address = stol(line.substr(9,4), nullptr, 16) << 16;
memory_offset = stol(line.substr(9,4), nullptr, 16) << 16; memory_offset = stol(line.substr(9,4), nullptr, 16) << 16;
extended_address = 0; extended_address = 0;
cout << "04 address set to 0x" << hex << extended_address << endl; cout << "04 address set to 0x" << hex << extended_address << endl;
cout << "04 offset set to 0x" << hex << memory_offset << endl; cout << "04 offset set to 0x" << hex << memory_offset << endl;
} else if (line.substr(7,2) == "05") { } else if (line.substr(7,2) == "05") {
program_counter = stol(line.substr(9,8), nullptr, 16); program_counter = stol(line.substr(9,8), nullptr, 16);
//program_counter = 0;
cout << "05 PC set to 0x" << hex << program_counter << endl; cout << "05 PC set to 0x" << hex << program_counter << endl;
} }
} }

View File

@ -41,14 +41,11 @@ SC_MODULE(Simulator)
BusCtrl* Bus; BusCtrl* Bus;
Trace *trace; Trace *trace;
Timer *timer; Timer *timer;
// Log *log;
uint32_t start_PC; uint32_t start_PC;
SC_CTOR(Simulator) SC_CTOR(Simulator)
{ {
// log = Log::getInstance();
MainMemory = new Memory("Main_Memory", filename); MainMemory = new Memory("Main_Memory", filename);
start_PC = MainMemory->getPCfromHEX(); start_PC = MainMemory->getPCfromHEX();
@ -127,16 +124,15 @@ void process_arguments(int argc, char* argv[]) {
break; break;
} }
} }
if (filename.empty()) { if (filename.empty()) {
filename = std::string(argv[optind]); filename = std::string(argv[optind]);
} }
} }
int sc_main(int argc, char* argv[]) int sc_main(int argc, char* argv[])
{ {
/* Capture Ctrl+C and finish the simulation */ /* Capture Ctrl+C and finish the simulation */
signal(SIGINT, intHandler); signal(SIGINT, intHandler);