summaryrefslogtreecommitdiff
path: root/uarch/core.h
diff options
context:
space:
mode:
authorJulian Blake Kongslie2022-11-19 16:29:27 -0800
committerJulian Blake Kongslie2022-11-19 16:29:27 -0800
commitfdb61389099cee41b86c25c3d1ddb660b509e5fa (patch)
tree00ebbec2b5a3398ea71442d5cd124a64bd61d80a /uarch/core.h
parentMulti-word fetch bundles and icache with realistic dram latency (diff)
downloadbiggolf-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 '')
-rw-r--r--uarch/core.h74
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
14struct core; 14struct core;
15 15
16struct restart {
17 infra::transaction tr;
18 unsigned int new_pc;
19 bool interrupt;
20};
21
16struct fetch_bundle { 22struct 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
23struct fetch_restart { 29struct 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
29struct fetch_stage : public infra::sim { 37struct 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 {
44struct decode_stage : public infra::sim { 52struct 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
65struct 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
75struct 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};