[> Intro
-----------
-LiteSATA provides a small footprint and configurable SATA1/2/3 core.
+LiteSATA provides a small footprint and configurable SATA gen1/2/3 core.
LiteSATA is part of LiteX libraries whose aims is to lower entry level of complex
FPGA IP cores by providing simple, elegant and efficient implementations of
About LiteSATA
================
-LiteSATA provides a small footprint and configurable SATA1/2/3 core.
+LiteSATA provides a small footprint and configurable SATA gen1/2/3 core.
LiteSATA is part of LiteX libraries whose aims is to lower entry level of complex
FPGA IP cores by providing simple, elegant and efficient implementations of
<img alt="./_static/LiteSATA_logo_full.png" src="_static/LiteSATA_logo_full.png">
-<h3>LiteSATA provides a <b>small footprint and configurable FPGA SATA1/2/3 core</b>.</h3>
+<h3>LiteSATA provides a <b>small footprint and configurable FPGA SATA gen1/2/3 core</b>.</h3>
<div class="container" style="width:100%;margin-bottom:10px;">
from migen.actorlib.fifo import *
from migen.actorlib.structuring import Pipeline, Converter
-# PHY / Link Layers
+bitrates = {
+ "sata_gen3" : 6.0,
+ "sata_gen2" : 3.0,
+ "sata_gen1" : 1.5,
+}
+
frequencies = {
- "SATA3" : 150.0,
- "SATA2" : 75.0,
- "SATA1" : 37.5,
+ "sata_gen3" : 150.0,
+ "sata_gen2" : 75.0,
+ "sata_gen1" : 37.5,
}
+# PHY / Link Layers
primitives = {
"ALIGN" : 0x7B4A4ABC,
"CONT" : 0X9999AA7C,
]
# clock domain crossing
- # (SATA3) 300MHz sata_rx clk to sys_clk
- # (SATA2) 150MHz sata_rx clk to sys_clk
- # (SATA1) 75MHz sata_rx clk to sys_clk
+ # (sata_gen3) 300MHz sata_rx clk to sys_clk
+ # (sata_gen2) 150MHz sata_rx clk to sys_clk
+ # (sata_gen1) 75MHz sata_rx clk to sys_clk
# requirements:
# due to the convertion ratio of 2, sys_clk need to be > sata_rx/2
# source destination is always able to accept data (ack always 1)
###
# clock domain crossing
- # (SATA3) sys_clk to 300MHz sata_tx clk
- # (SATA2) sys_clk to 150MHz sata_tx clk
- # (SATA1) sys_clk to 75MHz sata_tx clk
+ # (sata_gen3) sys_clk to 300MHz sata_tx clk
+ # (sata_gen2) sys_clk to 150MHz sata_tx clk
+ # (sata_gen1) sys_clk to 75MHz sata_tx clk
# requirements:
# source destination is always able to accept data (ack always 1)
fifo = AsyncFIFO(phy_description(32), 4)
self.clock_domains.cd_sata_rx = ClockDomain()
# CPLL
- # (SATA3) 150MHz / VCO @ 3GHz / Line rate @ 6Gbps
- # (SATA2 & SATA1) VCO still @ 3 GHz, Line rate is decreased with output dividers.
+ # (sata_gen3) 150MHz / VCO @ 3GHz / Line rate @ 6Gbps
+ # (sata_gen2 & sata_gen1) VCO still @ 3 GHz, Line rate is decreased with output dividers.
refclk = Signal()
self.specials += Instance("IBUFDS_GTE2",
i_CEB=0,
self.comb += gtx.gtrefclk0.eq(refclk)
# TX clocking
- # (SATA3) 150MHz from CPLL TXOUTCLK, sata_tx clk @ 300MHz (16-bits)
- # (SATA2) 150MHz from CPLL TXOUTCLK, sata_tx clk @ 150MHz (16-bits)
- # (SATA1) 150MHz from CPLL TXOUTCLK, sata_tx clk @ 75MHz (16-bits)
+ # (sata_gen3) 150MHz from CPLL TXOUTCLK, sata_tx clk @ 300MHz (16-bits)
+ # (sata_gen2) 150MHz from CPLL TXOUTCLK, sata_tx clk @ 150MHz (16-bits)
+ # (sata_gen1) 150MHz from CPLL TXOUTCLK, sata_tx clk @ 75MHz (16-bits)
mmcm_reset = Signal()
mmcm_locked = Signal()
mmcm_fb = Signal()
mmcm_clk_i = Signal()
mmcm_clk0_o = Signal()
mmcm_div_config = {
- "SATA1" : 16.0,
- "SATA2" : 8.0,
- "SATA3" : 4.0
+ "sata_gen1" : 16.0,
+ "sata_gen2" : 8.0,
+ "sata_gen3" : 4.0
}
mmcm_div = mmcm_div_config[revision]
self.specials += [
]
# RX clocking
- # (SATA3) sata_rx recovered clk @ 300MHz from GTX RXOUTCLK
- # (SATA2) sata_rx recovered clk @ 150MHz from GTX RXOUTCLK
- # (SATA1) sata_rx recovered clk @ 150MHz from GTX RXOUTCLK
+ # (sata_gen3) sata_rx recovered clk @ 300MHz from GTX RXOUTCLK
+ # (sata_gen2) sata_rx recovered clk @ 150MHz from GTX RXOUTCLK
+ # (sata_gen1) sata_rx recovered clk @ 150MHz from GTX RXOUTCLK
self.specials += [
Instance("BUFG", i_I=gtx.rxoutclk, o_O=self.cd_sata_rx.clk),
]
# Config at startup
div_config = {
- "SATA1" : 4,
- "SATA2" : 2,
- "SATA3" : 1
+ "sata_gen1" : 4,
+ "sata_gen2" : 2,
+ "sata_gen3" : 1
}
rxout_div = div_config[revision]
txout_div = div_config[revision]
cdr_config = {
- "SATA1" : 0x0380008BFF40100008,
- "SATA2" : 0x0388008BFF40200008,
- "SATA3" : 0X0380008BFF10200010
+ "sata_gen1" : 0x0380008BFF40100008,
+ "sata_gen2" : 0x0388008BFF40200008,
+ "sata_gen3" : 0X0380008BFF10200010
}
rxcdr_cfg = cdr_config[revision]
revision = soc.sata_phy.revision
- frequency = frequencies[soc.sata_phy.revision]
has_bist = hasattr(soc.sata, "bist")
user_ports = len(soc.sata.crossbar.users)
based on Migen/MiSoC
====== Building options: ======
-SATA revision: {} / {} MHz
+{} / {} Gbps
+System Clk: {} MHz (min: {} MHz)
User ports: {}
BIST: {}
===============================""".format(
- revision, frequency,
+ revision.replace("sata_", "SATA "), bitrates[revision],
+ soc.clk_freq/1000000, frequencies[revision],
user_ports,
has_bist
)
setup(
name="litesata",
version="unknown",
- description="Generic open-source SATA1/2/3 controller",
+ description="small footprint and configurable SATA gen1/2/3 core",
long_description=README,
author="Florent Kermarrec",
author_email="florent@enjoy-digital.fr",
self.submodules.crg = _CRG(platform)
# SATA PHY/Core/Frontend
- self.submodules.sata_phy = LiteSATAPHY(platform.device, platform.request("sata"), "SATA2", clk_freq)
+ self.submodules.sata_phy = LiteSATAPHY(platform.device, platform.request("sata"), "sata_gen2", clk_freq)
self.comb += self.crg.reset.eq(self.sata_phy.ctrl.need_reset) # XXX FIXME
self.submodules.sata = LiteSATA(self.sata_phy, with_bist=True, with_bist_csr=True)
from litesata.phy import LiteSATAPHY
from litesata import LiteSATA
-class _CRG(Module):
- def __init__(self, platform):
- self.clock_domains.cd_sys = ClockDomain()
-
class LiteSATACore(Module):
default_platform = "verilog_backend"
-
- def __init__(self, platform):
- clk_freq = 166*1000000
- self.crg = _CRG(platform)
+ def __init__(self, platform, clk_freq=166*1000000, nports=4):
+ self.clk_freq = clk_freq
# SATA PHY/Core/Frontend
- self.submodules.sata_phy = LiteSATAPHY(platform.device, platform.request("sata"), "SATA2", clk_freq)
+ self.submodules.sata_phy = LiteSATAPHY(platform.device, platform.request("sata"), "sata_gen2", clk_freq)
self.submodules.sata = LiteSATA(self.sata_phy)
# Get user ports from crossbar
- self.user_ports = self.sata.crossbar.get_ports(4)
+ self.user_ports = self.sata.crossbar.get_ports(nports)
def get_ios(self):
ios = set()