bus/wishbone: target model

This commit is contained in:
Sebastien Bourdeauducq 2012-06-10 16:40:33 +02:00
parent f061b25a24
commit ec501e7797
3 changed files with 50 additions and 34 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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])