未验证 提交 eae43642 编写于 作者: Y YikeZhou 提交者: GitHub

Merge pull request #276 from RISCVERS/max-instr-op

Add --max-instr option for emu
......@@ -15,6 +15,7 @@ static inline void print_help(const char *file) {
printf("\n");
printf(" -s, --seed=NUM use this seed\n");
printf(" -C, --max-cycles=NUM execute at most NUM cycles\n");
printf(" -I, --max-instr=NUM execute at most NUM instructions\n");
printf(" -i, --image=FILE run with this image file\n");
printf(" -b, --log-begin=NUM display log from NUM th cycle\n");
printf(" -e, --log-end=NUM stop display log at NUM th cycle\n");
......@@ -32,6 +33,7 @@ inline EmuArgs parse_args(int argc, const char *argv[]) {
{ "dump-wave", 0, NULL, 0 },
{ "seed", 1, NULL, 's' },
{ "max-cycles", 1, NULL, 'C' },
{ "max-instr", 1, NULL, 'I' },
{ "image", 1, NULL, 'i' },
{ "log-begin", 1, NULL, 'b' },
{ "log-end", 1, NULL, 'e' },
......@@ -41,7 +43,7 @@ inline EmuArgs parse_args(int argc, const char *argv[]) {
int o;
while ( (o = getopt_long(argc, const_cast<char *const*>(argv),
"-s:C:hi:m:b:e:", long_options, &long_index)) != -1) {
"-s:C:I:hi:m:b:e:", long_options, &long_index)) != -1) {
switch (o) {
case 0:
switch (long_index) {
......@@ -59,6 +61,7 @@ inline EmuArgs parse_args(int argc, const char *argv[]) {
}
break;
case 'C': args.max_cycles = atoll(optarg); break;
case 'I': args.max_instr = atoll(optarg); break;
case 'i': args.image = optarg; break;
case 'b': args.log_begin = atoll(optarg); break;
case 'e': args.log_end = atoll(optarg); break;
......@@ -222,12 +225,13 @@ inline void Emulator::single_cycle() {
cycles ++;
}
uint64_t Emulator::execute(uint64_t n) {
uint64_t Emulator::execute(uint64_t max_cycle, uint64_t max_instr) {
extern void poll_event(void);
extern uint32_t uptime(void);
uint32_t lasttime_poll = 0;
uint32_t lasttime_snapshot = 0;
uint64_t lastcommit = n;
uint64_t lastcommit = max_cycle;
uint64_t instr_left_last_cycle = max_instr;
const int stuck_limit = 2000;
uint32_t wdst[DIFFTEST_WIDTH];
......@@ -240,14 +244,19 @@ uint64_t Emulator::execute(uint64_t n) {
diff.wdata = wdata;
diff.wdst = wdst;
while (trapCode == STATE_RUNNING && n > 0) {
while (trapCode == STATE_RUNNING) {
if (!(max_cycle > 0 && max_instr > 0 && instr_left_last_cycle >= max_instr /* handle overflow */)) {
trapCode = STATE_LIMIT_EXCEEDED;
break;
}
single_cycle();
n --;
max_cycle --;
if (dut_ptr->io_trap_valid) trapCode = dut_ptr->io_trap_code;
if (trapCode != STATE_RUNNING) break;
if (lastcommit - n > stuck_limit && hascommit) {
if (lastcommit - max_cycle > stuck_limit && hascommit) {
eprintf("No instruction commits for %d cycles, maybe get stuck\n"
"(please also check whether a fence.i instruction requires more than %d cycles to flush the icache)\n",
stuck_limit, stuck_limit);
......@@ -283,7 +292,11 @@ uint64_t Emulator::execute(uint64_t n) {
if (difftest_step(&diff)) {
trapCode = STATE_ABORT;
}
lastcommit = n;
lastcommit = max_cycle;
// update instr_cnt
instr_left_last_cycle = max_instr;
max_instr -= diff.commit;
}
uint32_t t = uptime();
......@@ -355,6 +368,9 @@ void Emulator::display_trapinfo() {
case STATE_ABORT:
eprintf(ANSI_COLOR_RED "ABORT at pc = 0x%" PRIx64 "\n" ANSI_COLOR_RESET, pc);
break;
case STATE_LIMIT_EXCEEDED:
eprintf(ANSI_COLOR_YELLOW "EXCEEDING CYCLE/INSTR LIMIT at pc = 0x%" PRIx64 "\n" ANSI_COLOR_RESET, pc);
break;
default:
eprintf(ANSI_COLOR_RED "Unknown trap code: %d\n", trapCode);
}
......
......@@ -9,6 +9,7 @@
struct EmuArgs {
uint32_t seed;
uint64_t max_cycles;
uint64_t max_instr;
uint64_t log_begin, log_end;
const char *image;
const char *snapshot_path;
......@@ -17,6 +18,7 @@ struct EmuArgs {
EmuArgs() {
seed = 0;
max_cycles = -1;
max_instr = -1;
log_begin = 1;
log_end = -1;
snapshot_path = NULL;
......@@ -38,6 +40,7 @@ class Emulator {
STATE_GOODTRAP = 0,
STATE_BADTRAP,
STATE_ABORT,
STATE_LIMIT_EXCEEDED,
STATE_RUNNING = -1
};
......@@ -60,7 +63,7 @@ class Emulator {
public:
Emulator(int argc, const char *argv[]);
~Emulator();
uint64_t execute(uint64_t n);
uint64_t execute(uint64_t max_cycle, uint64_t max_instr);
uint64_t get_cycles() const { return cycles; }
EmuArgs get_args() const { return args; }
bool is_good_trap() { return trapCode == STATE_GOODTRAP; };
......
......@@ -19,7 +19,7 @@ int main(int argc, const char** argv) {
};
auto args = emu->get_args();
uint64_t cycles = emu->execute(args.max_cycles);
uint64_t cycles = emu->execute(args.max_cycles, args.max_instr);
bool is_good_trap = emu->is_good_trap();
delete emu;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册