class LiteSATA(Module, AutoCSR):
def __init__(self, phy, buffer_depth=2*fis_max_dwords,
- with_crossbar=False,
with_bist=False, with_bist_csr=False):
# phy
self.phy = phy
self.core = LiteSATACore(self.phy, buffer_depth)
# frontend
- if with_crossbar:
- self.crossbar = LiteSATACrossbar(self.core)
+ self.crossbar = LiteSATACrossbar(self.core)
if with_bist:
self.bist = LiteSATABIST(self.crossbar, with_bist_csr)
from migen.genlib.roundrobin import *
class LiteSATAArbiter(Module):
- def __init__(self, slaves, master):
- if len(slaves) == 1:
- self.comb += slaves[0].connect(master)
- else:
- self.rr = RoundRobin(len(slaves))
- self.grant = self.rr.grant
- cases = {}
- for i, slave in enumerate(slaves):
- sink, source = slave.sink, slave.source
- start = Signal()
- done = Signal()
- ongoing = Signal()
- self.comb += [
- start.eq(sink.stb & sink.sop),
- done.eq(source.stb & source.last & source.eop & source.ack)
- ]
- self.sync += \
- If(start,
- ongoing.eq(1)
- ).Elif(done,
- ongoing.eq(0)
- )
- self.comb += self.rr.request[i].eq((start | ongoing) & ~done)
- cases[i] = [slaves[i].connect(master)]
- self.comb += Case(self.grant, cases)
+ def __init__(self, users, master):
+ self.rr = RoundRobin(len(users))
+ self.grant = self.rr.grant
+ cases = {}
+ for i, slave in enumerate(users):
+ sink, source = slave.sink, slave.source
+ start = Signal()
+ done = Signal()
+ ongoing = Signal()
+ self.comb += [
+ start.eq(sink.stb & sink.sop),
+ done.eq(source.stb & source.last & source.eop & source.ack)
+ ]
+ self.sync += \
+ If(start,
+ ongoing.eq(1)
+ ).Elif(done,
+ ongoing.eq(0)
+ )
+ self.comb += self.rr.request[i].eq((start | ongoing) & ~done)
+ cases[i] = [users[i].connect(master)]
+ self.comb += Case(self.grant, cases)
from migen.bank.description import *
class LiteSATABISTGenerator(Module):
- def __init__(self, sata_master_port):
+ def __init__(self, user_port):
self.start = Signal()
self.sector = Signal(48)
self.count = Signal(16)
###
- source, sink = sata_master_port.source, sata_master_port.sink
+ source, sink = user_port.sink, user_port.source
self.counter = counter = Counter(bits_sign=32)
self.sync += If(sink.stb & sink.ack, self.aborted.eq(sink.failed))
class LiteSATABISTChecker(Module):
- def __init__(self, sata_master_port):
+ def __init__(self, user_port):
self.start = Signal()
self.sector = Signal(48)
self.count = Signal(16)
###
- source, sink = sata_master_port.source, sata_master_port.sink
+ source, sink = user_port.sink, user_port.source
self.counter = counter = Counter(bits_sign=32)
self.error_counter = Counter(self.errors, bits_sign=32)
]
class LiteSATABISTIdentify(Module):
- def __init__(self, sata_master_port):
+ def __init__(self, user_port):
self.start = Signal()
self.done = Signal()
###
- source, sink = sata_master_port.source, sata_master_port.sink
+ source, sink = user_port.sink, user_port.source
self.fsm = fsm = FSM(reset_state="IDLE")
fsm.act("IDLE",
Record.connect(self.sink, master.source),
Record.connect(master.sink, self.source)
]
+
+class LiteSATAUserPort(LiteSATASlavePort):
+ def __init__(self, dw):
+ LiteSATASlavePort.__init__(self, dw)
class LiteSATACrossbar(Module):
def __init__(self, core):
- self.slaves = []
+ self.users = []
self.master = LiteSATAMasterPort(32)
self.comb += [
self.master.source.connect(core.sink),
]
def get_port(self):
- master = LiteSATAMasterPort(32)
- slave = LiteSATASlavePort(32)
- self.comb += master.connect(slave)
- self.slaves.append(slave)
- return master
+ port = LiteSATAUserPort(32)
+ self.users += [port]
+ return port
def get_ports(self, n):
- masters = []
+ ports = []
for i in range(n):
- masters.append(self.get_port())
- return masters
+ ports.append(self.get_port())
+ return ports
def do_finalize(self):
- self.arbiter = LiteSATAArbiter(self.slaves, self.master)
+ self.arbiter = LiteSATAArbiter(self.users, self.master)
link_debug=False, link_random_level=0,
transport_debug=False, transport_loopback=False,
hdd_debug=True)
- self.controller = LiteSATA(self.hdd.phy, with_crossbar=True)
+ self.controller = LiteSATA(self.hdd.phy)
self.generator = LiteSATABISTGenerator(self.controller.crossbar.get_port())
self.checker = LiteSATABISTChecker(self.controller.crossbar.get_port())
revision = soc.sata_phy.revision
frequency = frequencies[soc.sata_phy.revision]
has_bist = hasattr(soc.sata, "bist")
- has_crossbar = hasattr(soc.sata, "crossbar")
- ports = 1 if not has_crossbar else len(soc.sata.crossbar.slaves)
+ user_ports = len(soc.sata.crossbar.users)
print("""
__ _ __ _______ _________
====== Building options: ======
SATA revision: {} / {} MHz
+User ports: {}
BIST: {}
-Crossbar: {}
-Ports: {}
===============================""".format(
revision, frequency,
- has_bist,
- has_crossbar,
- ports
+ user_ports,
+ has_bist
)
)
# SATA PHY/Core/Frontend
self.sata_phy = LiteSATAPHY(platform.device, platform.request("sata"), "SATA2", clk_freq)
self.comb += self.crg.reset.eq(self.sata_phy.ctrl.need_reset) # XXX FIXME
- self.sata = LiteSATA(self.sata_phy, with_crossbar=True, with_bist=True, with_bist_csr=True)
+ self.sata = LiteSATA(self.sata_phy, with_bist=True, with_bist_csr=True)
# Status Leds
self.leds = BISTLeds(platform, self.sata_phy)
# SATA PHY/Core/Frontend
self.sata_phy = LiteSATAPHY(platform.device, platform.request("sata"), "SATA2", clk_freq)
- self.sata = LiteSATA(self.sata_phy, with_crossbar=True)
+ self.sata = LiteSATA(self.sata_phy)
# Get user ports from crossbar
- n = 1
- self.crossbar_ports = self.sata.crossbar.get_ports(n)
+ self.user_ports = self.sata.crossbar.get_ports(4)
def get_ios(self):
# clock / reset
sink_layout = command_tx_description(32).get_full_layout()
source_layout = command_rx_description(32).get_full_layout()
- for crossbar_port in self.crossbar_ports:
+ for port in self.user_ports:
for e in _iter_layout(sink_layout):
- obj = getattr(crossbar_port.source, e[0])
+ obj = getattr(port.sink, e[0])
ios = ios.union({obj})
for e in _iter_layout(source_layout):
- obj = getattr(crossbar_port.sink, e[0])
+ obj = getattr(port.source, e[0])
ios = ios.union({obj})
return ios