Skip to content

Commit 591e8e6

Browse files
committed
targets: add SATA support to ECPIX-5
Add an optional Gen2 LiteSATA PHY/core using DCU1 channel 0 and a dedicated 150MHz reference PLL. Correct the platform SATA resource to expose only the DCU differential data lanes.
1 parent 40c8af3 commit 591e8e6

3 files changed

Lines changed: 33 additions & 8 deletions

File tree

docs/boards_inventory.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ python3 .github/scripts/generate_board_inventory.py --write
9797
| `kosagi_fomu` | kosagi_fomu_pvt | icestorm | `12000000.0` | - | included |
9898
| `kosagi_netv2` | kosagi_netv2 | vivado | `100000000.0` | Ethernet, SDCard, SPI SDCard, PCIe | included |
9999
| `krtkl_snickerdoodle` | krtkl_snickerdoodle | vivado | `100000000.0` | - | included |
100-
| `lambdaconcept_ecpix5` | lambdaconcept_ecpix5 | trellis | `75000000.0` | Ethernet, Etherbone, SDCard, Video Terminal, Video Framebuffer | included |
100+
| `lambdaconcept_ecpix5` | lambdaconcept_ecpix5 | trellis | `75000000.0` | Ethernet, Etherbone, SDCard, SATA, Video Terminal, Video Framebuffer | included |
101101
| `lattice_certus_nx_versa` | lattice_certus_nx_versa | radiant | `75000000.0` | SPI Flash | included |
102102
| `lattice_certuspro_nx_evn` | lattice_certuspro_nx_evn | radiant | `75000000.0` | - | included |
103103
| `lattice_certuspro_nx_versa` | lattice_certuspro_nx_versa | radiant | `75000000.0` | PCIe | included |

litex_boards/platforms/lambdaconcept_ecpix5.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,12 @@
115115
IOStandard("LVCMOS33"),
116116
),
117117

118-
# Sata
118+
# SATA (DCU1/CH0).
119119
("sata", 0,
120-
Subsignal("clk_p", Pins("AF12")),
121-
Subsignal("clk_n", Pins("AF13")),
122120
Subsignal("rx_p", Pins("AF15")),
123121
Subsignal("rx_n", Pins("AF16")),
124122
Subsignal("tx_p", Pins("AD16")),
125123
Subsignal("tx_n", Pins("AD17")),
126-
IOStandard("LVCMOS33"),
127124
),
128125

129126
# SPIFlash

litex_boards/targets/lambdaconcept_ecpix5.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
# CRG ----------------------------------------------------------------------------------------------
2929

3030
class _CRG(LiteXModule):
31-
def __init__(self, platform, sys_clk_freq):
31+
def __init__(self, platform, sys_clk_freq, with_sata=False):
3232
self.rst = Signal()
3333
self.cd_init = ClockDomain()
3434
self.cd_por = ClockDomain()
@@ -58,6 +58,16 @@ def __init__(self, platform, sys_clk_freq):
5858
pll.register_clkin(clk100, 100e6)
5959
pll.create_clkout(self.cd_sys2x_i, 2*sys_clk_freq)
6060
pll.create_clkout(self.cd_init, 25e6)
61+
62+
plls_locked = pll.locked
63+
if with_sata:
64+
# Keep SATA's fixed reference independent from the variable system clock.
65+
self.cd_sata_refclk = ClockDomain(reset_less=True)
66+
self.sata_pll = sata_pll = ECP5PLL()
67+
sata_pll.register_clkin(clk100, 100e6)
68+
sata_pll.create_clkout(self.cd_sata_refclk, 150e6)
69+
plls_locked = plls_locked & sata_pll.locked
70+
6171
self.specials += [
6272
Instance("ECLKSYNCB",
6373
i_ECLKI = self.cd_sys2x_i.clk,
@@ -69,7 +79,7 @@ def __init__(self, platform, sys_clk_freq):
6979
i_CLKI = self.cd_sys2x.clk,
7080
i_RST = self.reset,
7181
o_CDIVX = self.cd_sys.clk),
72-
AsyncResetSynchronizer(self.cd_sys, ~pll.locked | self.reset),
82+
AsyncResetSynchronizer(self.cd_sys, ~plls_locked | self.reset),
7383
]
7484

7585
# BaseSoC ------------------------------------------------------------------------------------------
@@ -81,14 +91,15 @@ def __init__(self, device="85F", sys_clk_freq=75e6, toolchain="trellis",
8191
eth_ip = "192.168.1.50",
8292
remote_ip = None,
8393
eth_dynamic_ip = False,
94+
with_sata = False,
8495
with_video_terminal = False,
8596
with_video_framebuffer = False,
8697
with_led_chaser = True,
8798
**kwargs):
8899
platform = lambdaconcept_ecpix5.Platform(device=device, toolchain=toolchain)
89100

90101
# CRG --------------------------------------------------------------------------------------
91-
self.crg = _CRG(platform, sys_clk_freq)
102+
self.crg = _CRG(platform, sys_clk_freq, with_sata=with_sata)
92103

93104
# SoCCore ----------------------------------------------------------------------------------
94105
SoCCore.__init__(self, platform, sys_clk_freq,
@@ -121,6 +132,21 @@ def __init__(self, device="85F", sys_clk_freq=75e6, toolchain="trellis",
121132
if with_ethernet:
122133
self.add_ethernet(phy=self.ethphy, dynamic_ip=eth_dynamic_ip, local_ip=eth_ip, remote_ip=remote_ip)
123134

135+
# SATA -------------------------------------------------------------------------------------
136+
if with_sata:
137+
from litesata.phy import LiteSATAPHY
138+
139+
self.sata_phy = LiteSATAPHY(platform.device,
140+
refclk = self.crg.cd_sata_refclk.clk,
141+
pads = platform.request("sata"),
142+
gen = "gen2",
143+
clk_freq = sys_clk_freq,
144+
data_width = 16,
145+
dual = 1,
146+
channel = 0,
147+
)
148+
self.add_sata(phy=self.sata_phy, mode="read+write")
149+
124150
# HDMI -------------------------------------------------------------------------------------
125151
if with_video_terminal or with_video_framebuffer:
126152
# PHY + IT6613 I2C initialization.
@@ -234,6 +260,7 @@ def main():
234260
parser.add_target_argument("--device", default="85F", help="ECP5 device (45F or 85F).")
235261
parser.add_target_argument("--sys-clk-freq", default=75e6, type=float, help="System clock frequency.")
236262
parser.add_target_argument("--with-sdcard", action="store_true", help="Enable SDCard support.")
263+
parser.add_target_argument("--with-sata", action="store_true", help="Enable SATA support.")
237264
ethopts = parser.target_group.add_mutually_exclusive_group()
238265
ethopts.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support.")
239266
ethopts.add_argument("--with-etherbone", action="store_true", help="Enable Etherbone support.")
@@ -255,6 +282,7 @@ def main():
255282
eth_ip = args.eth_ip,
256283
remote_ip = args.remote_ip,
257284
eth_dynamic_ip = args.eth_dynamic_ip,
285+
with_sata = args.with_sata,
258286
with_video_terminal = args.with_video_terminal,
259287
with_video_framebuffer = args.with_video_framebuffer,
260288
**parser.soc_argdict

0 commit comments

Comments
 (0)