add second version of wb_get which can cope with pipelines
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 12 Jan 2022 19:53:16 +0000 (19:53 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 12 Jan 2022 19:53:16 +0000 (19:53 +0000)
TODO: make it spot the "stall" signal

src/openpower/test/wb_get.py

index 937e6267f55cb197a68e01509ef00a9e345e42d7..426b66d6f07ce61fd5487d9820ad9137cc27eece 100644 (file)
@@ -57,3 +57,71 @@ def wb_get(wb, mem, name=None):
         yield
 
 
+def wb_get(wb, mem, name=None):
+    """simulator process for emulating wishbone (pipelined) out of a dictionary
+    deliberately do not send back a stall (ever)
+    """
+    if name is None:
+        name = ""
+
+    global stop
+    assert (stop == False)
+
+    while not stop:
+        while True: # wait for dc_valid
+            if stop:
+                return
+            cyc = yield (wb.cyc)
+            stb = yield (wb.stb)
+            if cyc and stb:
+                break
+            yield
+
+        next_ack = 0
+        addr = 0
+        while cyc:
+            prev_addr = addr
+            addr = (yield wb.adr) << 3
+            if addr not in mem:
+                print ("    %s WB NO entry @ %x, returning zero" % \
+                            (name, addr))
+
+            print ("    %s WB req @ %x" % (name, addr))
+
+            # read or write?
+            we = (yield wb.we)
+            if we:
+                # WRITE
+                store = (yield wb.dat_w)
+                sel = (yield wb.sel)
+                data = mem.get(addr, 0)
+                # note we assume 8-bit sel, here
+                res = 0
+                for i in range(8):
+                    mask = 0xff << (i*8)
+                    if sel & (1<<i):
+                        res |= store & mask
+                    else:
+                        res |= data & mask
+                mem[addr] = res
+                print ("    %s WB set %x mask %x data %x" % \
+                            (name, addr, sel, res))
+            else:
+                # READ
+                if next_ack:
+                    data = mem.get(prev_addr, 0)
+                    yield wb.dat_r.eq(data)
+                    print ("    %s WB get %x data %x" % \
+                                    (name, prev_addr, data))
+
+            # acknowledge previous strobe 1 clock late
+            yield wb.ack.eq(next_ack)
+            yield
+            next_ack = stb
+            stb = yield (wb.stb)
+            cyc = yield (wb.cyc)
+
+        # clear ack for next cyc
+        yield wb.ack.eq(0)
+
+