fix WB6to32 downconverter with stall signalling
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 9 Mar 2022 19:44:13 +0000 (19:44 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 9 Mar 2022 19:44:13 +0000 (19:44 +0000)
src/ls2.py

index 76cebdc580ad4cbe2a125da888c413da4d811f66..f45bb97ace257e448705a78091a1a66deb479db6 100644 (file)
@@ -96,17 +96,14 @@ class WB64to32Convert(Elaboratable):
         master, slave = self.master, self.slave
 
         has_top = Signal()
+        has_top_r = Signal()
         has_bot = Signal()
 
-        # Do we have a top word and/or a bottom word ?
-        with m.If(master.cyc & master.stb):
-            comb += has_top.eq(master.sel[4:].bool())
-            comb += has_bot.eq(master.sel[:4].bool())
-
         with m.FSM() as fsm:
             with m.State("IDLE"):
-                # Clear ACK in case it was set
+                # Clear ACK (and has_top_r) in case it was set
                 sync += master.ack.eq(0)
+                sync += has_top_r.eq(0)
 
                 # Do we have a cycle ?
                 with m.If(master.cyc & master.stb):
@@ -118,6 +115,12 @@ class WB64to32Convert(Elaboratable):
                     sync += slave.cyc.eq(1)
                     sync += slave.stb.eq(1)
 
+                    # Do we have a top word and/or a bottom word ?
+                    comb += has_top.eq(master.sel[4:].bool())
+                    comb += has_bot.eq(master.sel[:4].bool())
+                    # record the has_top flag for the next FSM state
+                    sync += has_top_r.eq(has_top)
+
                     # Copy write enable to IO out, copy address as well,
                     # LSB is set later based on HI/LO
                     sync += slave.we.eq(master.we)
@@ -145,6 +148,7 @@ class WB64to32Convert(Elaboratable):
                         # Wait for ack on TOP half
                         m.next = "WAIT_ACK_TOP"
 
+
             with m.State("WAIT_ACK_BOT"):
                 # If we aren't stalled by the device, clear stb
                 if hasattr(slave, "stall"):
@@ -158,7 +162,7 @@ class WB64to32Convert(Elaboratable):
                         sync += master.dat_r[:32].eq(slave.dat_r)
 
                     # Do we have a "top" part as well ?
-                    with m.If(has_top):
+                    with m.If(has_top_r):
                         # Latch data & sel
                         with m.If(master.we):
                             sync += slave.dat_w.eq(master.dat_w[32:])
@@ -189,7 +193,6 @@ class WB64to32Convert(Elaboratable):
                 if hasattr(slave, "stall"):
                     with m.If(~slave.stall):
                         sync += slave.stb.eq(0)
-                    sync += slave.stb.eq(0)
 
                 # Handle ack
                 with m.If(slave.ack):
@@ -298,10 +301,12 @@ class DDR3SoC(SoC, Elaboratable):
         # UART at 0xC000_2000, convert 32-bit bus down to 8-bit in an odd way
         if uart_pins is not None:
             # sigh actual UART in microwatt is 8-bit
-            self.uart = UART16550(data_width=8, pins=uart_pins)
+            self.uart = UART16550(data_width=8, pins=uart_pins,
+                                  features={'stall'})
             # but (see soc.vhdl) 8-bit regs are addressed at 32-bit locations
             cvtuartbus = wishbone.Interface(addr_width=5, data_width=32,
-                                            granularity=8)
+                                            granularity=8,
+                                            features={'stall'})
             umap = MemoryMap(addr_width=7, data_width=8, name="uart_map")
             cvtuartbus.memory_map = umap
             self._decoder.add(cvtuartbus, addr=0xc0002000) # 16550 UART addr
@@ -395,6 +400,9 @@ class DDR3SoC(SoC, Elaboratable):
             comb += uartbus.dat_w.eq(self.cvtuartbus.dat_w) # drops 8..31
             comb += self.cvtuartbus.dat_r.eq(uartbus.dat_r) # drops 8..31
             comb += self.cvtuartbus.ack.eq(uartbus.ack)
+            # aaand with the WB4-pipeline-to-WB3-classic mismatch, sigh
+            comb += uartbus.stall.eq(uartbus.cyc & ~uartbus.ack)
+            comb += self.cvtuartbus.stall.eq(uartbus.stall)
         if hasattr(self, "cpu"):
             m.submodules.intc = self.intc
             m.submodules.extcore = self.cpu