From ec413b7dd47fbc92a103947afb4f653ce29ad0d6 Mon Sep 17 00:00:00 2001 From: Cesar Strauss Date: Sat, 6 Feb 2021 17:53:22 -0300 Subject: [PATCH] Extract the fetch FSM out from the main FSM Allows future extension to prefixed instructions, as well as being an opportunity for pipeline optimization. At start, the fetch FSM waits for the PC to be stable. This happens when there is no longer an instruction being executed. When done, it hands over the instruction to the decoder. --- src/soc/simple/issuer.py | 76 +++++++++++++++++++++--------- src/soc/simple/test/test_issuer.py | 5 +- 2 files changed, 59 insertions(+), 22 deletions(-) diff --git a/src/soc/simple/issuer.py b/src/soc/simple/issuer.py index d662dff4..1021fa7a 100644 --- a/src/soc/simple/issuer.py +++ b/src/soc/simple/issuer.py @@ -237,34 +237,41 @@ class TestIssuerInternal(Elaboratable): insn_type = core.e.do.insn_type + # handshake signals between fetch and decode/execute + # fetch FSM can run as soon as the PC is valid + fetch_pc_valid_i = Signal() + fetch_pc_ready_o = Signal() + # when done, deliver the instruction to the next FSM + fetch_insn_o = Signal(32, reset_less=True) + fetch_insn_valid_o = Signal() + fetch_insn_ready_i = Signal() + # actually use a nmigen FSM for the first time (w00t) # this FSM is perhaps unusual in that it detects conditions # then "holds" information, combinatorially, for the core # (as opposed to using sync - which would be on a clock's delay) # this includes the actual opcode, valid flags and so on. - with m.FSM() as fsm: + with m.FSM(name='fetch_fsm'): # waiting (zzz) with m.State("IDLE"): - sync += pc_changed.eq(0) - sync += core.e.eq(0) - sync += core.raw_insn_i.eq(0) - sync += core.bigendian_i.eq(0) with m.If(~dbg.core_stop_o & ~core_rst): - # instruction allowed to go: start by reading the PC - # capture the PC and also drop it into Insn Memory - # we have joined a pair of combinatorial memory - # lookups together. this is Generally Bad. - comb += self.imem.a_pc_i.eq(pc) - comb += self.imem.a_valid_i.eq(1) - comb += self.imem.f_valid_i.eq(1) - sync += cur_state.pc.eq(pc) - - # initiate read of MSR. arrives one clock later - comb += self.state_r_msr.ren.eq(1<