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