From e4b8ab4151fd21af0c9a7958df3c05026332b760 Mon Sep 17 00:00:00 2001 From: Cesar Strauss Date: Sun, 7 Mar 2021 08:49:55 -0300 Subject: [PATCH] Merge WAIT_RESET into INSN_FETCH on the Issue FSM In a VL==0 loop, while we are skipping vector instructions, there needs to be a way to stop the core. Unfortunately, this means duplicating the corresponding code at instruction end, since there is no state in common on either loop (the VL==0 instruction skip loop and the VL>1 vector loop). This does makes it a little non-deterministic. Normally, we would stop the core at instruction end, but could instead end up stopping at instruction start. For this to happen, you need to stop the core at the right moment, just after the instruction ended and before the next instruction begins. A way to avoid this, if necessary, would be to create a duplicate of the INSN_FETCH state, that doesn't wait on "core stop" release. Since we are now waiting on "core stop" release at instruction start anyway, there is no need for the special WAIT_RESET state anymore. --- src/soc/simple/issuer.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/soc/simple/issuer.py b/src/soc/simple/issuer.py index f13f5672..ca561f8b 100644 --- a/src/soc/simple/issuer.py +++ b/src/soc/simple/issuer.py @@ -269,10 +269,16 @@ class TestIssuerInternal(Elaboratable): with m.FSM(name="issue_fsm"): - # Wait on "core stop" release, at reset - with m.State("WAIT_RESET"): + # 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"): + # wait on "core stop" release, before next fetch + # need to do this here, in case we are in a VL==0 loop with m.If(~dbg.core_stop_o & ~core_rst): - m.next = "INSN_FETCH" + comb += fetch_pc_valid_i.eq(1) + with m.If(fetch_pc_ready_o): + m.next = "INSN_WAIT" with m.Else(): comb += core.core_stopped_i.eq(1) comb += dbg.core_stopped_i.eq(1) @@ -286,15 +292,6 @@ class TestIssuerInternal(Elaboratable): comb += update_svstate.eq(1) sync += sv_changed.eq(1) - # 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"): - # TODO: update PC here, before 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) @@ -325,6 +322,7 @@ class TestIssuerInternal(Elaboratable): with m.State("EXECUTE_WAIT"): # wait on "core stop" release, at instruction end + # need to do this here, in case we are in a VL>1 loop with m.If(~dbg.core_stop_o & ~core_rst): comb += exec_pc_ready_i.eq(1) with m.If(exec_pc_valid_o): -- 2.30.2