2024-04-03 17:44:27 +00:00
|
|
|
#ifndef _DIFFTEST_DIFFTEST_H_
|
|
|
|
#define _DIFFTEST_DIFFTEST_H_
|
2024-07-15 10:47:44 +00:00
|
|
|
#include "api.hpp"
|
|
|
|
#include <filesystem>
|
2024-08-08 08:38:05 +00:00
|
|
|
#include <spdlog/spdlog.h>
|
2024-07-15 10:47:44 +00:00
|
|
|
#include <vector>
|
2024-07-16 01:50:17 +00:00
|
|
|
extern "C" {
|
|
|
|
#include <gdbstub.h>
|
|
|
|
}
|
2024-07-15 10:47:44 +00:00
|
|
|
|
|
|
|
class Difftest {
|
|
|
|
private:
|
|
|
|
Target dut;
|
|
|
|
std::vector<Target> refs;
|
|
|
|
|
2024-07-16 01:50:17 +00:00
|
|
|
// target used for read_reg, write_reg, read_mem, write_mem
|
|
|
|
Target *current_target = &dut;
|
2024-07-22 08:20:19 +00:00
|
|
|
bool halt_status = false;
|
|
|
|
inline void start_run() {
|
|
|
|
__atomic_store_n(&halt_status, false, __ATOMIC_RELAXED);
|
|
|
|
};
|
|
|
|
inline bool is_halt() {
|
|
|
|
return __atomic_load_n(&halt_status, __ATOMIC_RELAXED);
|
|
|
|
};
|
2024-07-16 01:50:17 +00:00
|
|
|
|
2024-07-15 10:47:44 +00:00
|
|
|
public:
|
|
|
|
Difftest(Target &&dut, std::vector<Target> &&refs);
|
|
|
|
|
|
|
|
void setup(const std::filesystem::path &memory_file);
|
2024-07-16 01:50:17 +00:00
|
|
|
|
|
|
|
// Export API for gdbstub
|
2024-07-15 10:47:44 +00:00
|
|
|
gdb_action_t cont();
|
2024-07-16 01:50:17 +00:00
|
|
|
gdb_action_t stepi();
|
|
|
|
int read_reg(int regno, size_t *value);
|
|
|
|
int write_reg(int regno, size_t value);
|
|
|
|
int read_mem(size_t addr, size_t len, void *val);
|
|
|
|
int write_mem(size_t addr, size_t len, void *val);
|
|
|
|
bool set_bp(size_t addr, bp_type_t type);
|
|
|
|
bool del_bp(size_t addr, bp_type_t type);
|
|
|
|
|
2024-08-16 04:27:24 +00:00
|
|
|
struct ExecRet {
|
|
|
|
bool at_breakpoint;
|
|
|
|
bool do_difftest;
|
|
|
|
bool check_failed;
|
|
|
|
};
|
|
|
|
ExecRet exec(size_t n, gdb_action_t *ret);
|
|
|
|
|
2024-07-16 03:16:11 +00:00
|
|
|
bool check_all();
|
2024-07-22 08:20:19 +00:00
|
|
|
int sync_regs_to_ref(void);
|
2024-08-09 05:10:47 +00:00
|
|
|
std::string list_targets(void);
|
|
|
|
std::string switch_target(int index);
|
2024-07-22 08:20:19 +00:00
|
|
|
|
|
|
|
inline void halt() {
|
|
|
|
__atomic_store_n(&halt_status, true, __ATOMIC_RELAXED);
|
|
|
|
};
|
2024-07-16 03:16:11 +00:00
|
|
|
|
2024-07-22 08:20:19 +00:00
|
|
|
arch_info_t get_arch() const { return *dut.isa_arch_info; }
|
2024-07-16 01:50:17 +00:00
|
|
|
|
2024-07-15 10:47:44 +00:00
|
|
|
static bool check(Target &dut, Target &ref) {
|
2024-08-08 08:38:05 +00:00
|
|
|
size_t pcref, pcdut;
|
|
|
|
bool passed = true;
|
|
|
|
dut.ops.read_reg(dut.args.data(), 32, &pcdut);
|
|
|
|
ref.ops.read_reg(ref.args.data(), 32, &pcref);
|
2024-07-22 08:20:19 +00:00
|
|
|
for (int r = 0; r < dut.isa_arch_info->reg_num; r++) {
|
2024-07-15 10:47:44 +00:00
|
|
|
size_t regdut = 0, regref = 0;
|
|
|
|
dut.ops.read_reg(dut.args.data(), r, ®dut);
|
|
|
|
ref.ops.read_reg(ref.args.data(), r, ®ref);
|
|
|
|
if (regdut != regref) {
|
2024-08-08 08:38:05 +00:00
|
|
|
spdlog::error("Reg {} different: \n\tPC:\t(ref) {:x}\t(dut) {:x}\n\t"
|
|
|
|
"value:\t(ref) {:x}\t(dut) {:x}",
|
|
|
|
r, pcref, pcdut, regref, regdut);
|
|
|
|
passed = false;
|
2024-07-15 10:47:44 +00:00
|
|
|
}
|
|
|
|
}
|
2024-08-08 08:38:05 +00:00
|
|
|
return passed;
|
2024-07-15 10:47:44 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class Iterator {
|
|
|
|
private:
|
|
|
|
Difftest &difftest;
|
|
|
|
size_t index;
|
|
|
|
bool on_dut;
|
|
|
|
|
|
|
|
public:
|
|
|
|
Iterator(Difftest &difftest, size_t index, bool on_dut)
|
|
|
|
: difftest(difftest), index(index), on_dut(on_dut) {}
|
|
|
|
|
|
|
|
Iterator &operator++() {
|
|
|
|
if (on_dut) {
|
|
|
|
on_dut = false;
|
|
|
|
} else {
|
|
|
|
++index;
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator!=(const Iterator &other) const {
|
|
|
|
return index != other.index || on_dut != other.on_dut;
|
|
|
|
}
|
|
|
|
|
|
|
|
Target &operator*() {
|
|
|
|
if (on_dut) {
|
|
|
|
return difftest.dut;
|
|
|
|
} else {
|
|
|
|
return difftest.refs.at(index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
Iterator begin() { return Iterator(*this, 0, true); }
|
|
|
|
|
|
|
|
Iterator end() { return Iterator(*this, refs.size(), false); }
|
|
|
|
};
|
2024-04-03 17:44:27 +00:00
|
|
|
|
2024-07-22 08:20:19 +00:00
|
|
|
#endif
|