From eb3fd68203fee7c63245c702914c2acd3332d65a Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Thu, 22 Sep 2022 11:29:07 -0700 Subject: Initial commit. --- frontend/fetch.h | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 frontend/fetch.h (limited to 'frontend/fetch.h') diff --git a/frontend/fetch.h b/frontend/fetch.h new file mode 100644 index 0000000..0eaebd5 --- /dev/null +++ b/frontend/fetch.h @@ -0,0 +1,79 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "frontend/bundle.h" +#include "infra/pipetrace.h" +#include "infra/sim.h" +#include "memory/dram.h" + +namespace frontend { + struct fetch : public infra::sim { + struct restart { + unsigned int new_generation; + std::uint64_t previous_line_address; + std::uint64_t new_next_line_address; + }; + infra::port restartp; + + infra::port *commandp = nullptr; + infra::port responsep; + + infra::port *bundlep = nullptr; + + unsigned int generation = 0; + std::uint64_t next_line_address = 0; + + // FIXME make prediction table finite + std::map predictor; + + bool fill_request_sent = false; + + void clock() { + if (restartp.can_read()) { + auto r = restartp.read(); + generation = r.new_generation; + next_line_address = r.new_next_line_address; + fill_request_sent = false; + if (r.new_next_line_address == r.previous_line_address || r.new_next_line_address == r.previous_line_address + 1) + predictor.erase(r.previous_line_address); + else + predictor[r.previous_line_address] = r.new_next_line_address; + } + if (fill_request_sent && responsep.can_read() && bundlep->can_write()) { + auto r = responsep.read(); + if (r.line_address == next_line_address) { + bundle b; + b.transaction = r.transaction; + b.generation = generation; + b.line_address = next_line_address; + if (auto p = predictor.find(next_line_address); p != predictor.end()) + b.next_line_address = p->second; + else + b.next_line_address = next_line_address + 1; + next_line_address = b.next_line_address; + pte(b.transaction, "", fmt::format("next fetch line {:x}", next_line_address)); + b.data = std::move(r.data); + bundlep->write(std::move(b)); + fill_request_sent = false; + } + } + if (!fill_request_sent && commandp->can_write()) { + memory::dram::command c; + c.transaction = infra::pt::toplevel(); + pte(c.transaction, "F", fmt::format("fetch gen={}", generation)); + c.line_address = next_line_address; + c.responsep = &responsep; + commandp->write(std::move(c)); + fill_request_sent = true; + } + if (!fill_request_sent) + responsep.discard(); + } + }; +} -- cgit v1.2.3