diff options
Diffstat (limited to 'main.cpp')
| -rw-r--r-- | main.cpp | 116 |
1 files changed, 22 insertions, 94 deletions
| @@ -1,113 +1,41 @@ | |||
| 1 | #include <fmt/core.h> | ||
| 2 | #include <iostream> | 1 | #include <iostream> |
| 3 | #include <memory> | ||
| 4 | #include <optional> | ||
| 5 | #include <utility> | 2 | #include <utility> |
| 6 | 3 | ||
| 7 | #include "aisa/aisa.h" | ||
| 8 | #include "aisa/async.h" | ||
| 9 | #include "aisa/simple-models.h" | ||
| 10 | #include "fib/fib.h" | 4 | #include "fib/fib.h" |
| 11 | #include "git-tag.h" | 5 | #include "git-tag.h" |
| 12 | 6 | #include "sim/sim.h" | |
| 13 | const unsigned int max_steps = 300; | 7 | #include "sim/queue.h" |
| 14 | const bool show_mem_fetch = false; | 8 | #include "uarch/exec.h" |
| 15 | const bool show_mem_store = true; | 9 | #include "uarch/fetch.h" |
| 16 | const bool show_regs = false; | 10 | #include "uarch/memory.h" |
| 17 | const bool show_steps = false; | 11 | #include "uarch/types.h" |
| 18 | const bool show_tasks = false; | ||
| 19 | 12 | ||
| 20 | int main(int argc, const char *argv[]) | 13 | int main(int argc, const char *argv[]) |
| 21 | { | 14 | { |
| 22 | std::cout << "Version " << GIT_TAG << "\n"; | 15 | std::cout << "Version " << GIT_TAG << "\n"; |
| 23 | 16 | ||
| 24 | struct Eval : public aisa::AsyncEval<Eval>, aisa::PagedMem<>, aisa::TaskStack, aisa::VectorRF { | 17 | fib::Fib<3> fib; |
| 25 | bool fetch_mem(aisa::byte_t *bytes, aisa::addr_t addr, aisa::addr_t size) | ||
| 26 | { | ||
| 27 | if (aisa::PagedMem<>::fetch_mem(bytes, addr, size)) { | ||
| 28 | if (show_mem_fetch) { | ||
| 29 | fmt::print("\t\t\t"); | ||
| 30 | for (; size; --size) | ||
| 31 | fmt::print("{:02x} ", *bytes++); | ||
| 32 | fmt::print("= [{:x}]\n", addr); | ||
| 33 | } | ||
| 34 | return true; | ||
| 35 | } | ||
| 36 | return false; | ||
| 37 | } | ||
| 38 | |||
| 39 | bool store_mem(aisa::addr_t addr, const aisa::byte_t *bytes, aisa::addr_t size) | ||
| 40 | { | ||
| 41 | if (aisa::PagedMem<>::store_mem(addr, bytes, size)) { | ||
| 42 | if (show_mem_store) { | ||
| 43 | fmt::print("\t\t\t[{:x}] =", addr); | ||
| 44 | for (; size; --size) | ||
| 45 | fmt::print(" {:02x}", *bytes++); | ||
| 46 | fmt::print("\n"); | ||
| 47 | } | ||
| 48 | return true; | ||
| 49 | } | ||
| 50 | return false; | ||
| 51 | } | ||
| 52 | |||
| 53 | bool store_reg(aisa::regnum_t rn, aisa::regval_t rv) | ||
| 54 | { | ||
| 55 | if (aisa::VectorRF::store_reg(rn, rv)) { | ||
| 56 | if (show_regs) | ||
| 57 | fmt::print(".{} = {}\n", fib::Reg::disasm(rn), rv); | ||
| 58 | return true; | ||
| 59 | } | ||
| 60 | return false; | ||
| 61 | } | ||
| 62 | |||
| 63 | bool push_task(std::unique_ptr<const aisa::Task> &&task) | ||
| 64 | { | ||
| 65 | auto d = task->disasm(); | ||
| 66 | if (aisa::TaskStack::push_task(std::move(task))) { | ||
| 67 | if (show_tasks) | ||
| 68 | fmt::print("\t\t*** ENTER {} ***\n", d); | ||
| 69 | return true; | ||
| 70 | } | ||
| 71 | return false; | ||
| 72 | } | ||
| 73 | 18 | ||
| 74 | bool pop_task() | 19 | sim::Scheduler sched; |
| 75 | { | ||
| 76 | if (aisa::TaskStack::pop_task()) { | ||
| 77 | if (show_tasks) | ||
| 78 | fmt::print("\t\t *** LEAVE ***\n"); | ||
| 79 | return true; | ||
| 80 | } | ||
| 81 | return false; | ||
| 82 | } | ||
| 83 | } eval; | ||
| 84 | 20 | ||
| 85 | fib::Fib<3> fib; | 21 | sim::Queue<uarch::FillReq> fillreqq(sched, 1); |
| 22 | sim::Queue<uarch::Fill> fillfetchq(sched, 0); | ||
| 23 | sim::Queue<uarch::Fill> fillexecq(sched, 0); | ||
| 24 | sim::Queue<uarch::Store> storeq(sched, 1); | ||
| 25 | sim::Queue<uarch::Uop> execq(sched, 0); | ||
| 86 | 26 | ||
| 87 | if (!eval.async_setup_initial_task(fib)()) { | 27 | auto fetch = new uarch::FetchStage(sched, fib, fillreqq, fillfetchq, execq); |
| 88 | fmt::print("Failed to complete initial setup.\n"); | 28 | auto exec = new uarch::ExecStage(sched, execq, fillreqq, fillexecq, storeq); |
| 89 | return 1; | 29 | auto mem = new uarch::MemStage(sched, fillreqq, {&fillfetchq, &fillexecq}, storeq); |
| 90 | } | ||
| 91 | 30 | ||
| 92 | for (unsigned int i = 0; i < max_steps; ++i) { | 31 | while (true) { |
| 93 | auto res = eval.async_fetch_and_run_step()(); | 32 | std::cout << "\n*** cycle " << sched.now << "\n\n"; |
| 94 | if (res.has_value()) { | 33 | sched.clock(); |
| 95 | auto &es = *res; | ||
| 96 | if (es.first) { | ||
| 97 | auto &step = *es.first; | ||
| 98 | auto &w = es.second; | ||
| 99 | if (show_steps) | ||
| 100 | fmt::print("\t{}\n", step.disasm(&w)); | ||
| 101 | } else { | ||
| 102 | break; | ||
| 103 | } | ||
| 104 | } else { | ||
| 105 | fmt::print("Failed to complete step.\n"); | ||
| 106 | return 2; | ||
| 107 | } | ||
| 108 | } | 34 | } |
| 109 | 35 | ||
| 110 | fmt::print("Functional model exited.\n"); | 36 | delete fetch; |
| 37 | delete exec; | ||
| 38 | delete mem; | ||
| 111 | 39 | ||
| 112 | return 0; | 40 | return 0; |
| 113 | } | 41 | } |
