From: Luke Kenneth Casson Leighton Date: Fri, 14 May 2021 11:09:55 +0000 (+0100) Subject: sort out LoadStore1 misalignment FSM, also required test function pi_ld X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2b93e5167f843c226d30f630b5d871d379aa6be0;p=soc.git sort out LoadStore1 misalignment FSM, also required test function pi_ld to be modified to understand exceptions. pi_st TODO --- diff --git a/src/soc/config/test/test_pi2ls.py b/src/soc/config/test/test_pi2ls.py index f1807ccf..bb363a38 100644 --- a/src/soc/config/test/test_pi2ls.py +++ b/src/soc/config/test/test_pi2ls.py @@ -29,8 +29,9 @@ def wait_addr(port): def wait_ldok(port): while True: ldok = yield port.ld.ok - print("ldok", ldok) - if ldok: + exc_happened = yield port.exc_o.happened + print("ldok", ldok, "exception", exc_happened) + if ldok or exc_happened: break yield @@ -80,10 +81,14 @@ def pi_ld(port1, addr, datalen, msr_pr=0): yield yield from wait_ldok(port1) # wait until ld ok data = yield port1.ld.data + exc_happened = yield port1.exc_o.happened # cleanup yield port1.is_ld_i.eq(0) # end yield port1.addr.ok.eq(0) # set !ok + if exc_happened: + return 0 + yield from wait_busy(port1, no=False) # wait while not busy return data diff --git a/src/soc/experiment/test/test_ldst_pi.py b/src/soc/experiment/test/test_ldst_pi.py index 7ae1c2c7..c052b141 100644 --- a/src/soc/experiment/test/test_ldst_pi.py +++ b/src/soc/experiment/test/test_ldst_pi.py @@ -276,5 +276,5 @@ def test_misalign_mmu(): if __name__ == '__main__': - #test_mmu() + test_mmu() test_misalign_mmu() diff --git a/src/soc/fu/ldst/loadstore.py b/src/soc/fu/ldst/loadstore.py index 57404747..e20a7796 100644 --- a/src/soc/fu/ldst/loadstore.py +++ b/src/soc/fu/ldst/loadstore.py @@ -132,7 +132,6 @@ class LoadStore1(PortInterfaceBase): return None def set_rd_addr(self, m, addr, mask, misalign, msr_pr): - m.d.comb += self.d_out.valid.eq(self.d_validblip) m.d.comb += self.d_valid.eq(1) m.d.comb += self.req.load.eq(1) # load operation m.d.comb += self.req.byte_sel.eq(mask) @@ -151,7 +150,6 @@ class LoadStore1(PortInterfaceBase): def set_wr_data(self, m, data, wen): # do the "blip" on write data - m.d.comb += self.d_out.valid.eq(self.d_validblip) m.d.comb += self.d_valid.eq(1) # put data into comb which is picked up in main elaborate() m.d.comb += self.d_w_valid.eq(1) @@ -188,19 +186,20 @@ class LoadStore1(PortInterfaceBase): # a request when MMU_LOOKUP completes. m.d.comb += self.d_validblip.eq(rising_edge(m, self.d_valid)) ldst_r = LDSTRequest("ldst_r") - with m.If(self.d_validblip): - sync += ldst_r.eq(self.req) # copy of LDSTRequest on "blip" # fsm skeleton with m.Switch(self.state): with m.Case(State.IDLE): - with m.If(self.d_validblip): + with m.If(self.d_validblip & ~exc.happened): comb += self.busy.eq(1) sync += self.state.eq(State.ACK_WAIT) + sync += ldst_r.eq(self.req) # copy of LDSTRequest on "blip" + with m.Else(): + sync += ldst_r.eq(0) # waiting for completion with m.Case(State.ACK_WAIT): - comb += self.busy.eq(1) + comb += self.busy.eq(~exc.happened) with m.If(d_in.error): # cache error is not necessarily "final", it could @@ -299,12 +298,14 @@ class LoadStore1(PortInterfaceBase): # task 2: if dcache fails, look up in MMU. # do **NOT** confuse the two. with m.If(self.d_validblip): + m.d.comb += self.d_out.valid.eq(~exc.happened) m.d.comb += d_out.load.eq(self.req.load) m.d.comb += d_out.byte_sel.eq(self.req.byte_sel) m.d.comb += self.addr.eq(self.req.addr) m.d.comb += d_out.nc.eq(self.req.nc) m.d.comb += d_out.priv_mode.eq(self.req.priv_mode) m.d.comb += d_out.virt_mode.eq(self.req.virt_mode) + m.d.comb += self.align_intr.eq(self.req.align_intr) with m.Else(): m.d.comb += d_out.load.eq(ldst_r.load) m.d.comb += d_out.byte_sel.eq(ldst_r.byte_sel) @@ -312,6 +313,7 @@ class LoadStore1(PortInterfaceBase): m.d.comb += d_out.nc.eq(ldst_r.nc) m.d.comb += d_out.priv_mode.eq(ldst_r.priv_mode) m.d.comb += d_out.virt_mode.eq(ldst_r.virt_mode) + m.d.comb += self.align_intr.eq(ldst_r.align_intr) # XXX these should be possible to remove but for some reason # cannot be... yet. TODO, investigate