From b14be4c8a339eb1a39d9abb8576d990d71518fd0 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Tue, 12 Jun 2012 21:04:47 +0200 Subject: [PATCH] actorlib: ASMI sequential reader --- examples/dataflow/dma.py | 51 ++++++++++++++++++++++++++++++-------- migen/actorlib/dma_asmi.py | 44 ++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 10 deletions(-) create mode 100644 migen/actorlib/dma_asmi.py diff --git a/examples/dataflow/dma.py b/examples/dataflow/dma.py index 100055f33..7c0de8169 100644 --- a/examples/dataflow/dma.py +++ b/examples/dataflow/dma.py @@ -3,7 +3,7 @@ from random import Random from migen.fhdl import verilog from migen.flow.ala import * from migen.flow.network import * -from migen.actorlib import dma_wishbone +from migen.actorlib import dma_wishbone, dma_asmi from migen.actorlib.sim import * from migen.bus import wishbone, asmibus from migen.sim.generic import Simulator @@ -45,13 +45,27 @@ def wishbone_sim(efragment, master, end_simulation): peripheral = wishbone.Target(MyModelWB()) tap = wishbone.Tap(peripheral.bus) interconnect = wishbone.InterconnectPointToPoint(master.bus, peripheral.bus) - + def _end_simulation(s): + s.interrupt = end_simulation(s) fragment = efragment \ + peripheral.get_fragment() \ + tap.get_fragment() \ + interconnect.get_fragment() \ - + Fragment(sim=[end_simulation]) - + + Fragment(sim=[_end_simulation]) + sim = Simulator(fragment, Runner()) + sim.run() + +def asmi_sim(efragment, hub, end_simulation): + def _end_simulation(s): + s.interrupt = end_simulation(s) + peripheral = asmibus.Target(hub, MyModelASMI()) + tap = asmibus.Tap(hub) + def _end_simulation(s): + s.interrupt = end_simulation(s) + fragment = efragment \ + + peripheral.get_fragment() \ + + tap.get_fragment() \ + + Fragment(sim=[_end_simulation]) sim = Simulator(fragment, Runner()) sim.run() @@ -65,9 +79,8 @@ def test_wb_reader(): g.add_connection(reader, dumper) comp = CompositeActor(g) - def end_simulation(s): - s.interrupt = adrgen.done and not s.rd(comp.busy) - wishbone_sim(comp.get_fragment(), reader, end_simulation) + wishbone_sim(comp.get_fragment(), reader, + lambda s: adrgen.done and not s.rd(comp.busy)) def test_wb_writer(): print("*** Testing Wishbone writer") @@ -77,9 +90,27 @@ def test_wb_writer(): g.add_connection(trgen, writer) comp = CompositeActor(g) - def end_simulation(s): - s.interrupt = trgen.done and not s.rd(comp.busy) - wishbone_sim(comp.get_fragment(), writer, end_simulation) + wishbone_sim(comp.get_fragment(), writer, + lambda s: trgen.done and not s.rd(comp.busy)) + +def test_asmi_seqreader(): + print("*** Testing ASMI sequential reader") + + hub = asmibus.Hub(32, 32) + port = hub.get_port() + hub.finalize() + + adrgen = SimActor(adrgen_gen(), ("address", Source, [("a", BV(32))])) + reader = dma_asmi.SequentialReader(port) + dumper = SimActor(dumper_gen(), ("data", Sink, [("d", BV(32))])) + g = DataFlowGraph() + g.add_connection(adrgen, reader) + g.add_connection(reader, dumper) + comp = CompositeActor(g) + + asmi_sim(hub.get_fragment() + comp.get_fragment(), hub, + lambda s: adrgen.done and not s.rd(comp.busy)) test_wb_reader() test_wb_writer() +test_asmi_seqreader() diff --git a/migen/actorlib/dma_asmi.py b/migen/actorlib/dma_asmi.py new file mode 100644 index 000000000..6a201f576 --- /dev/null +++ b/migen/actorlib/dma_asmi.py @@ -0,0 +1,44 @@ +from migen.fhdl.structure import * +from migen.flow.actor import * + +class SequentialReader(Actor): + def __init__(self, port): + self.port = port + assert(len(self.port.slots) == 1) + super().__init__( + ("address", Sink, [("a", BV(self.port.hub.aw))]), + ("data", Source, [("d", BV(self.port.hub.dw))])) + + def get_fragment(self): + sample = Signal() + data_reg_loaded = Signal() + data_reg = Signal(BV(self.port.hub.dw)) + + accept_new = Signal() + + # We check that len(self.port.slots) == 1 + # and therefore we can assume that self.port.ack + # goes low until the data phase. + + comb = [ + self.busy.eq(~data_reg_loaded | ~self.port.ack), + self.port.adr.eq(self.token("address").a), + self.port.we.eq(0), + accept_new.eq(~data_reg_loaded | self.endpoints["data"].ack), + self.port.stb.eq(self.endpoints["address"].stb & accept_new), + self.endpoints["address"].ack.eq(self.port.ack & accept_new), + self.endpoints["data"].stb.eq(data_reg_loaded), + self.token("data").d.eq(data_reg) + ] + sync = [ + If(self.endpoints["data"].ack, + data_reg_loaded.eq(0) + ), + If(sample, + data_reg_loaded.eq(1), + data_reg.eq(self.port.dat_r) + ), + sample.eq(self.port.get_call_expression()) + ] + + return Fragment(comb, sync)