Remove ASMI
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Tue, 16 Jul 2013 16:50:50 +0000 (18:50 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Tue, 16 Jul 2013 16:50:50 +0000 (18:50 +0200)
migen/actorlib/dma_asmi.py [deleted file]
migen/bus/asmibus.py [deleted file]
migen/bus/wishbone2asmi.py [deleted file]

diff --git a/migen/actorlib/dma_asmi.py b/migen/actorlib/dma_asmi.py
deleted file mode 100644 (file)
index 142b2a1..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-from migen.fhdl.std import *
-from migen.flow.actor import *
-from migen.genlib.buffers import ReorderBuffer
-
-class SequentialReader(Module):
-       def __init__(self, port):
-               assert(len(port.slots) == 1)
-               self.address = Sink([("a", port.hub.aw)])
-               self.data = Source([("d", port.hub.dw)])
-               self.busy = Signal()
-       
-               ###
-
-               sample = Signal()
-               data_reg_loaded = Signal()
-               data_reg = Signal(port.hub.dw)
-               accept_new = Signal()
-               
-               # We check that len(port.slots) == 1
-               # and therefore we can assume that port.ack
-               # goes low until the data phase.
-               
-               self.comb += [
-                       self.busy.eq(~data_reg_loaded | ~port.ack),
-                       port.adr.eq(self.address.payload.a),
-                       port.we.eq(0),
-                       accept_new.eq(~data_reg_loaded | self.data.ack),
-                       port.stb.eq(self.address.stb & accept_new),
-                       self.address.ack.eq(port.ack & accept_new),
-                       self.data.stb.eq(data_reg_loaded),
-                       self.data.payload.d.eq(data_reg)
-               ]
-               self.sync += [
-                       If(self.data.ack, data_reg_loaded.eq(0)),
-                       If(sample,
-                               data_reg_loaded.eq(1),
-                               data_reg.eq(port.dat_r)
-                       ),
-                       sample.eq(port.get_call_expression())
-               ]
-
-class OOOReader(Module):
-       def __init__(self, port):
-               assert(len(port.slots) > 1)
-               self.address = Sink([("a", port.hub.aw)])
-               self.data = Source([("d", port.hub.dw)])
-               self.busy = Signal() # TODO: drive busy
-       
-               ###
-
-               tag_width = flen(port.tag_call)
-               data_width = port.hub.dw
-               depth = len(port.slots)
-               rob = ReorderBuffer(tag_width, data_width, depth)
-               self.submodules += rob
-               
-               self.comb += [
-                       port.adr.eq(self.address.payload.a),
-                       port.we.eq(0),
-                       port.stb.eq(self.address.stb & rob.can_issue),
-                       self.address.ack.eq(port.ack & rob.can_issue),
-                       rob.issue.eq(self.address.stb & port.ack),
-                       rob.tag_issue.eq(port.base + port.tag_issue),
-                       
-                       rob.data_call.eq(port.dat_r),
-                       
-                       self.data.stb.eq(rob.can_read),
-                       rob.read.eq(self.data.ack),
-                       self.data.payload.d.eq(rob.data_read)
-               ]
-               self.sync += [
-                       # Data is announced one cycle in advance.
-                       # Register the call to synchronize it with the data signal.
-                       rob.call.eq(port.call),
-                       rob.tag_call.eq(port.tag_call)
-               ]
-
-class SequentialWriter(Module):
-       def __init__(self, port):
-               assert(len(port.slots) == 1)
-               self.address_data = Sink([("a", port.hub.aw), ("d", port.hub.dw)])
-               self.busy = Signal()
-
-               ###
-
-               data_reg = Signal(port.hub.dw)
-               self.comb += [
-                       port.adr.eq(self.address_data.payload.a),
-                       port.we.eq(1),
-                       port.stb.eq(self.address_data.stb),
-                       self.address_data.ack.eq(port.ack),
-                       port.dat_wm.eq(0)
-               ]
-               self.sync += [
-                       port.dat_w.eq(0),
-                       If(port.get_call_expression(),
-                               self.busy.eq(0),
-                               port.dat_w.eq(data_reg)
-                       ),
-                       If(self.address_data.stb & self.address_data.ack,
-                               self.busy.eq(1),
-                               data_reg.eq(self.address_data.payload.d)
-                       )
-               ]
-
-class _WriteSlot(Module):
-       def __init__(self, port, load_data, n):
-               self.busy = Signal()
-
-               ###
-
-               drive_data = Signal()
-               data_reg = Signal(port.hub.dw)
-               self.comb += [
-                       If(drive_data, port.dat_w.eq(data_reg)),
-                       port.dat_wm.eq(0)
-               ]
-
-               self.sync += [
-                       drive_data.eq(0),
-                       If(port.get_call_expression(n),
-                               self.busy.eq(0),
-                               drive_data.eq(1)
-                       ),
-                       If(port.stb & port.ack & (port.tag_issue == n),
-                               self.busy.eq(1),
-                               data_reg.eq(load_data)
-                       ),
-               ]
-
-class OOOWriter(Module):
-       def __init__(self, port):
-               assert(len(port.slots) > 1)
-               self.address_data = Sink([("a", port.hub.aw), ("d", port.hub.dw)])
-               self.busy = Signal()
-
-               ###
-
-               self.comb += [
-                       port.adr.eq(self.address_data.payload.a),
-                       port.we.eq(1),
-                       port.stb.eq(self.address_data.stb),
-                       self.address_data.ack.eq(port.ack)
-               ]
-
-               busy = 0
-               for i in range(len(port.slots)):
-                       write_slot = _WriteSlot(port, self.address_data.payload.d, i)
-                       self.submodules += write_slot
-                       busy = busy | write_slot.busy
-               self.comb += self.busy.eq(busy)
-
-def Reader(port):
-       if len(port.slots) == 1:
-               return SequentialReader(port)
-       else:
-               return OOOReader(port)
-
-def Writer(port):
-       if len(port.slots) == 1:
-               return SequentialWriter(port)
-       else:
-               return OOOWriter(port)
diff --git a/migen/bus/asmibus.py b/migen/bus/asmibus.py
deleted file mode 100644 (file)
index 77b0fc3..0000000
+++ /dev/null
@@ -1,304 +0,0 @@
-from migen.fhdl.std import *
-from migen.fhdl.module import FinalizeError
-from migen.genlib.misc import optree
-from migen.genlib import roundrobin
-from migen.bus.transactions import *
-from migen.sim.generic import Proxy
-
-(SLOT_EMPTY, SLOT_PENDING, SLOT_PROCESSING) = range(3)
-
-class Slot(Module):
-       def __init__(self, aw, time):
-               self.time = time
-               self.state = Signal(2)
-               self.we = Signal()
-               self.adr = Signal(aw)
-               if self.time:
-                       self.mature = Signal()
-               
-               self.allocate = Signal()
-               self.allocate_we = Signal()
-               self.allocate_adr = Signal(aw)
-               self.process = Signal()
-               self.call = Signal()
-       
-               ###
-
-               self.sync += [
-                       If(self.allocate,
-                               self.state.eq(SLOT_PENDING),
-                               self.we.eq(self.allocate_we),
-                               self.adr.eq(self.allocate_adr)
-                       ),
-                       If(self.process, self.state.eq(SLOT_PROCESSING)),
-                       If(self.call, self.state.eq(SLOT_EMPTY))
-               ]
-               if self.time:
-                       counter = Signal(max=self.time+1)
-                       self.comb += self.mature.eq(counter == 0)
-                       self.sync += [
-                               If(self.allocate,
-                                       counter.eq(self.time)
-                               ).Elif(counter != 0,
-                                       counter.eq(counter - 1)
-                               )
-                       ]
-
-class Port(Module):
-       def __init__(self, hub, base, nslots):
-               self.hub = hub
-               self.base = base
-               self.submodules.slots = [Slot(self.hub.aw, self.hub.time) for i in range(nslots)]
-               
-               # request issuance
-               self.adr = Signal(self.hub.aw)
-               self.we = Signal()
-               self.stb = Signal()
-               # tag_issue is created by finalize()
-               self.ack = Signal()
-               
-               # request completion
-               self.call = Signal()
-               # tag_call is created by finalize()
-               self.dat_r = Signal(self.hub.dw)
-               self.dat_w = Signal(self.hub.dw)
-               self.dat_wm = Signal(self.hub.dw//8)
-
-       def do_finalize(self):
-               nslots = len(self.slots)
-               if nslots > 1:
-                       self.tag_issue = Signal(max=nslots)
-               self.tag_call = Signal(self.hub.tagbits)
-
-               # allocate
-               for s in self.slots:
-                       self.comb += [
-                               s.allocate_we.eq(self.we),
-                               s.allocate_adr.eq(self.adr)
-                       ]
-               choose_slot = None
-               needs_tags = len(self.slots) > 1
-               for n, s in reversed(list(enumerate(self.slots))):
-                       choose_slot = If(s.state == SLOT_EMPTY,
-                               s.allocate.eq(self.stb),
-                               self.tag_issue.eq(n) if needs_tags else None
-                       ).Else(choose_slot)
-               self.comb += choose_slot
-               self.comb += self.ack.eq(optree("|", 
-                       [s.state == SLOT_EMPTY for s in self.slots]))
-
-               # call
-               self.comb += [s.call.eq(self.get_call_expression(n))
-                       for n, s in enumerate(self.slots)]
-       
-       def get_call_expression(self, slotn=0):
-               if not self.finalized:
-                       raise FinalizeError
-               return self.call \
-                       & (self.tag_call == (self.base + slotn))
-
-class Hub(Module):
-       def __init__(self, aw, dw, time=0):
-               self.aw = aw
-               self.dw = dw
-               self.time = time
-
-               self.ports = []
-               self._next_base = 0
-               self.tagbits = 0
-               
-               self.call = Signal()
-               # tag_call is created by do_finalize()
-               self.dat_r = Signal(self.dw)
-               self.dat_w = Signal(self.dw)
-               self.dat_wm = Signal(self.dw//8)
-       
-       def get_port(self, nslots=1):
-               if self.finalized:
-                       raise FinalizeError
-               new_port = Port(self, self._next_base, nslots)
-               self._next_base += nslots
-               self.tagbits = bits_for(self._next_base-1)
-               self.ports.append(new_port)
-               self.submodules += new_port
-               return new_port
-       
-       def do_finalize(self):
-               self.tag_call = Signal(self.tagbits)
-               for port in self.ports:
-                       self.comb += [
-                               port.call.eq(self.call),
-                               port.tag_call.eq(self.tag_call),
-                               port.dat_r.eq(self.dat_r)
-                       ]
-               self.comb += [
-                       self.dat_w.eq(optree("|", [port.dat_w for port in self.ports])),
-                       self.dat_wm.eq(optree("|", [port.dat_wm for port in self.ports]))
-               ]
-       
-       def get_slots(self):
-               if not self.finalized:
-                       raise FinalizeError
-               return sum([port.slots for port in self.ports], [])
-
-class Tap(Module):
-       def __init__(self, hub, handler=print):
-               self.hub = hub
-               self.handler = handler
-               self.tag_to_transaction = dict()
-               self.transaction = None
-       
-       def do_simulation(self, s):
-               hub = Proxy(s, self.hub)
-               
-               # Pull any data announced in the previous cycle.
-               if isinstance(self.transaction, TWrite):
-                       self.transaction.data = hub.dat_w
-                       self.transaction.sel = ~hub.dat_wm
-                       self.handler(self.transaction)
-                       self.transaction = None
-               if isinstance(self.transaction, TRead):
-                       self.transaction.data = hub.dat_r
-                       self.handler(self.transaction)
-                       self.transaction = None
-               
-               # Tag issue. Transaction objects are created here
-               # and placed into the tag_to_transaction dictionary.
-               for tag, slot in enumerate(self.hub.get_slots()):
-                       if s.rd(slot.allocate):
-                               adr = s.rd(slot.allocate_adr)
-                               we = s.rd(slot.allocate_we)
-                               if we:
-                                       transaction = TWrite(adr)
-                               else:
-                                       transaction = TRead(adr)
-                               transaction.latency = s.cycle_counter
-                               self.tag_to_transaction[tag] = transaction
-               
-               # Tag call.
-               if hub.call:
-                       transaction = self.tag_to_transaction[hub.tag_call]
-                       transaction.latency = s.cycle_counter - transaction.latency + 1
-                       self.transaction = transaction
-
-class Initiator(Module):
-       def __init__(self, generator, port):
-               self.generator = generator
-               self.port = port
-               self.done = False
-               self._exe = None
-       
-       def _execute(self, s, generator, port):
-               while True:
-                       transaction = next(generator)
-                       transaction_start = s.cycle_counter
-                       if transaction is None:
-                               yield
-                       else:
-                               # tag phase
-                               s.wr(port.adr, transaction.address)
-                               if isinstance(transaction, TWrite):
-                                       s.wr(port.we, 1)
-                               else:
-                                       s.wr(port.we, 0)
-                               s.wr(port.stb, 1)
-                               yield
-                               while not s.rd(port.ack):
-                                       yield
-                               if hasattr(port, "tag_issue"):
-                                       tag = s.rd(port.tag_issue)
-                               else:
-                                       tag = 0
-                               tag += port.base
-                               s.wr(port.stb, 0)
-                               
-                               # data phase
-                               while not (s.rd(port.call) and (s.rd(port.tag_call) == tag)):
-                                       yield
-                               if isinstance(transaction, TWrite):
-                                       s.wr(port.dat_w, transaction.data)
-                                       s.wr(port.dat_wm, ~transaction.sel)
-                                       yield
-                                       s.wr(port.dat_w, 0)
-                                       s.wr(port.dat_wm, 0)
-                               else:
-                                       yield
-                                       transaction.data = s.rd(port.dat_r)
-                               transaction.latency = s.cycle_counter - transaction_start - 1
-       
-       def do_simulation(self, s):
-               if not self.done:
-                       if self._exe is None:
-                               self._exe = self._execute(s, self.generator, self.port)
-                       try:
-                               next(self._exe)
-                       except StopIteration:
-                               self.done = True
-
-class TargetModel:
-       def __init__(self):
-               self.last_slot = 0
-       
-       def read(self, address):
-               return 0
-       
-       def write(self, address, data, mask):
-               pass
-       
-       # Round-robin scheduling.
-       def select_slot(self, pending_slots):
-               if not pending_slots:
-                       return -1
-               self.last_slot += 1
-               if self.last_slot > max(pending_slots):
-                       self.last_slot = 0
-               while self.last_slot not in pending_slots:
-                       self.last_slot += 1
-               return self.last_slot
-
-class Target(Module):
-       def __init__(self, model, hub):
-               self.model = model
-               self.hub = hub
-               self._calling_tag = -1
-               self._write_request_d = -1
-               self._write_request = -1
-               self._read_request = -1
-       
-       def do_simulation(self, s):
-               slots = self.hub.get_slots()
-               
-               # Data I/O
-               if self._write_request >= 0:
-                       self.model.write(self._write_request,
-                               s.rd(self.hub.dat_w), s.rd(self.hub.dat_wm))
-               if self._read_request >= 0:
-                       s.wr(self.hub.dat_r, self.model.read(self._read_request))
-                       
-               # Request pipeline
-               self._read_request = -1
-               self._write_request = self._write_request_d
-               self._write_request_d = -1
-               
-               # Examine pending slots and possibly choose one.
-               # Note that we do not use the SLOT_PROCESSING state here.
-               # Selected slots are immediately called.
-               pending_slots = set()
-               for tag, slot in enumerate(slots):
-                       if tag != self._calling_tag and s.rd(slot.state) == SLOT_PENDING:
-                               pending_slots.add(tag)
-               slot_to_call = self.model.select_slot(pending_slots)
-               
-               # Call slot.
-               if slot_to_call >= 0:
-                       slot = slots[slot_to_call]
-                       s.wr(self.hub.call, 1)
-                       s.wr(self.hub.tag_call, slot_to_call)
-                       self._calling_tag = slot_to_call
-                       if s.rd(slot.we):
-                               self._write_request_d = s.rd(slot.adr)
-                       else:
-                               self._read_request = s.rd(slot.adr)
-               else:
-                       s.wr(self.hub.call, 0)
-                       self._calling_tag = -1
diff --git a/migen/bus/wishbone2asmi.py b/migen/bus/wishbone2asmi.py
deleted file mode 100644 (file)
index 49902a8..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-from migen.fhdl.std import *
-from migen.bus import wishbone
-from migen.genlib.fsm import FSM, NextState
-from migen.genlib.misc import split, displacer, chooser
-from migen.genlib.record import Record, layout_len
-
-# cachesize (in 32-bit words) is the size of the data store, must be a power of 2
-class WB2ASMI:
-       def __init__(self, cachesize, asmiport):
-               self.wishbone = wishbone.Interface()
-               self.cachesize = cachesize
-               self.asmiport = asmiport
-               if len(self.asmiport.slots) != 1:
-                       raise ValueError("ASMI port must have 1 slot")
-               if self.asmiport.hub.dw <= 32:
-                       raise ValueError("ASMI data width must be strictly larger than 32")
-               if (self.asmiport.hub.dw % 32) != 0:
-                       raise ValueError("ASMI data width must be a multiple of 32")
-
-       def get_fragment(self):
-               comb = []
-               sync = []
-               
-               aaw = self.asmiport.hub.aw
-               adw = self.asmiport.hub.dw
-               
-               # Split address:
-               # TAG | LINE NUMBER | LINE OFFSET
-               offsetbits = log2_int(adw//32)
-               addressbits = aaw + offsetbits
-               linebits = log2_int(self.cachesize) - offsetbits
-               tagbits = addressbits - linebits
-               adr_offset, adr_line, adr_tag = split(self.wishbone.adr, offsetbits, linebits, tagbits)
-               
-               # Data memory
-               data_mem = Memory(adw, 2**linebits)
-               data_port = data_mem.get_port(write_capable=True, we_granularity=8)
-               
-               write_from_asmi = Signal()
-               write_to_asmi = Signal()
-               adr_offset_r = Signal(offsetbits)
-               comb += [
-                       data_port.adr.eq(adr_line),
-                       If(write_from_asmi,
-                               data_port.dat_w.eq(self.asmiport.dat_r),
-                               data_port.we.eq(Replicate(1, adw//8))
-                       ).Else(
-                               data_port.dat_w.eq(Replicate(self.wishbone.dat_w, adw//32)),
-                               If(self.wishbone.cyc & self.wishbone.stb & self.wishbone.we & self.wishbone.ack,
-                                       displacer(self.wishbone.sel, adr_offset, data_port.we, 2**offsetbits, reverse=True)
-                               )
-                       ),
-                       If(write_to_asmi, self.asmiport.dat_w.eq(data_port.dat_r)),
-                       self.asmiport.dat_wm.eq(0),
-                       chooser(data_port.dat_r, adr_offset_r, self.wishbone.dat_r, reverse=True)
-               ]
-               sync += [
-                       adr_offset_r.eq(adr_offset)
-               ]
-               
-               # Tag memory
-               tag_layout = [("tag", tagbits), ("dirty", 1)]
-               tag_mem = Memory(layout_len(tag_layout), 2**linebits)
-               tag_port = tag_mem.get_port(write_capable=True)
-               tag_do = Record(tag_layout)
-               tag_di = Record(tag_layout)
-               comb += [
-                       tag_do.raw_bits().eq(tag_port.dat_r),
-                       tag_port.dat_w.eq(tag_di.raw_bits())
-               ]
-                       
-               comb += [
-                       tag_port.adr.eq(adr_line),
-                       tag_di.tag.eq(adr_tag),
-                       self.asmiport.adr.eq(Cat(adr_line, tag_do.tag))
-               ]
-               
-               # Control FSM
-               write_to_asmi_pre = Signal()
-               sync.append(write_to_asmi.eq(write_to_asmi_pre))
-               
-               fsm = FSM()
-               
-               fsm.act("IDLE",
-                       If(self.wishbone.cyc & self.wishbone.stb, NextState("TEST_HIT"))
-               )
-               fsm.act("TEST_HIT",
-                       If(tag_do.tag == adr_tag,
-                               self.wishbone.ack.eq(1),
-                               If(self.wishbone.we,
-                                       tag_di.dirty.eq(1),
-                                       tag_port.we.eq(1)
-                               ),
-                               NextState("IDLE")
-                       ).Else(
-                               If(tag_do.dirty,
-                                       NextState("EVICT_ISSUE")
-                               ).Else(
-                                       NextState("REFILL_WRTAG")
-                               )
-                       )
-               )
-               
-               fsm.act("EVICT_ISSUE",
-                       self.asmiport.stb.eq(1),
-                       self.asmiport.we.eq(1),
-                       If(self.asmiport.ack, NextState("EVICT_WAIT"))
-               )
-               fsm.act("EVICT_WAIT",
-                       # Data is actually sampled by the memory controller in the next state.
-                       # But since the data memory has one cycle latency, it gets the data
-                       # at the address given during this cycle.
-                       If(self.asmiport.get_call_expression(),
-                               write_to_asmi_pre.eq(1),
-                               NextState("REFILL_WRTAG")
-                       )
-               )
-               
-               fsm.act("REFILL_WRTAG",
-                       # Write the tag first to set the ASMI address
-                       tag_port.we.eq(1),
-                       NextState("REFILL_ISSUE")
-               )
-               fsm.act("REFILL_ISSUE",
-                       self.asmiport.stb.eq(1),
-                       If(self.asmiport.ack, NextState("REFILL_WAIT"))
-               )
-               fsm.act("REFILL_WAIT",
-                       If(self.asmiport.get_call_expression(), NextState("REFILL_COMPLETE"))
-               )
-               fsm.act("REFILL_COMPLETE",
-                       write_from_asmi.eq(1),
-                       NextState("TEST_HIT")
-               )
-               
-               return Fragment(comb, sync, specials={data_mem, tag_mem, data_port, tag_port}) \
-                       + fsm.get_fragment()