From fdb61389099cee41b86c25c3d1ddb660b509e5fa Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Sat, 19 Nov 2022 16:29:27 -0800 Subject: Pipelined microarchitecture, which even almost works! Includes such horrors as the "unstore" operation for undoing autoincremented addresses on instructions subsequently found to be bogus. --- uarch/core.h | 74 ++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 14 deletions(-) (limited to 'uarch/core.h') 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 @@ struct core; +struct restart { + infra::transaction tr; + unsigned int new_pc; + bool interrupt; +}; + struct fetch_bundle { infra::transaction tr; unsigned int gen; @@ -20,10 +26,12 @@ struct fetch_bundle { memory::line data; }; -struct fetch_restart { +struct inst_bundle { infra::transaction tr; - unsigned int new_gen; - unsigned int new_pc; + unsigned int gen; + unsigned int pc; + std::uint64_t icount; + instruction_context inst; }; struct fetch_stage : public infra::sim { @@ -31,8 +39,8 @@ struct fetch_stage : public infra::sim { memory::inline_cache<8, 2> cache; - unsigned int gen = 0; unsigned int pc; + bool didrestart = false; bool outstandingfill = false; @@ -44,20 +52,38 @@ struct fetch_stage : public infra::sim { struct decode_stage : public infra::sim { core &c; + bool interrupt = false; + + unsigned int pc; + std::uint64_t icount; + + decode_stage(core &c); + + void clock(); +}; + +struct indir_stage : public infra::sim { + core &c; + unsigned int gen = 0; - bool interrupt = false; + indir_stage(core &c); + + void clock(); +}; + +struct exec_stage : public infra::sim { + core &c; + + unsigned int gen = 0; 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); + exec_stage(core &c); void clock(); }; @@ -66,30 +92,50 @@ struct core { iomodel &system; funcchecker checker; - memory::dram mem{12}; + std::optional restarto; + unsigned int gen = 0; + + std::uint64_t icount; + + memory::dram mem{0}; infra::port mem_commandp; - infra::priority_arbiter mem_command_arb; + 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; + infra::port decode_to_exec_instp; + + infra::port indir_instp; + infra::port indir_mem_load_commandp; + infra::port indir_mem_store_commandp; + infra::port indir_mem_responsep; + infra::port indir_to_exec_instp; + + infra::port exec_mem_commandp; + infra::port exec_mem_responsep; // Construction order is execution order within a cycle, so this list should be back-to-front (for zero-cycle restarts) + exec_stage exec{*this}; + indir_stage indir{*this}; decode_stage decode{*this}; fetch_stage fetch{*this}; core(iomodel &model) : system(model) , checker(model) + , icount(checker.icount) { 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; + mem_command_arb.peerp[0] = &exec_mem_commandp; + mem_command_arb.peerp[1] = &indir_mem_store_commandp; + mem_command_arb.peerp[2] = &indir_mem_load_commandp; + mem_command_arb.peerp[3] = &decode_mem_commandp; + mem_command_arb.peerp[4] = &fetch_mem_commandp; } }; -- cgit v1.2.3