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):
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):
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)
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)
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),
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])