#pragma once #include #include "infra/arbiter.h" #include "infra/pipetrace.h" #include "infra/port.h" #include "io/model.h" #include "isa/checker.h" #include "isa/isa.h" #include "memory/cache.h" #include "memory/dram.h" struct core; struct fetch_bundle { infra::transaction tr; unsigned int gen; unsigned int pc; memory::line data; }; struct fetch_restart { infra::transaction tr; unsigned int new_gen; unsigned int new_pc; }; struct fetch_stage : public infra::sim { core &c; memory::inline_cache<8, 2> cache; unsigned int gen = 0; unsigned int pc; bool didrestart = false; bool outstandingfill = false; fetch_stage(core &c); void clock(); }; struct decode_stage : public infra::sim { core &c; unsigned int gen = 0; bool interrupt = false; unsigned int acc; unsigned int link; unsigned int mq; unsigned int pc; std::array ctlregs; std::uint64_t icount; instruction_context inst; bool outstandingfill = false; decode_stage(core &c); void clock(); }; struct core { iomodel &system; funcchecker checker; memory::dram mem{12}; infra::port mem_commandp; infra::priority_arbiter mem_command_arb; infra::port fetch_mem_commandp; infra::port fetch_mem_responsep; infra::port fetch_bundlep; std::optional fetch_restarto; infra::port decode_mem_commandp; infra::port decode_mem_responsep; // Construction order is execution order within a cycle, so this list should be back-to-front (for zero-cycle restarts) decode_stage decode{*this}; fetch_stage fetch{*this}; core(iomodel &model) : system(model) , checker(model) { mem.commandp = &mem_commandp; mem_command_arb.outp = &mem_commandp; mem_command_arb.peerp[0] = &decode_mem_commandp; mem_command_arb.peerp[1] = &fetch_mem_commandp; } };