npc: drop sdb, use gdb as frontend

This commit is contained in:
xinyangli 2024-07-10 20:27:09 +08:00
parent 7c982b238b
commit 2ab098d181
Signed by: xin
SSH key fingerprint: SHA256:qZ/tzd8lYRtUFSrfBDBMcUqV4GHKxqeqRA3huItgvbk
8 changed files with 137 additions and 128 deletions

View file

@ -20,12 +20,12 @@
template <typename T, std::size_t nr> class _RegistersBase {
std::array<T, nr> regs;
T pc;
virtual T fetch_pc();
virtual T fetch_reg(std::size_t id);
virtual T fetch_pc() const;
virtual T fetch_reg(std::size_t id) const;
public:
T operator[](size_t id) { return fetch_reg(id); }
T get_pc() { return fetch_pc(); }
T operator[](size_t id) const { return fetch_reg(id); }
T get_pc() const { return fetch_pc(); }
void update() {
for (int i = 0; i < regs.size(); i++) {
regs[i] = fetch_reg(i);
@ -112,14 +112,14 @@ public:
if (ram->in_pmem(addr)) {
ram->transfer(addr, buf, len, false);
} else {
std::cerr << "Not in pmem" << std::endl;
std::cerr << "0x" << std::hex << addr << " not in pmem" << std::endl;
}
}
void copy_from(paddr_t addr, const uint8_t *buf, size_t len) {
void copy_from(paddr_t addr, uint8_t *buf, size_t len) {
if (ram->in_pmem(addr)) {
ram->transfer(addr, buf, len, true);
} else {
std::cerr << "Not in pmem" << std::endl;
std::cerr << "0x" << std::hex << addr << " not in pmem" << std::endl;
}
}
void *get_pmem() { return ram->mem.data(); }

View file

@ -29,4 +29,10 @@ const std::map<std::string, int> riscv32_regs_by_name{
{"t5", 30}, {"t6", 31}};
#endif
#endif
#include <gdbstub.h>
struct Breakpoint {
size_t addr;
bp_type_t type;
};
#endif

View file

@ -1,7 +1,10 @@
#ifndef _NPC_TRACER_H_
#define _NPC_TRACER_H_
#include "components.hpp"
#include "types.h"
#include <filesystem>
#include <gdbstub.h>
#include <sys/types.h>
#include <verilated_vcd_c.h>
template <class T> class Tracer {
@ -26,16 +29,24 @@ public:
void update() { m_trace->dump(cycle++); }
};
template <typename T> class VlModuleInterfaceCommon : public T {
template <typename T, typename R> class VlModuleInterfaceCommon : public T {
uint64_t sim_time = 0;
uint64_t posedge_cnt = 0;
std::unique_ptr<Tracer<T>> tracer;
public:
VlModuleInterfaceCommon<T>(std::filesystem::path wavefile) {
const R *registers;
VlModuleInterfaceCommon<T, R>() {
tracer = nullptr;
registers = nullptr;
}
void setup(std::filesystem::path wavefile, const R *r) {
if (!wavefile.empty())
tracer = std::make_unique<Tracer<T>>(this, wavefile);
registers = r;
}
void eval() {
if (this->is_posedge()) {
posedge_cnt++;
@ -51,6 +62,25 @@ public:
this->eval();
}
}
gdb_action_t eval(const std::vector<Breakpoint> &breakpoints) {
gdb_action_t res;
do {
this->eval();
size_t pc = registers->get_pc();
for (const auto &bp : breakpoints) {
if (pc == bp.addr) {
res.data = bp.addr;
switch (bp.type) {
default:
res.reason = gdb_action_t::ACT_BREAKPOINT;
}
return res;
}
}
} while (true);
}
void reset_eval(int n) {
extern bool g_skip_memcheck;
g_skip_memcheck = true;

View file

@ -7,14 +7,14 @@ template <typename T, std::size_t nr>
class _RegistersVPI : public _RegistersBase<T, nr> {
std::array<vpiHandle, nr> reg_handles;
vpiHandle pc_handle;
T vpi_get(vpiHandle vh) {
T vpi_get(vpiHandle vh) const {
s_vpi_value v;
v.format = vpiIntVal;
vpi_get_value(vh, &v);
return v.value.integer;
}
T fetch_pc(void) { return vpi_get(pc_handle); }
T fetch_reg(std::size_t id) { return vpi_get(reg_handles[id]); }
T fetch_pc(void) const { return vpi_get(pc_handle); }
T fetch_reg(std::size_t id) const { return vpi_get(reg_handles[id]); }
public:
_RegistersVPI<T, nr>(const std::string regs_prefix,