From d61b441b2dae5a7928c42b1134250772e7db325a Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 21 Feb 2021 15:50:31 +0000 Subject: [PATCH] move execute_fsm to separate function in TestIssuer --- src/soc/simple/issuer.py | 147 ++++++++++++++++++++++----------------- 1 file changed, 82 insertions(+), 65 deletions(-) diff --git a/src/soc/simple/issuer.py b/src/soc/simple/issuer.py index 53368bce..214e8c3d 100644 --- a/src/soc/simple/issuer.py +++ b/src/soc/simple/issuer.py @@ -150,7 +150,6 @@ class TestIssuerInternal(Elaboratable): core_rst, cur_state, fetch_pc_ready_o, fetch_pc_valid_i, fetch_insn_valid_o, fetch_insn_ready_i, - msr_read, sv_read, fetch_insn_o): """fetch FSM this FSM performs fetch of raw instruction data, partial-decodes @@ -162,6 +161,9 @@ class TestIssuerInternal(Elaboratable): pdecode2 = self.pdecode2 svp64 = self.svp64 + msr_read = Signal(reset=1) + sv_read = Signal(reset=1) + with m.FSM(name='fetch_fsm'): # waiting (zzz) @@ -242,6 +244,81 @@ class TestIssuerInternal(Elaboratable): with m.If(fetch_insn_ready_i): m.next = "IDLE" + def execute_fsm(self, m, core, nia, + cur_state, fetch_insn_o, + fetch_pc_ready_o, fetch_pc_valid_i, + fetch_insn_valid_o, fetch_insn_ready_i): + """execute FSM + + decode / issue / execute FSM. this interacts with the "fetch" FSM + through fetch_pc_ready/valid (incoming) and fetch_insn_ready/valid + (outgoing). SVP64 RM prefixes have already been set up by the + "fetch" phase, so execute is fairly straightforward. + """ + + comb = m.d.comb + sync = m.d.sync + pdecode2 = self.pdecode2 + svp64 = self.svp64 + + # temporaries + dec_opcode_i = pdecode2.dec.raw_opcode_in # raw opcode + core_busy_o = core.busy_o # core is busy + core_ivalid_i = core.ivalid_i # instruction is valid + core_issue_i = core.issue_i # instruction is issued + insn_type = core.e.do.insn_type # instruction MicroOp type + + pc_changed = Signal() # note write to PC + + with m.FSM(): + + # go fetch the instruction at the current PC + # at this point, there is no instruction running, that + # could inadvertently update the PC. + with m.State("INSN_FETCH"): + comb += fetch_pc_valid_i.eq(1) + with m.If(fetch_pc_ready_o): + m.next = "INSN_WAIT" + + # decode the instruction when it arrives + with m.State("INSN_WAIT"): + comb += fetch_insn_ready_i.eq(1) + with m.If(fetch_insn_valid_o): + # decode the instruction + comb += dec_opcode_i.eq(fetch_insn_o) # actual opcode + sync += core.e.eq(pdecode2.e) + sync += core.state.eq(cur_state) + sync += core.raw_insn_i.eq(dec_opcode_i) + sync += core.bigendian_i.eq(self.core_bigendian_i) + # also drop PC and MSR into decode "state" + m.next = "INSN_START" # move to "start" + + # waiting for instruction bus (stays there until not busy) + with m.State("INSN_START"): + comb += core_ivalid_i.eq(1) # instruction is valid + comb += core_issue_i.eq(1) # and issued + sync += pc_changed.eq(0) + + m.next = "INSN_ACTIVE" # move to "wait completion" + + # instruction started: must wait till it finishes + with m.State("INSN_ACTIVE"): + with m.If(insn_type != MicrOp.OP_NOP): + comb += core_ivalid_i.eq(1) # instruction is valid + with m.If(self.state_nia.wen & (1<