From: Luke Kenneth Casson Leighton Date: Sun, 9 May 2021 19:32:45 +0000 (+0100) Subject: move (unused) ACK_WAIT code into FSM X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5f4d5b03ecaf16c7aab952692edc902720553f54;p=soc.git move (unused) ACK_WAIT code into FSM remove another (unneeded) state, FINISH_LFS sort-of got ACK_WAIT to flip over to IDLE but done has to be asserted for longer than necessary. needs investigating --- diff --git a/src/soc/fu/ldst/loadstore.py b/src/soc/fu/ldst/loadstore.py index f3544b08..ef332efd 100644 --- a/src/soc/fu/ldst/loadstore.py +++ b/src/soc/fu/ldst/loadstore.py @@ -29,8 +29,7 @@ class State(Enum): ACK_WAIT = 1 # waiting for ack from dcache MMU_LOOKUP = 2 # waiting for MMU to look up translation TLBIE_WAIT = 3 # waiting for MMU to finish doing a tlbie - FINISH_LFS = 4 # write back converted SP data for lfs* - COMPLETE = 5 # extra cycle to complete an operation + COMPLETE = 4 # extra cycle to complete an operation # glue logic for microwatt mmu and dcache @@ -176,34 +175,38 @@ class LoadStore1(PortInterfaceBase): # fsm skeleton with m.Switch(self.state): with m.Case(State.IDLE): - pass - with m.Case(State.ACK_WAIT): - pass + with m.If(self.d_validblip): + sync += self.state.eq(State.ACK_WAIT) + + with m.Case(State.ACK_WAIT): # waiting for completion + with m.If(d_out.error): + with m.If(d_out.cache_paradox): + sync += self.derror.eq(1) + sync += self.state.eq(State.IDLE) + sync += self.dsisr[63 - 38].eq(~self.load) + # XXX there is no architected bit for this + # (probably should be a machine check in fact) + sync += self.dsisr[63 - 35].eq(d_out.cache_paradox) + + with m.Else(): + # Look up the translation for TLB miss + # and also for permission error and RC error + # in case the PTE has been updated. + sync += self.mmureq.eq(1) + sync += self.state.eq(State.MMU_LOOKUP) + with m.If(d_out.valid): + m.d.comb += self.done.eq(1) + sync += self.state.eq(State.IDLE) + with m.If(self.load): + m.d.comb += self.load_data.eq(d_out.data) + with m.Case(State.MMU_LOOKUP): pass with m.Case(State.TLBIE_WAIT): pass - with m.Case(State.FINISH_LFS): - pass with m.Case(State.COMPLETE): pass - # microwatt: only if State.ACK_WAIZ - with m.If(d_out.error): - with m.If(d_out.cache_paradox): - sync += self.derror.eq(1) - sync += self.dsisr[63 - 38].eq(~self.load) - # XXX there is no architected bit for this - # (probably should be a machine check in fact) - sync += self.dsisr[63 - 35].eq(d_out.cache_paradox) - - with m.Else(): - # Look up the translation for TLB miss - # and also for permission error and RC error - # in case the PTE has been updated. - sync += self.mmureq.eq(1) - sync += self.state.eq(State.MMU_LOOKUP) - exc = self.pi.exc_o # happened, alignment, instr_fault, invalid. @@ -252,6 +255,9 @@ class LoadStore1(PortInterfaceBase): m.d.comb += d_in.byte_sel.eq(self.byte_sel) m.d.comb += d_in.addr.eq(self.addr) m.d.comb += d_in.nc.eq(self.nc) + + # XXX these should be possible to remove but for some reason + # cannot be... yet. TODO, investigate m.d.comb += self.done.eq(d_out.valid) m.d.comb += self.load_data.eq(d_out.data)