Prepare for debug
This commit is contained in:
parent
4c60d6ae75
commit
49103e5591
|
@ -336,7 +336,7 @@ public:
|
||||||
* @param inst instruction to execute
|
* @param inst instruction to execute
|
||||||
* @return true if PC is affected by instruction
|
* @return true if PC is affected by instruction
|
||||||
*/
|
*/
|
||||||
bool process_instruction(Instruction *inst);
|
bool process_instruction(Instruction *inst, bool *breakpoint = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Decodes opcode of instruction
|
* @brief Decodes opcode of instruction
|
||||||
|
|
|
@ -405,7 +405,7 @@ public:
|
||||||
bool Exec_C_JAL(int m_rd);
|
bool Exec_C_JAL(int m_rd);
|
||||||
bool Exec_C_EBREAK();
|
bool Exec_C_EBREAK();
|
||||||
|
|
||||||
bool process_instruction(Instruction *inst);
|
bool process_instruction(Instruction *inst, bool *breakpoint = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*!
|
||||||
|
\file Debug.h
|
||||||
|
\brief GDB connector
|
||||||
|
\author Màrius Montón
|
||||||
|
\date February 2021
|
||||||
|
*/
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#ifndef INC_DEBUG_H_
|
||||||
|
#define INC_DEBUG_H_
|
||||||
|
|
||||||
|
#define SC_INCLUDE_DYNAMIC_PROCESSES
|
||||||
|
|
||||||
|
#include "systemc"
|
||||||
|
|
||||||
|
#include "tlm.h"
|
||||||
|
#include "tlm_utils/simple_initiator_socket.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "CPU.h"
|
||||||
|
#include "Memory.h"
|
||||||
|
|
||||||
|
class Debug: sc_core::sc_module {
|
||||||
|
public:
|
||||||
|
|
||||||
|
Debug(sc_core::sc_module_name name, uint32_t PC, CPU *cpu, Memory* mem);
|
||||||
|
~Debug();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string compute_checksum_string(const std::string &msg);
|
||||||
|
void send_packet(int conn, const std::string &msg);
|
||||||
|
std::string receive_packet();
|
||||||
|
void handle_gdb_loop();
|
||||||
|
|
||||||
|
static constexpr size_t bufsize = 1024 * 8;
|
||||||
|
char iobuf[bufsize]{};
|
||||||
|
int conn;
|
||||||
|
CPU *dbg_cpu;
|
||||||
|
Memory *dbg_mem;
|
||||||
|
tlm::tlm_generic_payload dbg_trans;
|
||||||
|
unsigned char pyld_array[128];
|
||||||
|
std::unordered_set<uint32_t> breakpoints;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* INC_DEBUG_H_ */
|
|
@ -1160,9 +1160,10 @@ bool BASE_ISA::Exec_SFENCE() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BASE_ISA::process_instruction(Instruction *inst) {
|
bool BASE_ISA::process_instruction(Instruction *inst, bool *breakpoint) {
|
||||||
bool PC_not_affected = true;
|
bool PC_not_affected = true;
|
||||||
|
|
||||||
|
*breakpoint = false;
|
||||||
setInstr(inst->getInstr());
|
setInstr(inst->getInstr());
|
||||||
|
|
||||||
switch (decode()) {
|
switch (decode()) {
|
||||||
|
@ -1290,9 +1291,13 @@ bool BASE_ISA::process_instruction(Instruction *inst) {
|
||||||
break;
|
break;
|
||||||
case OP_ECALL:
|
case OP_ECALL:
|
||||||
Exec_ECALL();
|
Exec_ECALL();
|
||||||
|
*breakpoint = true;
|
||||||
|
std::cout << "ECALL" << std::endl;
|
||||||
break;
|
break;
|
||||||
case OP_EBREAK:
|
case OP_EBREAK:
|
||||||
Exec_EBREAK();
|
Exec_EBREAK();
|
||||||
|
*breakpoint = true;
|
||||||
|
std::cout << "EBREAK" << std::endl;
|
||||||
break;
|
break;
|
||||||
case OP_CSRRW:
|
case OP_CSRRW:
|
||||||
Exec_CSRRW();
|
Exec_CSRRW();
|
||||||
|
|
|
@ -680,9 +680,11 @@ bool C_extension::Exec_C_EBREAK() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool C_extension::process_instruction(Instruction *inst) {
|
bool C_extension::process_instruction(Instruction *inst, bool *breakpoint) {
|
||||||
bool PC_not_affected = true;
|
bool PC_not_affected = true;
|
||||||
|
|
||||||
|
*breakpoint = false;
|
||||||
|
|
||||||
setInstr(inst->getInstr());
|
setInstr(inst->getInstr());
|
||||||
|
|
||||||
switch (decode()) {
|
switch (decode()) {
|
||||||
|
@ -766,6 +768,8 @@ bool C_extension::process_instruction(Instruction *inst) {
|
||||||
break;
|
break;
|
||||||
case OP_C_EBREAK:
|
case OP_C_EBREAK:
|
||||||
Exec_C_EBREAK();
|
Exec_C_EBREAK();
|
||||||
|
std::cout << "C_EBREAK" << std::endl;
|
||||||
|
*breakpoint = true;
|
||||||
break;
|
break;
|
||||||
[[unlikely]] default:
|
[[unlikely]] default:
|
||||||
std::cout << "C instruction not implemented yet" << "\n";
|
std::cout << "C instruction not implemented yet" << "\n";
|
||||||
|
|
|
@ -0,0 +1,310 @@
|
||||||
|
/*!
|
||||||
|
\file Debug.cpp
|
||||||
|
\brief GDB connector
|
||||||
|
\author Màrius Montón
|
||||||
|
\date February 2021
|
||||||
|
*/
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
|
#include "Debug.h"
|
||||||
|
|
||||||
|
constexpr char nibble_to_hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
|
||||||
|
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||||
|
|
||||||
|
Debug::Debug(sc_core::sc_module_name name, uint32_t PC, CPU *cpu, Memory* mem) {
|
||||||
|
|
||||||
|
std::cout << "Debug constructor\n";
|
||||||
|
|
||||||
|
dbg_cpu = cpu;
|
||||||
|
dbg_mem = mem;
|
||||||
|
|
||||||
|
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
int optval = 1;
|
||||||
|
int ans = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval,
|
||||||
|
sizeof(optval));
|
||||||
|
|
||||||
|
sockaddr_in addr;
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
addr.sin_port = htons(1234);
|
||||||
|
|
||||||
|
ans = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
|
||||||
|
|
||||||
|
ans = listen(sock, 1);
|
||||||
|
|
||||||
|
socklen_t len = sizeof(addr);
|
||||||
|
conn = accept(sock, (struct sockaddr *) &addr, &len);
|
||||||
|
|
||||||
|
handle_gdb_loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug::~Debug() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Debug::send_packet(int conn, const std::string &msg) {
|
||||||
|
std::string frame = "+$" + msg + "#" + compute_checksum_string(msg);
|
||||||
|
|
||||||
|
memcpy(iobuf, frame.c_str(), frame.size());
|
||||||
|
|
||||||
|
int nbytes = ::send(conn, iobuf, frame.size(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Debug::receive_packet() {
|
||||||
|
int nbytes = ::recv(conn, iobuf, bufsize, 0);
|
||||||
|
|
||||||
|
if (nbytes == 0) {
|
||||||
|
return "";
|
||||||
|
} else if (nbytes == 1) {
|
||||||
|
return std::string("+");
|
||||||
|
} else {
|
||||||
|
// 1) find $
|
||||||
|
// 2) find #
|
||||||
|
// 3) assert that two chars follow #
|
||||||
|
|
||||||
|
char *start = strchr(iobuf, '$');
|
||||||
|
char *end = strchr(iobuf, '#');
|
||||||
|
|
||||||
|
std::string message(start + 1, end - (start + 1));
|
||||||
|
|
||||||
|
{
|
||||||
|
//std::string local_checksum = compute_checksum_string(message);
|
||||||
|
//std::string recv_checksum(end + 1, 2);
|
||||||
|
//assert(local_checksum == recv_checksum);
|
||||||
|
}
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Debug::handle_gdb_loop() {
|
||||||
|
std::cout << "Handle_GDB_Loop\n";
|
||||||
|
|
||||||
|
Registers *register_bank = dbg_cpu->getRegisterBank();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
std::string msg = receive_packet();
|
||||||
|
|
||||||
|
// std::cout << "msg: " << msg << std::endl;
|
||||||
|
if (msg.size() == 0) {
|
||||||
|
std::cout << "remote connection seems to be closed, terminating ..."
|
||||||
|
<< std::endl;
|
||||||
|
break;
|
||||||
|
} else if (msg == "+") {
|
||||||
|
// NOTE: just ignore this message, nothing to do in this case
|
||||||
|
} else if (boost::starts_with(msg, "qSupported")) {
|
||||||
|
printf("qSupported\n");
|
||||||
|
send_packet(conn, "PacketSize=1024;swbreak-;hwbreak+;vContSupported+");
|
||||||
|
} else if (msg == "vMustReplyEmpty") {
|
||||||
|
printf("vMustReplyEmpty\n");
|
||||||
|
send_packet(conn, "");
|
||||||
|
} else if (msg == "Hg0") {
|
||||||
|
printf("Hq0\n");
|
||||||
|
send_packet(conn, "OK");
|
||||||
|
} else if (msg == "Hc0") {
|
||||||
|
printf("Hc0\n");
|
||||||
|
send_packet(conn, "");
|
||||||
|
} else if (msg == "qTStatus") {
|
||||||
|
printf("qTStatus\n");
|
||||||
|
send_packet(conn, "");
|
||||||
|
} else if (msg == "?") {
|
||||||
|
printf("?\n");
|
||||||
|
send_packet(conn, "S05");
|
||||||
|
} else if (msg == "qfThreadInfo") {
|
||||||
|
printf("qThreadInfo\n");
|
||||||
|
send_packet(conn, "");
|
||||||
|
} else if (boost::starts_with(msg, "qL")) {
|
||||||
|
printf("qL\n");
|
||||||
|
send_packet(conn, "");
|
||||||
|
} else if (msg == "Hc-1") {
|
||||||
|
printf("Hc-1\n");
|
||||||
|
send_packet(conn, "OK");
|
||||||
|
} else if (msg == "qC") {
|
||||||
|
printf("qC\n");
|
||||||
|
send_packet(conn, "-1");
|
||||||
|
} else if (msg == "qAttached") {
|
||||||
|
printf("qAttached\n");
|
||||||
|
send_packet(conn, "0"); // 0 process started, 1 attached to process
|
||||||
|
} else if (msg == "g") {
|
||||||
|
// std::cout << msg << '\n';
|
||||||
|
|
||||||
|
std::stringstream stream;
|
||||||
|
stream << std::setfill('0') << std::hex;
|
||||||
|
for (int i = 1; i < 32; i++) {
|
||||||
|
stream << std::setw(8) << register_bank->getValue(i);
|
||||||
|
}
|
||||||
|
send_packet(conn, stream.str());
|
||||||
|
} else if (boost::starts_with(msg, "p")) {
|
||||||
|
std::cout << "P : " << msg << std::endl;
|
||||||
|
long n = strtol(msg.c_str() + 1, 0, 16);
|
||||||
|
|
||||||
|
int reg_value;
|
||||||
|
if (n < 32) {
|
||||||
|
reg_value = register_bank->getValue(n);
|
||||||
|
} else if (n == 32) {
|
||||||
|
reg_value = register_bank->getPC();
|
||||||
|
} else {
|
||||||
|
// see: https://github.com/riscv/riscv-gnu-toolchain/issues/217
|
||||||
|
// risc-v register 834
|
||||||
|
reg_value = register_bank->getCSR(n - 65);
|
||||||
|
}
|
||||||
|
std::stringstream stream;
|
||||||
|
stream << std::setfill('0') << std::hex;
|
||||||
|
stream << std::setw(8) << htonl(reg_value);
|
||||||
|
send_packet(conn, stream.str());
|
||||||
|
} else if (boost::starts_with(msg, "P")) {
|
||||||
|
printf("P\n");
|
||||||
|
char * pEnd;
|
||||||
|
long reg = strtol(msg.c_str() + 1, &pEnd, 16);
|
||||||
|
std::cout << "n: " << reg;
|
||||||
|
int val = strtol(pEnd + 1, 0, 16);
|
||||||
|
std::cout << "= " << val << std::endl;
|
||||||
|
register_bank->setValue(reg + 1, val);
|
||||||
|
send_packet(conn, "OK");
|
||||||
|
} else if (boost::starts_with(msg, "m")) {
|
||||||
|
printf("m\n");
|
||||||
|
|
||||||
|
char * pEnd;
|
||||||
|
long addr = strtol(msg.c_str() + 1, &pEnd, 16);;
|
||||||
|
int len = strtol(pEnd + 1, &pEnd, 16);
|
||||||
|
std::cout << "msg m: " << msg << std::endl;
|
||||||
|
std::cout << std::hex << "addr: " << addr << " , " << len << std::endl;
|
||||||
|
|
||||||
|
dbg_trans.set_data_ptr(pyld_array);
|
||||||
|
dbg_trans.set_command(tlm::TLM_READ_COMMAND);
|
||||||
|
dbg_trans.set_address(addr);
|
||||||
|
dbg_trans.set_data_length(len);
|
||||||
|
dbg_mem->transport_dbg(dbg_trans);
|
||||||
|
|
||||||
|
std::stringstream stream;
|
||||||
|
stream << std::setfill('0') << std::hex;
|
||||||
|
for (auto &c : pyld_array) {
|
||||||
|
stream << std::setw(2) << (0xFF & c);
|
||||||
|
}
|
||||||
|
|
||||||
|
send_packet(conn, stream.str());
|
||||||
|
|
||||||
|
} else if (boost::starts_with(msg, "M")) {
|
||||||
|
printf("M\n");
|
||||||
|
//memory_access_t m = parse_memory_access(msg);
|
||||||
|
//std::string data = msg.substr(msg.find(":") + 1);
|
||||||
|
//write_memory(m.start, m.nbytes, data);
|
||||||
|
send_packet(conn, "OK");
|
||||||
|
} else if (boost::starts_with(msg, "X")) {
|
||||||
|
printf("X\n");
|
||||||
|
send_packet(conn, ""); // binary data unsupported, gdb will send
|
||||||
|
// text based message M
|
||||||
|
} else if (msg == "qOffsets") {
|
||||||
|
printf("qOffsets\n");
|
||||||
|
// NOTE: seems to be additional offsets wrt. the exec. elf file
|
||||||
|
send_packet(conn, "Text=0;Data=0;Bss=0");
|
||||||
|
} else if (msg == "qSymbol::") {
|
||||||
|
printf("qSymbol\n");
|
||||||
|
send_packet(conn, "OK");
|
||||||
|
} else if (msg == "vCont?") {
|
||||||
|
printf("vCont?\n");
|
||||||
|
send_packet(conn, "vCont;cs");
|
||||||
|
} else if (msg == "c") {
|
||||||
|
printf("c\n");
|
||||||
|
//try {
|
||||||
|
// core.run();
|
||||||
|
//if (core.status == CoreExecStatus::HitBreakpoint) {
|
||||||
|
// send_packet(conn, "S05");
|
||||||
|
// core.status = CoreExecStatus::Runnable;
|
||||||
|
//} else if (core.status == CoreExecStatus::Terminated) {
|
||||||
|
//send_packet(conn, "S03");
|
||||||
|
//} else {
|
||||||
|
// assert(false && "invalid core status (apparently still marked as runnable)");
|
||||||
|
//}
|
||||||
|
//} catch (std::exception &e) {
|
||||||
|
// send_packet(conn, "S04");
|
||||||
|
//}
|
||||||
|
bool breakpoint_hit = false;
|
||||||
|
bool bkpt = false;
|
||||||
|
do {
|
||||||
|
// std::cout << "PC: " << std::hex << register_bank->getPC() << std::endl;
|
||||||
|
bkpt = dbg_cpu->CPU_step();
|
||||||
|
uint32_t currentPC = register_bank->getPC();
|
||||||
|
|
||||||
|
auto search = breakpoints.find(currentPC);
|
||||||
|
if (search != breakpoints.end()) {
|
||||||
|
breakpoint_hit = true;
|
||||||
|
}
|
||||||
|
} while ((breakpoint_hit == false) && (bkpt == false));
|
||||||
|
|
||||||
|
std::cout << "Breakpoint hit at 0x" << std::hex << register_bank->getPC() << std::endl;
|
||||||
|
|
||||||
|
//send_packet(conn, "S05");
|
||||||
|
send_packet(conn, "S03");
|
||||||
|
} else if (msg == "s") {
|
||||||
|
printf("s\n");
|
||||||
|
bool breakpoint;
|
||||||
|
|
||||||
|
dbg_cpu->CPU_step();
|
||||||
|
|
||||||
|
uint32_t currentPC = register_bank->getPC();
|
||||||
|
auto search = breakpoints.find(currentPC);
|
||||||
|
if (search != breakpoints.end()) {
|
||||||
|
breakpoint = true;
|
||||||
|
} else {
|
||||||
|
breakpoint = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (breakpoint) {
|
||||||
|
send_packet(conn, "S03");
|
||||||
|
} else {
|
||||||
|
send_packet(conn, "S05");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (boost::starts_with(msg, "vKill")) {
|
||||||
|
printf("vKill\n");
|
||||||
|
send_packet(conn, "OK");
|
||||||
|
break;
|
||||||
|
} else if (boost::starts_with(msg, "Z1")) {
|
||||||
|
char * pEnd;
|
||||||
|
long addr = strtol(msg.c_str() + 3, &pEnd, 16);;
|
||||||
|
std::cout << "msg m: " << msg << std::endl;
|
||||||
|
breakpoints.insert(addr);
|
||||||
|
std::cout << "Breakpoint set to addres 0x"<< std::hex << addr << std::endl;
|
||||||
|
send_packet(conn, "OK");
|
||||||
|
} else if (boost::starts_with(msg, "z1")) {
|
||||||
|
send_packet(conn, "OK");
|
||||||
|
} else if (boost::starts_with(msg, "z0")) {
|
||||||
|
|
||||||
|
} else if (boost::starts_with(msg, "Z0")) {
|
||||||
|
char * pEnd;
|
||||||
|
long addr = strtol(msg.c_str() + 3, &pEnd, 16);;
|
||||||
|
std::cout << "msg m: " << msg << std::endl;
|
||||||
|
breakpoints.insert(addr);
|
||||||
|
std::cout << "Breakpoint set to address 0x"<< std::hex << addr << std::endl;
|
||||||
|
send_packet(conn, "OK");
|
||||||
|
} else {
|
||||||
|
std::cout << "unsupported message '" << msg
|
||||||
|
<< "' detected, terminating ..." << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Debug::compute_checksum_string(const std::string &msg) {
|
||||||
|
unsigned sum = 0;
|
||||||
|
for (auto c : msg) {
|
||||||
|
sum += unsigned(c);
|
||||||
|
}
|
||||||
|
sum = sum % 256;
|
||||||
|
|
||||||
|
char low = nibble_to_hex[sum & 0xf];
|
||||||
|
char high = nibble_to_hex[(sum & (0xf << 4)) >> 4];
|
||||||
|
|
||||||
|
return {high, low};
|
||||||
|
}
|
|
@ -21,8 +21,10 @@
|
||||||
#include "BusCtrl.h"
|
#include "BusCtrl.h"
|
||||||
#include "Trace.h"
|
#include "Trace.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
|
#include "Debug.h"
|
||||||
|
|
||||||
std::string filename;
|
std::string filename;
|
||||||
|
bool debug_session = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class Simulator
|
* @class Simulator
|
||||||
|
@ -44,7 +46,7 @@ SC_MODULE(Simulator) {
|
||||||
MainMemory = new Memory("Main_Memory", filename);
|
MainMemory = new Memory("Main_Memory", filename);
|
||||||
start_PC = MainMemory->getPCfromHEX();
|
start_PC = MainMemory->getPCfromHEX();
|
||||||
|
|
||||||
cpu = new CPU("cpu", start_PC);
|
cpu = new CPU("cpu", start_PC, debug_session);
|
||||||
|
|
||||||
Bus = new BusCtrl("BusCtrl");
|
Bus = new BusCtrl("BusCtrl");
|
||||||
trace = new Trace("Trace");
|
trace = new Trace("Trace");
|
||||||
|
@ -58,6 +60,10 @@ SC_MODULE(Simulator) {
|
||||||
Bus->timer_socket.bind(timer->socket);
|
Bus->timer_socket.bind(timer->socket);
|
||||||
|
|
||||||
timer->irq_line.bind(cpu->irq_line_socket);
|
timer->irq_line.bind(cpu->irq_line_socket);
|
||||||
|
|
||||||
|
if (debug_session) {
|
||||||
|
Debug debug("Debug", start_PC, cpu, MainMemory);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~Simulator() {
|
~Simulator() {
|
||||||
|
@ -87,9 +93,14 @@ void process_arguments(int argc, char *argv[]) {
|
||||||
log = Log::getInstance();
|
log = Log::getInstance();
|
||||||
log->setLogLevel(Log::ERROR);
|
log->setLogLevel(Log::ERROR);
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "D:f:?")) != -1) {
|
debug_session = false;
|
||||||
|
|
||||||
|
while ((c = getopt(argc, argv, "DL:f:?")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'D':
|
case 'D':
|
||||||
|
debug_session = true;
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
debug_level = std::atoi(optarg);
|
debug_level = std::atoi(optarg);
|
||||||
|
|
||||||
switch (debug_level) {
|
switch (debug_level) {
|
||||||
|
@ -114,7 +125,7 @@ void process_arguments(int argc, char *argv[]) {
|
||||||
filename = std::string(optarg);
|
filename = std::string(optarg);
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
std::cout << "Call ./RISCV_TLM -D <debuglevel> (0..3) filename.hex"
|
std::cout << "Call ./RISCV_TLM -D -L <debuglevel> (0..3) filename.hex"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -126,6 +137,8 @@ void process_arguments(int argc, char *argv[]) {
|
||||||
if (filename.empty()) {
|
if (filename.empty()) {
|
||||||
filename = std::string(argv[optind]);
|
filename = std::string(argv[optind]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cout << "file: " << filename << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
int sc_main(int argc, char *argv[]) {
|
int sc_main(int argc, char *argv[]) {
|
||||||
|
|
Loading…
Reference in New Issue