2018-09-21 17:23:31 +08:00
|
|
|
/*!
|
2020-06-02 19:08:38 +08:00
|
|
|
\file Simulator.cpp
|
|
|
|
\brief Top level simulation entity
|
|
|
|
\author Màrius Montón
|
|
|
|
\date September 2018
|
|
|
|
*/
|
2018-09-21 17:23:31 +08:00
|
|
|
|
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"
|
2018-09-20 05:44:38 +08:00
|
|
|
#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
|
|
|
|
2020-06-02 19:08:38 +08:00
|
|
|
std::string filename;
|
2018-09-11 00:44:54 +08:00
|
|
|
|
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
|
|
|
|
*/
|
2020-06-02 19:08:38 +08:00
|
|
|
SC_MODULE(Simulator) {
|
|
|
|
CPU *cpu;
|
|
|
|
Memory *MainMemory;
|
|
|
|
BusCtrl *Bus;
|
|
|
|
Trace *trace;
|
|
|
|
Timer *timer;
|
|
|
|
|
2021-01-15 22:51:03 +08:00
|
|
|
|
2020-06-02 19:08:38 +08:00
|
|
|
|
|
|
|
SC_CTOR(Simulator) {
|
2021-01-15 22:51:03 +08:00
|
|
|
uint32_t start_PC;
|
|
|
|
|
2020-06-02 19:08:38 +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");
|
|
|
|
timer = new Timer("Timer");
|
|
|
|
|
|
|
|
cpu->instr_bus.bind(Bus->cpu_instr_socket);
|
|
|
|
cpu->mem_intf->data_bus.bind(Bus->cpu_data_socket);
|
|
|
|
|
|
|
|
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->irq_line.bind(cpu->irq_line_socket);
|
|
|
|
}
|
|
|
|
|
|
|
|
~Simulator() {
|
|
|
|
delete MainMemory;
|
|
|
|
delete cpu;
|
|
|
|
delete Bus;
|
|
|
|
delete trace;
|
|
|
|
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) {
|
2020-06-02 19:08:38 +08:00
|
|
|
delete top;
|
2021-01-15 22:51:03 +08:00
|
|
|
(void) dummy;
|
2020-06-02 19:08:38 +08:00
|
|
|
//sc_stop();
|
|
|
|
exit(-1);
|
2018-09-11 00:44:54 +08:00
|
|
|
}
|
|
|
|
|
2020-06-02 19:08:38 +08:00
|
|
|
void process_arguments(int argc, char *argv[]) {
|
2019-02-12 21:08:40 +08:00
|
|
|
|
|
|
|
int c;
|
|
|
|
int debug_level;
|
|
|
|
Log *log;
|
|
|
|
|
|
|
|
log = Log::getInstance();
|
|
|
|
log->setLogLevel(Log::ERROR);
|
2020-06-02 19:08:38 +08:00
|
|
|
while ((c = getopt(argc, argv, "D:f:?")) != -1) {
|
2019-02-12 21:08:40 +08:00
|
|
|
switch (c) {
|
2020-06-02 19:08:38 +08:00
|
|
|
case 'D':
|
|
|
|
debug_level = atoi(optarg);
|
|
|
|
|
|
|
|
switch (debug_level) {
|
|
|
|
case 3:
|
|
|
|
log->setLogLevel(Log::INFO);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
log->setLogLevel(Log::WARNING);
|
2019-02-12 21:08:40 +08:00
|
|
|
break;
|
2020-06-02 19:08:38 +08:00
|
|
|
case 1:
|
|
|
|
log->setLogLevel(Log::DEBUG);
|
2019-02-12 21:08:40 +08:00
|
|
|
break;
|
2020-06-02 19:08:38 +08:00
|
|
|
case 0:
|
|
|
|
log->setLogLevel(Log::ERROR);
|
2019-02-12 21:08:40 +08:00
|
|
|
break;
|
2020-06-02 19:08:38 +08:00
|
|
|
default:
|
|
|
|
log->setLogLevel(Log::INFO);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
filename = std::string(optarg);
|
|
|
|
break;
|
|
|
|
case '?':
|
|
|
|
std::cout << "Call ./RISCV_TLM -D <debuglevel> (0..3) filename.hex"
|
|
|
|
<< std::endl;
|
|
|
|
break;
|
2019-02-12 21:08:40 +08:00
|
|
|
}
|
|
|
|
}
|
2019-03-29 05:52:36 +08:00
|
|
|
|
2019-02-12 21:08:40 +08:00
|
|
|
if (filename.empty()) {
|
|
|
|
filename = std::string(argv[optind]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-02 19:08:38 +08:00
|
|
|
int sc_main(int argc, char *argv[]) {
|
|
|
|
|
|
|
|
/* Capture Ctrl+C and finish the simulation */
|
|
|
|
signal(SIGINT, intHandler);
|
|
|
|
|
|
|
|
/* SystemC time resolution set to 1 ns*/
|
|
|
|
sc_core::sc_set_time_resolution(1, sc_core::SC_NS);
|
|
|
|
|
|
|
|
/* Parse and process program arguments. -f is mandatory */
|
|
|
|
process_arguments(argc, argv);
|
2018-09-11 00:44:54 +08:00
|
|
|
|
2020-06-02 19:08:38 +08:00
|
|
|
top = new Simulator("top");
|
|
|
|
sc_core::sc_start();
|
2018-09-11 00:44:54 +08:00
|
|
|
|
2020-06-02 19:08:38 +08:00
|
|
|
std::cout << "Press Enter to finish" << std::endl;
|
|
|
|
std::cin.ignore();
|
2018-11-25 19:07:08 +08:00
|
|
|
|
2020-06-02 19:08:38 +08:00
|
|
|
// call all destructors, clean exit.
|
|
|
|
delete top;
|
2018-09-11 00:44:54 +08:00
|
|
|
|
2020-06-02 19:08:38 +08:00
|
|
|
return 0;
|
2018-09-11 00:44:54 +08:00
|
|
|
}
|