risc-v-tlm/src/Simulator.cpp

149 lines
2.8 KiB
C++
Raw Normal View History

2018-09-21 17:23:31 +08:00
/*!
\file Simulator.cpp
\brief Top level simulation entity
\author Màrius Montón
\date September 2018
*/
2018-09-11 00:44:54 +08:00
#define SC_INCLUDE_DYNAMIC_PROCESSES
#include "systemc"
#include "tlm.h"
#include "tlm_utils/simple_initiator_socket.h"
#include "tlm_utils/simple_target_socket.h"
#include <signal.h>
2019-02-12 21:08:40 +08:00
#include <unistd.h>
2018-09-11 00:44:54 +08:00
#include "CPU.h"
#include "Memory.h"
#include "BusCtrl.h"
#include "Trace.h"
2019-01-13 08:30:49 +08:00
#include "Timer.h"
2018-09-11 00:44:54 +08:00
using namespace sc_core;
using namespace sc_dt;
using namespace std;
string filename;
2018-09-21 17:23:31 +08:00
/**
* @class Simulator
2019-02-12 21:08:40 +08:00
* This class instantiates all necessary modules, connects its ports and starts
2018-09-21 17:23:31 +08:00
* the simulation.
*
* @brief Top simulation entity
*/
SC_MODULE(Simulator)
2018-09-11 00:44:54 +08:00
{
CPU *cpu;
Memory *MainMemory;
BusCtrl* Bus;
Trace *trace;
2019-01-13 08:30:49 +08:00
Timer *timer;
2018-09-11 00:44:54 +08:00
uint32_t start_PC;
2018-09-11 00:44:54 +08:00
2018-09-21 17:23:31 +08:00
SC_CTOR(Simulator)
2018-09-11 00:44:54 +08:00
{
MainMemory = new Memory("Main_Memory", filename);
start_PC = MainMemory->getPCfromHEX();
cpu = new CPU("cpu", start_PC);
Bus = new BusCtrl("BusCtrl");
trace = new Trace("Trace");
2019-01-13 08:30:49 +08:00
timer = new Timer("Timer");
cpu->instr_bus.bind(Bus->cpu_instr_socket);
cpu->exec->data_bus.bind(Bus->cpu_data_socket);
2018-09-21 17:23:31 +08:00
Bus->memory_socket.bind(MainMemory->socket);
Bus->trace_socket.bind(trace->socket);
2019-01-13 08:30:49 +08:00
Bus->timer_socket.bind(timer->socket);
2019-01-22 19:43:05 +08:00
//timer->timer_irq.bind(IRQ);
// cpu->interrupt.bind(IRQ);
timer->irq_line.bind(cpu->irq_line_socket);
2018-09-11 00:44:54 +08:00
}
2018-09-21 17:23:31 +08:00
~Simulator() {
cout << "Simulator destructor" << endl;
2018-09-11 00:44:54 +08:00
delete cpu;
delete MainMemory;
delete Bus;
delete trace;
2019-01-13 08:30:49 +08:00
delete timer;
2018-09-11 00:44:54 +08:00
}
};
2018-09-21 17:23:31 +08:00
Simulator *top;
2018-09-11 00:44:54 +08:00
void intHandler(int dummy) {
delete top;
//sc_stop();
exit(-1);
}
2019-02-12 21:08:40 +08:00
void process_arguments(int argc, char* argv[]) {
int c;
int debug_level;
Log *log;
log = Log::getInstance();
log->setLogLevel(Log::ERROR);
while ((c = getopt (argc, argv, "D:f:?")) != -1) {
switch (c) {
case 'D':
debug_level = atoi(optarg);
switch (debug_level) {
case 3:
log->setLogLevel(Log::INFO);
break;
case 2:
log->setLogLevel(Log::WARNING);
break;
case 1:
log->setLogLevel(Log::DEBUG);
break;
case 0:
log->setLogLevel(Log::ERROR);
break;
default:
log->setLogLevel(Log::INFO);
break;
}
break;
case 'f' :
filename = std::string(optarg);
break;
case '?' :
std::cout << "Call ./RISCV_TLM -D <debuglevel> (0..4) filename.hex" << std::endl;
break;
}
}
2019-03-29 05:52:36 +08:00
2019-02-12 21:08:40 +08:00
if (filename.empty()) {
filename = std::string(argv[optind]);
}
}
2018-09-11 00:44:54 +08:00
int sc_main(int argc, char* argv[])
{
2019-01-13 08:30:49 +08:00
/* Capture Ctrl+C and finish the simulation */
2018-09-11 00:44:54 +08:00
signal(SIGINT, intHandler);
/* SystemC time resolution set to 1 ns*/
sc_set_time_resolution(1, SC_NS);
2019-02-12 21:08:40 +08:00
/* Parse and process program arguments. -f is mandatory */
process_arguments(argc, argv);
2018-09-11 00:44:54 +08:00
2018-09-21 17:23:31 +08:00
top = new Simulator("top");
2018-09-11 00:44:54 +08:00
sc_start();
return 0;
}