diff options
| author | Julian Blake Kongslie | 2022-11-19 16:29:27 -0800 |
|---|---|---|
| committer | Julian Blake Kongslie | 2022-11-19 16:29:27 -0800 |
| commit | fdb61389099cee41b86c25c3d1ddb660b509e5fa (patch) | |
| tree | 00ebbec2b5a3398ea71442d5cd124a64bd61d80a /uarch/core.h | |
| parent | Multi-word fetch bundles and icache with realistic dram latency (diff) | |
| download | biggolf-fdb61389099cee41b86c25c3d1ddb660b509e5fa.tar.xz | |
Pipelined microarchitecture, which even almost works!
Includes such horrors as the "unstore" operation for undoing
autoincremented addresses on instructions subsequently found to be
bogus.
Diffstat (limited to 'uarch/core.h')
| -rw-r--r-- | uarch/core.h | 74 |
1 files changed, 60 insertions, 14 deletions
diff --git a/uarch/core.h b/uarch/core.h index a6772f3..b53a205 100644 --- a/uarch/core.h +++ b/uarch/core.h | |||
| @@ -13,6 +13,12 @@ | |||
| 13 | 13 | ||
| 14 | struct core; | 14 | struct core; |
| 15 | 15 | ||
| 16 | struct restart { | ||
| 17 | infra::transaction tr; | ||
| 18 | unsigned int new_pc; | ||
| 19 | bool interrupt; | ||
| 20 | }; | ||
| 21 | |||
| 16 | struct fetch_bundle { | 22 | struct fetch_bundle { |
| 17 | infra::transaction tr; | 23 | infra::transaction tr; |
| 18 | unsigned int gen; | 24 | unsigned int gen; |
| @@ -20,10 +26,12 @@ struct fetch_bundle { | |||
| 20 | memory::line data; | 26 | memory::line data; |
| 21 | }; | 27 | }; |
| 22 | 28 | ||
| 23 | struct fetch_restart { | 29 | struct inst_bundle { |
| 24 | infra::transaction tr; | 30 | infra::transaction tr; |
| 25 | unsigned int new_gen; | 31 | unsigned int gen; |
| 26 | unsigned int new_pc; | 32 | unsigned int pc; |
| 33 | std::uint64_t icount; | ||
| 34 | instruction_context inst; | ||
| 27 | }; | 35 | }; |
| 28 | 36 | ||
| 29 | struct fetch_stage : public infra::sim { | 37 | struct fetch_stage : public infra::sim { |
| @@ -31,8 +39,8 @@ struct fetch_stage : public infra::sim { | |||
| 31 | 39 | ||
| 32 | memory::inline_cache<8, 2> cache; | 40 | memory::inline_cache<8, 2> cache; |
| 33 | 41 | ||
| 34 | unsigned int gen = 0; | ||
| 35 | unsigned int pc; | 42 | unsigned int pc; |
| 43 | |||
| 36 | bool didrestart = false; | 44 | bool didrestart = false; |
| 37 | bool outstandingfill = false; | 45 | bool outstandingfill = false; |
| 38 | 46 | ||
| @@ -44,20 +52,38 @@ struct fetch_stage : public infra::sim { | |||
| 44 | struct decode_stage : public infra::sim { | 52 | struct decode_stage : public infra::sim { |
| 45 | core &c; | 53 | core &c; |
| 46 | 54 | ||
| 55 | bool interrupt = false; | ||
| 56 | |||
| 57 | unsigned int pc; | ||
| 58 | std::uint64_t icount; | ||
| 59 | |||
| 60 | decode_stage(core &c); | ||
| 61 | |||
| 62 | void clock(); | ||
| 63 | }; | ||
| 64 | |||
| 65 | struct indir_stage : public infra::sim { | ||
| 66 | core &c; | ||
| 67 | |||
| 47 | unsigned int gen = 0; | 68 | unsigned int gen = 0; |
| 48 | 69 | ||
| 49 | bool interrupt = false; | 70 | indir_stage(core &c); |
| 71 | |||
| 72 | void clock(); | ||
| 73 | }; | ||
| 74 | |||
| 75 | struct exec_stage : public infra::sim { | ||
| 76 | core &c; | ||
| 77 | |||
| 78 | unsigned int gen = 0; | ||
| 50 | 79 | ||
| 51 | unsigned int acc; | 80 | unsigned int acc; |
| 52 | unsigned int link; | 81 | unsigned int link; |
| 53 | unsigned int mq; | 82 | unsigned int mq; |
| 54 | unsigned int pc; | 83 | unsigned int pc; |
| 55 | std::array<uint_fast32_t, NUM_CTLREGS> ctlregs; | 84 | std::array<uint_fast32_t, NUM_CTLREGS> ctlregs; |
| 56 | std::uint64_t icount; | ||
| 57 | instruction_context inst; | ||
| 58 | bool outstandingfill = false; | ||
| 59 | 85 | ||
| 60 | decode_stage(core &c); | 86 | exec_stage(core &c); |
| 61 | 87 | ||
| 62 | void clock(); | 88 | void clock(); |
| 63 | }; | 89 | }; |
| @@ -66,30 +92,50 @@ struct core { | |||
| 66 | iomodel &system; | 92 | iomodel &system; |
| 67 | funcchecker checker; | 93 | funcchecker checker; |
| 68 | 94 | ||
| 69 | memory::dram mem{12}; | 95 | std::optional<restart> restarto; |
| 96 | unsigned int gen = 0; | ||
| 97 | |||
| 98 | std::uint64_t icount; | ||
| 99 | |||
| 100 | memory::dram mem{0}; | ||
| 70 | infra::port<memory::dram::command> mem_commandp; | 101 | infra::port<memory::dram::command> mem_commandp; |
| 71 | 102 | ||
| 72 | infra::priority_arbiter<memory::dram::command, 2> mem_command_arb; | 103 | infra::priority_arbiter<memory::dram::command, 5> mem_command_arb; |
| 73 | 104 | ||
| 74 | infra::port<memory::dram::command> fetch_mem_commandp; | 105 | infra::port<memory::dram::command> fetch_mem_commandp; |
| 75 | infra::port<memory::dram::response> fetch_mem_responsep; | 106 | infra::port<memory::dram::response> fetch_mem_responsep; |
| 76 | infra::port<fetch_bundle> fetch_bundlep; | 107 | infra::port<fetch_bundle> fetch_bundlep; |
| 77 | std::optional<fetch_restart> fetch_restarto; | ||
| 78 | 108 | ||
| 79 | infra::port<memory::dram::command> decode_mem_commandp; | 109 | infra::port<memory::dram::command> decode_mem_commandp; |
| 80 | infra::port<memory::dram::response> decode_mem_responsep; | 110 | infra::port<memory::dram::response> decode_mem_responsep; |
| 111 | infra::port<inst_bundle> decode_to_exec_instp; | ||
| 112 | |||
| 113 | infra::port<inst_bundle> indir_instp; | ||
| 114 | infra::port<memory::dram::command> indir_mem_load_commandp; | ||
| 115 | infra::port<memory::dram::command> indir_mem_store_commandp; | ||
| 116 | infra::port<memory::dram::response> indir_mem_responsep; | ||
| 117 | infra::port<inst_bundle> indir_to_exec_instp; | ||
| 118 | |||
| 119 | infra::port<memory::dram::command> exec_mem_commandp; | ||
| 120 | infra::port<memory::dram::response> exec_mem_responsep; | ||
| 81 | 121 | ||
| 82 | // Construction order is execution order within a cycle, so this list should be back-to-front (for zero-cycle restarts) | 122 | // Construction order is execution order within a cycle, so this list should be back-to-front (for zero-cycle restarts) |
| 123 | exec_stage exec{*this}; | ||
| 124 | indir_stage indir{*this}; | ||
| 83 | decode_stage decode{*this}; | 125 | decode_stage decode{*this}; |
| 84 | fetch_stage fetch{*this}; | 126 | fetch_stage fetch{*this}; |
| 85 | 127 | ||
| 86 | core(iomodel &model) | 128 | core(iomodel &model) |
| 87 | : system(model) | 129 | : system(model) |
| 88 | , checker(model) | 130 | , checker(model) |
| 131 | , icount(checker.icount) | ||
| 89 | { | 132 | { |
| 90 | mem.commandp = &mem_commandp; | 133 | mem.commandp = &mem_commandp; |
| 91 | mem_command_arb.outp = &mem_commandp; | 134 | mem_command_arb.outp = &mem_commandp; |
| 92 | mem_command_arb.peerp[0] = &decode_mem_commandp; | 135 | mem_command_arb.peerp[0] = &exec_mem_commandp; |
| 93 | mem_command_arb.peerp[1] = &fetch_mem_commandp; | 136 | mem_command_arb.peerp[1] = &indir_mem_store_commandp; |
| 137 | mem_command_arb.peerp[2] = &indir_mem_load_commandp; | ||
| 138 | mem_command_arb.peerp[3] = &decode_mem_commandp; | ||
| 139 | mem_command_arb.peerp[4] = &fetch_mem_commandp; | ||
| 94 | } | 140 | } |
| 95 | }; | 141 | }; |
