I have a platform for native simulation, composed with sc_main.cpp, native_wrapper.cpp, native_wrapper.h, hardware.... I have to implement another CPU but I didn't find a method to make this.
Because extern "C" is needed since the software is compiled in C and is linked against native_wrapper.cpp, which is compiled in C++, for this, we call methods of soft in a this manner, using “NativeWrapper::get_instance()->method_name()”
below you can see code of sc_main.cpp, native_wrapper.cpp and native_wrapper.h. Thanks for your help
code for native_wrapper.h
#include "ensitlm.h" #include "native_wrapper.h" /* extern "C" is needed since the software is compiled in C and * is linked against native_wrapper.cpp, which is compiled in C++. */ extern "C" int __start(); extern "C" void __interrupt(); extern "C" void write_mem(uint32_t addr, uint32_t data) { //abort(); // TODO NativeWrapper::get_instance()->write_mem(addr, data); } extern "C" unsigned int read_mem(uint32_t addr) { //abort(); // TODO return NativeWrapper::get_instance()->read_mem(addr); } extern "C" void cpu_relax() { //abort(); // TODO NativeWrapper::get_instance()->cpu_relax(); } extern "C" void wait_for_irq() { //abort(); // TODO NativeWrapper::get_instance()->wait_for_irq(); } NativeWrapper * NativeWrapper::get_instance() { static NativeWrapper * instance = NULL; if (!instance) instance = new NativeWrapper("native_wrapper"); return instance; } NativeWrapper::NativeWrapper(sc_core::sc_module_name name) : sc_module(name), irq("irq") { SC_THREAD(compute); SC_METHOD(interrupt_handler_internal); sensitive << irq ; dont_initialize(); } void NativeWrapper::write_mem(unsigned int addr, unsigned int data) { tlm::tlm_response_status stat = socket.write(addr, data); } unsigned int NativeWrapper::read_mem(unsigned int addr) { //abort(); // TODO uint32_t localbuf; tlm::tlm_response_status stat = socket.read(addr,localbuf); return localbuf; } void NativeWrapper::cpu_relax() { //abort(); // TODO wait(1000, sc_core::SC_MS); /* temps arbitraire */ } void NativeWrapper::wait_for_irq() { if (!interrupt) wait(interrupt_event); interrupt = false; } void NativeWrapper::compute() { //abort(); // TODO __start(); } void NativeWrapper::interrupt_handler_internal() { interrupt = true; interrupt_event.notify(); __interrupt(); }
and native_wrapper.h :
#ifndef NATIVEWRAPPER_H #define NATIVEWRAPPER_H #ifndef ENSITLM_H #error Please include file "ensitlm.h" #endif SC_MODULE(NativeWrapper) { ensitlm::initiator_socket<NativeWrapper> socket; sc_core::sc_in<bool> irq; private: SC_CTOR(NativeWrapper); public: /* We use a singleton here. This is a limitation since it doesn't allow multiple NativeWrapper instances (multiple CPU in the platform), but it considerably reduces the complexity of Makefiles, hal.h, ... */ static NativeWrapper * get_instance(); void write_mem(unsigned int addr, unsigned int data); unsigned int read_mem(unsigned int addr); void cpu_relax(); void wait_for_irq(); void compute(); void interrupt_handler_internal(); bool interrupt; sc_core::sc_event interrupt_event; }; #endif
sc_main.cpp
#include "ensitlm.h" #include "native_wrapper.h" #include "memory.h" #include "bus.h" #include "timer.h" #include "vga.h" #include "intc.h" #include "gpio.h" int sc_main(int, char**) { NativeWrapper& cpu = *NativeWrapper::get_instance(); Memory memory("Memory", 0x00100000); Bus bus("bus"); TIMER timer("timer", sc_core::sc_time(20, sc_core::SC_NS)); Vga vga("vga"); Intc intc("intc"); Gpio gpio("gpio"); ......