bus/wishbone: target model
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Sun, 10 Jun 2012 14:40:33 +0000 (16:40 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Sun, 10 Jun 2012 14:40:33 +0000 (16:40 +0200)
examples/dataflow_dma.py
examples/wb_initiator.py
migen/bus/wishbone.py

index b5f24a7cff485fed3e1b9df9f7b2c0dc2061ab86..a6ccd9a34a765587b63804e21d80b660e340dbf1 100644 (file)
@@ -9,22 +9,18 @@ from migen.bus import wishbone
 from migen.sim.generic import Simulator
 from migen.sim.icarus import Runner
 
-class MyPeripheral:
+class MyModel:
        def __init__(self):
-               self.bus = wishbone.Interface()
-               self.ack_en = Signal()
                self.prng = Random(763627)
-
-       def do_simulation(self, s):
-               # Only authorize acks on certain cycles to simulate variable latency.
-               s.wr(self.ack_en, self.prng.randrange(0, 2))
-
-       def get_fragment(self):
-               comb = [
-                       self.bus.ack.eq(self.bus.cyc & self.bus.stb & self.ack_en),
-                       self.bus.dat_r.eq(self.bus.adr + 4)
-               ]
-               return Fragment(comb, sim=[self.do_simulation])
+       
+       def read(self, address):
+               return address + 4
+       
+       def write(self, address, data, sel):
+               pass
+       
+       def can_ack(self, bus):
+               return self.prng.randrange(0, 2)
 
 def adrgen_gen():
        for i in range(10):
@@ -47,7 +43,7 @@ def test_reader():
        g.add_connection(reader, dumper)
        comp = CompositeActor(g)
        
-       peripheral = MyPeripheral()
+       peripheral = wishbone.Target(MyModel())
        interconnect = wishbone.InterconnectPointToPoint(reader.bus, peripheral.bus)
        
        def end_simulation(s):
@@ -76,7 +72,7 @@ def test_writer():
        g.add_connection(trgen, writer)
        comp = CompositeActor(g)
        
-       peripheral = MyPeripheral()
+       peripheral = wishbone.Target(MyModel())
        tap = wishbone.Tap(peripheral.bus)
        interconnect = wishbone.InterconnectPointToPoint(writer.bus, peripheral.bus)
        
index d5e38adcd4773ca4be4dcd838d6bd393ff26608a..607de6963a10b4ed389fdccccfd9cf3c0ee1daa3 100644 (file)
@@ -33,31 +33,26 @@ def my_generator():
                        yield None
 
 # Our bus slave.
-# All transactions complete with a random delay.
-# Reads return address + 4. Writes are simply acknowledged.
-class MyPeripheral:
+class MyModel:
        def __init__(self):
-               self.bus = wishbone.Interface()
-               self.ack_en = Signal()
                self.prng = Random(763627)
-
-       def do_simulation(self, s):
-               # Only authorize acks on certain cycles to simulate variable latency.
-               s.wr(self.ack_en, self.prng.randrange(0, 2))
-
-       def get_fragment(self):
-               comb = [
-                       self.bus.ack.eq(self.bus.cyc & self.bus.stb & self.ack_en),
-                       self.bus.dat_r.eq(self.bus.adr + 4)
-               ]
-               return Fragment(comb, sim=[self.do_simulation])
+       
+       def read(self, address):
+               return address + 4
+       
+       def write(self, address, data, sel):
+               pass
+       
+       def can_ack(self, bus):
+               return self.prng.randrange(0, 2)
 
 def main():
        # The "wishbone.Initiator" library component runs our generator
        # and manipulates the bus signals accordingly.
        master = wishbone.Initiator(my_generator())
-       # Our slave.
-       slave = MyPeripheral()
+       # The "wishbone.Target" library component examines the bus signals
+       # and calls into our model object.
+       slave = wishbone.Target(MyModel())
        # The "wishbone.Tap" library component examines the bus at the slave port
        # and displays the transactions on the console (<TRead...>/<TWrite...>).
        tap = wishbone.Tap(slave.bus)
index 83b27fe326106a50b847b553c35a4638313a9c48..d7a400ae418f922cefccb3254a356c3764f59ff3 100644 (file)
@@ -3,6 +3,7 @@ from migen.corelogic import roundrobin
 from migen.corelogic.misc import multimux, optree
 from migen.bus.simple import *
 from migen.bus.transactions import *
+from migen.sim.generic import Proxy
 
 _desc = Description(
        (M_TO_S,        "adr",          30),
@@ -186,3 +187,27 @@ class Initiator:
        
        def get_fragment(self):
                return Fragment(sim=[self.do_simulation])
+
+class Target:
+       def __init__(self, model):
+               self.bus = Interface()
+               self.model = model
+       
+       def do_simulation(self, s):
+               bus = Proxy(s, self.bus)
+               if not bus.ack:
+                       if hasattr(self.model, "can_ack"):
+                               can_ack = self.model.can_ack(bus)
+                       else:
+                               can_ack = True
+                       if can_ack and bus.cyc and bus.stb:
+                               if bus.we:
+                                       self.model.write(bus.adr, bus.dat_w, bus.sel)
+                               else:
+                                       bus.dat_r = self.model.read(bus.adr)
+                               bus.ack = 1
+               else:
+                       bus.ack = 0
+       
+       def get_fragment(self):
+               return Fragment(sim=[self.do_simulation])