diff options
| author | Alejandro Soto <alejandro@34project.org> | 2022-12-16 13:19:47 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2022-12-16 22:20:26 -0600 |
| commit | 2c7ad7bd098d885f3df623fe099adf500fbafad7 (patch) | |
| tree | fb3566e130504711d733edb0216149a960fc89ce /tb/top/conspiracion.cpp | |
| parent | 6e52e1df7567cdf419a193bf541dd98c0253e5a4 (diff) | |
Improve simulation performance for the most common case
Diffstat (limited to 'tb/top/conspiracion.cpp')
| -rw-r--r-- | tb/top/conspiracion.cpp | 72 |
1 files changed, 57 insertions, 15 deletions
diff --git a/tb/top/conspiracion.cpp b/tb/top/conspiracion.cpp index e1095f2..0286cfc 100644 --- a/tb/top/conspiracion.cpp +++ b/tb/top/conspiracion.cpp @@ -229,7 +229,7 @@ int main(int argc, char **argv) args::ValueFlag<unsigned> cycles ( - parser, "cycles", "Max number of core cycles to run", {"cycles"}, UINT_MAX + parser, "cycles", "Max number of core cycles to run", {"cycles"}, 0 ); args::ValueFlag<int> control_fd @@ -425,11 +425,6 @@ int main(int argc, char **argv) { tick(); tick(); - - if(top.breakpoint || (!(time & ((1 << 8) - 1)) && async_halt)) [[unlikely]] - { - top.halt = 1; - } }; if(!no_tty) @@ -564,22 +559,69 @@ int main(int argc, char **argv) core.fetch->explicit_branch__VforceVal = 1; - unsigned i = 0; - // Abuse unsigned overflow (cycles is UINT_MAX by default) - while(!failed && i + 1 <= *cycles) + auto maybe_halt = [&]() + { + if(top.breakpoint || async_halt) + { + top.halt = 1; + } + + return top.halt; + }; + + auto loop_fast = [&]() { do { - cycle(); - if(failed || top.cpu_halted) [[unlikely]] + for(unsigned iters = 0; iters < 1024 && !top.breakpoint; ++iters) { - goto halt_or_fail; + top.clk_clk = 0; + top.eval(); + avl.tick_falling(); + + top.clk_clk = 1; + top.eval(); + + // This is free most of the time + try + { + avl.tick_rising(); + } catch(const avl_bus_error&) + { + failed = true; + break; + } } - } while(++i + 1 <= *cycles); + } while(!maybe_halt()); + }; + + unsigned i = 0; + auto loop_accurate = [&]() + { + do + { + cycle(); + maybe_halt(); + } while(!failed && !top.cpu_halted && (*cycles == 0 || ++i < *cycles)); + }; + + const bool slow_path = *cycles > 0 || enable_accurate_video || enable_trace; - break; + while(true) + { + if(slow_path || top.halt || top.step) + { + loop_accurate(); + } else + { + loop_fast(); + } + + if(failed || (*cycles > 0 && i >= *cycles)) + { + break; + } -halt_or_fail: top.step = 0; core.fetch->target__VforceVal = core.control->pc; |
