summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Blake Kongslie2022-11-11 16:29:22 -0800
committerJulian Blake Kongslie2022-11-11 16:29:22 -0800
commita2c9de8fcc63a954b6486846b80c402a85d956ca (patch)
treedcfffddafa0edff1d63bb4cfca5609a556ae70a6
parentIgnore pipetrace files (diff)
downloadbiggolf-a2c9de8fcc63a954b6486846b80c402a85d956ca.tar.xz
Multi-word fetch bundles and icache with realistic dram latency
Diffstat (limited to '')
-rw-r--r--isa/decode.cpp2
-rw-r--r--main.cpp2
m---------nanosim0
-rw-r--r--uarch/core.cpp55
-rw-r--r--uarch/core.h27
5 files changed, 65 insertions, 21 deletions
diff --git a/isa/decode.cpp b/isa/decode.cpp
index 2151e2b..061fe5c 100644
--- a/isa/decode.cpp
+++ b/isa/decode.cpp
@@ -415,7 +415,7 @@ instruction_context decode(std::uint_fast32_t flags, unsigned int pc, unsigned i
415 default: 415 default:
416 inst.df = "IOT %b"; 416 inst.df = "IOT %b";
417 inst.ef = [bits](auto &ctx) { 417 inst.ef = [bits](auto &ctx) {
418 std::cerr << "warning: unimplemented IOT device " << ((bits >> 6) & 07) << ((bits >> 3) & 07) << " suboperation " << (bits & 07) << "\n"; 418 //std::cerr << "warning: unimplemented IOT device " << ((bits >> 6) & 07) << ((bits >> 3) & 07) << " suboperation " << (bits & 07) << "\n";
419 }; 419 };
420 } 420 }
421 break; 421 break;
diff --git a/main.cpp b/main.cpp
index 4fec1f4..226fc31 100644
--- a/main.cpp
+++ b/main.cpp
@@ -79,7 +79,7 @@ int main(int argc, const char *argv[]) {
79 std::ofstream pt("bug.pt"); 79 std::ofstream pt("bug.pt");
80 infra::pt::ptfile = &pt; 80 infra::pt::ptfile = &pt;
81 81
82 while (!core.checker.done()) { 82 for (unsigned int cycles = 0; !core.checker.done() && cycles < 500000; ++cycles) {
83// if (!checker.ctlregs[HALTED]) { 83// if (!checker.ctlregs[HALTED]) {
84// if (checker.inst.final_address.has_value()) 84// if (checker.inst.final_address.has_value())
85// std::cout << fmt::format("{:05o} {:01o} {:04o} {:04o} {:005o}\n", checker.pc, checker.link, checker.acc, checker.mq, *checker.inst.final_address); 85// std::cout << fmt::format("{:05o} {:01o} {:04o} {:04o} {:005o}\n", checker.pc, checker.link, checker.acc, checker.mq, *checker.inst.final_address);
diff --git a/nanosim b/nanosim
Subproject 3c43115056a1622d97de05fbc56c38e2013cfc1 Subproject db82579d3c023c441c895d26d32de3fa039eafa
diff --git a/uarch/core.cpp b/uarch/core.cpp
index 34f422a..8b2db9b 100644
--- a/uarch/core.cpp
+++ b/uarch/core.cpp
@@ -25,21 +25,38 @@ void fetch_stage::clock() {
25 gen = r.new_gen; 25 gen = r.new_gen;
26 pc = r.new_pc; 26 pc = r.new_pc;
27 didrestart = true; 27 didrestart = true;
28 outstandingfill = false;
28 c.fetch_restarto.reset(); 29 c.fetch_restarto.reset();
29 } 30 }
30 31
32 if (c.fetch_mem_responsep.can_read()) {
33 auto r = c.fetch_mem_responsep.read();
34 cache.handle_response(r);
35 }
36
31 if (c.fetch_bundlep.can_write()) { 37 if (c.fetch_bundlep.can_write()) {
32 fetch_bundle b; 38 fetch_bundle b;
33 b.tr = infra::pt::toplevel(); 39 if (auto t = cache.fetchline(b.data, pc); t.has_value()) {
34 b.gen = gen; 40 b.tr = infra::pt::toplevel();
35 b.pc = pc; 41 b.gen = gen;
36 b.word = c.mem.fetch(pc); 42 b.pc = pc;
37 if (didrestart) 43 if (didrestart)
38 infra::pt::event(b.tr, ">", now-1, ""); 44 infra::pt::event(b.tr, ">", now-1, "");
39 pte(b.tr, "F"); 45 pte(b.tr, "F", fmt::format("pc={:05o}", b.pc));
40 c.fetch_bundlep.write(std::move(b)); 46 c.fetch_bundlep.write(std::move(b));
41 pc = (pc & 070000) | ((pc + 1) & 007777); 47 pc = (pc & 070000) | (((pc & ~memory::LINE_BYTE_OFFSET_MASK) + memory::LINE_BYTES) & 007777);
42 didrestart = false; 48 didrestart = false;
49 outstandingfill = false;
50 }
51 }
52
53 if (!outstandingfill && c./*fetch_*/mem_commandp.can_write() && !cache.probe(pc)) {
54 memory::dram::command fr;
55 fr.transaction = infra::pt::toplevel();
56 fr.line_address = pc >> memory::LINE_BYTES_LOG2;
57 fr.responsep = &c.fetch_mem_responsep;
58 c./*fetch_*/mem_commandp.write(std::move(fr));
59 outstandingfill = true;
43 } 60 }
44} 61}
45 62
@@ -47,28 +64,31 @@ void decode_stage::clock() {
47 bool progress = ctlregs[HALTED]; 64 bool progress = ctlregs[HALTED];
48 65
49 if (!ctlregs[HALTED] && c.fetch_bundlep.can_read()) { 66 if (!ctlregs[HALTED] && c.fetch_bundlep.can_read()) {
50 auto b = c.fetch_bundlep.read(); 67 auto b = c.fetch_bundlep.peek();
51 68
52 if (b.gen != gen) 69 if (b.gen != gen)
53 goto bail_out; 70 goto bail_out;
54 71
55 if (b.pc != pc) { 72 if ((b.pc >> memory::LINE_BYTES_LOG2) != (pc >> memory::LINE_BYTES_LOG2)) {
56 pte(b.tr, "~"); 73 pte(b.tr, "~");
57 fetch_restart r; 74 fetch_restart r;
58 r.tr = b.tr; 75 r.tr = b.tr;
59 r.new_gen = ++gen; 76 r.new_gen = ++gen;
60 r.new_pc = pc; 77 r.new_pc = pc;
61 c.fetch_restarto = std::move(r); 78 c.fetch_restarto = std::move(r);
79 c.fetch_bundlep.discard();
62 goto bail_out; 80 goto bail_out;
63 } 81 }
64 82
65 progress = true; 83 progress = true;
66 84
67 pte(b.tr, "E"); 85 auto tr = infra::pt::child(b.tr);
86
87 pte(tr, "E");
68 88
69 inst = decode(ctlregs[FLAGS], 89 inst = decode(ctlregs[FLAGS],
70 pc, 90 pc,
71 c.mem.fetch(pc), 91 b.data[pc & memory::LINE_BYTE_OFFSET_MASK],
72 interrupt); 92 interrupt);
73 auto next_pc = inst.next_pc; 93 auto next_pc = inst.next_pc;
74 94
@@ -84,7 +104,7 @@ void decode_stage::clock() {
84 assert(!inst.need_autoinc_store); 104 assert(!inst.need_autoinc_store);
85 } 105 }
86 106
87 pte(b.tr, "", inst.disasm()); 107 pte(tr, "", inst.disasm());
88 108
89 if (inst.need_exec_load) 109 if (inst.need_exec_load)
90 inst.data = c.mem.fetch(inst.final_address.value()); 110 inst.data = c.mem.fetch(inst.final_address.value());
@@ -114,6 +134,9 @@ void decode_stage::clock() {
114 134
115 assert(inst.next_pc == next_pc || inst.possibly_redirects); 135 assert(inst.next_pc == next_pc || inst.possibly_redirects);
116 pc = inst.next_pc; 136 pc = inst.next_pc;
137
138 if ((b.pc >> memory::LINE_BYTES_LOG2) != (pc >> memory::LINE_BYTES_LOG2))
139 c.fetch_bundlep.discard();
117 } 140 }
118bail_out: 141bail_out:
119 142
@@ -125,7 +148,7 @@ bail_out:
125 148
126 c.checker.execute(); 149 c.checker.execute();
127 assert(c.checker.icount == icount); 150 assert(c.checker.icount == icount);
128 std::cerr << fmt::format("icount={:} pc={:05o} checkerpc={:05o}\n", icount, pc, c.checker.pc); 151// std::cerr << fmt::format("icount={:} pc={:05o} checkerpc={:05o}\n", icount, pc, c.checker.pc);
129 assert(pc == c.checker.pc); 152 assert(pc == c.checker.pc);
130 assert(acc == c.checker.acc); 153 assert(acc == c.checker.acc);
131 assert(link == c.checker.link); 154 assert(link == c.checker.link);
diff --git a/uarch/core.h b/uarch/core.h
index 0f9be74..a6772f3 100644
--- a/uarch/core.h
+++ b/uarch/core.h
@@ -2,11 +2,14 @@
2 2
3#include <array> 3#include <array>
4 4
5#include "infra/arbiter.h"
5#include "infra/pipetrace.h" 6#include "infra/pipetrace.h"
6#include "infra/port.h" 7#include "infra/port.h"
7#include "io/model.h" 8#include "io/model.h"
8#include "isa/checker.h" 9#include "isa/checker.h"
9#include "isa/isa.h" 10#include "isa/isa.h"
11#include "memory/cache.h"
12#include "memory/dram.h"
10 13
11struct core; 14struct core;
12 15
@@ -14,7 +17,7 @@ struct fetch_bundle {
14 infra::transaction tr; 17 infra::transaction tr;
15 unsigned int gen; 18 unsigned int gen;
16 unsigned int pc; 19 unsigned int pc;
17 unsigned int word; 20 memory::line data;
18}; 21};
19 22
20struct fetch_restart { 23struct fetch_restart {
@@ -26,9 +29,12 @@ struct fetch_restart {
26struct fetch_stage : public infra::sim { 29struct fetch_stage : public infra::sim {
27 core &c; 30 core &c;
28 31
32 memory::inline_cache<8, 2> cache;
33
29 unsigned int gen = 0; 34 unsigned int gen = 0;
30 unsigned int pc; 35 unsigned int pc;
31 bool didrestart = false; 36 bool didrestart = false;
37 bool outstandingfill = false;
32 38
33 fetch_stage(core &c); 39 fetch_stage(core &c);
34 40
@@ -49,6 +55,7 @@ struct decode_stage : public infra::sim {
49 std::array<uint_fast32_t, NUM_CTLREGS> ctlregs; 55 std::array<uint_fast32_t, NUM_CTLREGS> ctlregs;
50 std::uint64_t icount; 56 std::uint64_t icount;
51 instruction_context inst; 57 instruction_context inst;
58 bool outstandingfill = false;
52 59
53 decode_stage(core &c); 60 decode_stage(core &c);
54 61
@@ -58,11 +65,20 @@ struct decode_stage : public infra::sim {
58struct core { 65struct core {
59 iomodel &system; 66 iomodel &system;
60 funcchecker checker; 67 funcchecker checker;
61 funcmem mem;
62 68
69 memory::dram mem{12};
70 infra::port<memory::dram::command> mem_commandp;
71
72 infra::priority_arbiter<memory::dram::command, 2> mem_command_arb;
73
74 infra::port<memory::dram::command> fetch_mem_commandp;
75 infra::port<memory::dram::response> fetch_mem_responsep;
63 infra::port<fetch_bundle> fetch_bundlep; 76 infra::port<fetch_bundle> fetch_bundlep;
64 std::optional<fetch_restart> fetch_restarto; 77 std::optional<fetch_restart> fetch_restarto;
65 78
79 infra::port<memory::dram::command> decode_mem_commandp;
80 infra::port<memory::dram::response> decode_mem_responsep;
81
66 // Construction order is execution order within a cycle, so this list should be back-to-front (for zero-cycle restarts) 82 // Construction order is execution order within a cycle, so this list should be back-to-front (for zero-cycle restarts)
67 decode_stage decode{*this}; 83 decode_stage decode{*this};
68 fetch_stage fetch{*this}; 84 fetch_stage fetch{*this};
@@ -70,5 +86,10 @@ struct core {
70 core(iomodel &model) 86 core(iomodel &model)
71 : system(model) 87 : system(model)
72 , checker(model) 88 , checker(model)
73 { } 89 {
90 mem.commandp = &mem_commandp;
91 mem_command_arb.outp = &mem_commandp;
92 mem_command_arb.peerp[0] = &decode_mem_commandp;
93 mem_command_arb.peerp[1] = &fetch_mem_commandp;
94 }
74}; 95};