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. --- backend/exec.h | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 backend/exec.h (limited to 'backend/exec.h') diff --git a/backend/exec.h b/backend/exec.h new file mode 100644 index 0000000..f1474b8 --- /dev/null +++ b/backend/exec.h @@ -0,0 +1,72 @@ +#pragma once + +#include "infra/port.h" +#include "inst.h" +#include "memory/dram.h" + +namespace backend { + struct exec : public infra::sim { + infra::port execp; + infra::port *writebackp = nullptr; + infra::port *loadp = nullptr; + infra::port loadresultp; + + infra::port stallp; + + void clock() { + if (stallp.can_read() && writebackp->can_write()) { + const auto &i = stallp.peek(); + switch (i.field[OPCODE]) { + case OP_LOAD: + if (loadresultp.can_read()) { + auto i = stallp.read(); + auto addr = i.field[SRC1] + i.field[SRC2]; + auto offset = addr & memory::LINE_BYTE_OFFSET_MASK; + pte(i.transaction, "", fmt::format("addr={:x} offset={:x}", addr, offset)); + auto f = loadresultp.read(); + std::uint64_t r = 0; + for (unsigned int i = 0; i < sizeof(r); ++i) + r |= f.data[i + offset] << (8 * i); + i.result = r; + writebackp->write(std::move(i)); + } + break; + } + } else if (execp.can_read() && writebackp->can_write() && loadp->can_write()) { + auto i = execp.read(); + pte(i.transaction, "E", fmt::format("exec gen={} op={:x} a={:x} b={:x}", i.generation, i.field[OPCODE], i.field[SRC1], i.field[SRC2])); + switch (i.field[OPCODE]) { + case OP_JUMP_ABS_IF_ZERO: + if (i.field[SRC2] == 0) + i.result = i.field[SRC1]; + else + i.result = i.linear_next_pc; + break; + case OP_JUMP_ABS_IF_NONZERO: + if (i.field[SRC2] != 0) + i.result = i.field[SRC1]; + else + i.result = i.linear_next_pc; + break; + case OP_EMIT: + case OP_ADD: + i.result = i.field[SRC1] + i.field[SRC2]; + break; + case OP_LOAD: + { + memory::dram::command c; + c.transaction = i.transaction; + c.line_address = (i.field[SRC1] + i.field[SRC2]) >> memory::LINE_BYTES_LOG2; + c.write = false; + c.responsep = &loadresultp; + loadp->write(std::move(c)); + } + stallp.write(std::move(i)); + break; + } + if (stallp.can_write()) + writebackp->write(std::move(i)); + } + } + }; +} -- cgit v1.2.3