diff --git a/docs/boards_inventory.md b/docs/boards_inventory.md index 3679efc5a..6159e8402 100644 --- a/docs/boards_inventory.md +++ b/docs/boards_inventory.md @@ -97,7 +97,7 @@ python3 .github/scripts/generate_board_inventory.py --write | `kosagi_fomu` | kosagi_fomu_pvt | icestorm | `12000000.0` | - | included | | `kosagi_netv2` | kosagi_netv2 | vivado | `100000000.0` | Ethernet, SDCard, SPI SDCard, PCIe | included | | `krtkl_snickerdoodle` | krtkl_snickerdoodle | vivado | `100000000.0` | - | included | -| `lambdaconcept_ecpix5` | lambdaconcept_ecpix5 | trellis | `75000000.0` | Ethernet, Etherbone, SDCard, Video Terminal, Video Framebuffer | included | +| `lambdaconcept_ecpix5` | lambdaconcept_ecpix5 | trellis | `75000000.0` | Ethernet, Etherbone, SDCard, SATA, Video Terminal, Video Framebuffer | included | | `lattice_certus_nx_versa` | lattice_certus_nx_versa | radiant | `75000000.0` | SPI Flash | included | | `lattice_certuspro_nx_evn` | lattice_certuspro_nx_evn | radiant | `75000000.0` | - | included | | `lattice_certuspro_nx_versa` | lattice_certuspro_nx_versa | radiant | `75000000.0` | PCIe | included | diff --git a/litex_boards/platforms/lambdaconcept_ecpix5.py b/litex_boards/platforms/lambdaconcept_ecpix5.py index 5db26a12f..ab751f421 100644 --- a/litex_boards/platforms/lambdaconcept_ecpix5.py +++ b/litex_boards/platforms/lambdaconcept_ecpix5.py @@ -115,15 +115,12 @@ IOStandard("LVCMOS33"), ), - # Sata + # SATA (DCU1/CH0). ("sata", 0, - Subsignal("clk_p", Pins("AF12")), - Subsignal("clk_n", Pins("AF13")), Subsignal("rx_p", Pins("AF15")), Subsignal("rx_n", Pins("AF16")), Subsignal("tx_p", Pins("AD16")), Subsignal("tx_n", Pins("AD17")), - IOStandard("LVCMOS33"), ), # SPIFlash diff --git a/litex_boards/targets/lambdaconcept_ecpix5.py b/litex_boards/targets/lambdaconcept_ecpix5.py index 24ca3c895..0f1cd7e1a 100755 --- a/litex_boards/targets/lambdaconcept_ecpix5.py +++ b/litex_boards/targets/lambdaconcept_ecpix5.py @@ -28,7 +28,7 @@ # CRG ---------------------------------------------------------------------------------------------- class _CRG(LiteXModule): - def __init__(self, platform, sys_clk_freq): + def __init__(self, platform, sys_clk_freq, with_sata=False): self.rst = Signal() self.cd_init = ClockDomain() self.cd_por = ClockDomain() @@ -58,6 +58,16 @@ def __init__(self, platform, sys_clk_freq): pll.register_clkin(clk100, 100e6) pll.create_clkout(self.cd_sys2x_i, 2*sys_clk_freq) pll.create_clkout(self.cd_init, 25e6) + + plls_locked = pll.locked + if with_sata: + # Keep SATA's fixed reference independent from the variable system clock. + self.cd_sata_refclk = ClockDomain(reset_less=True) + self.sata_pll = sata_pll = ECP5PLL() + sata_pll.register_clkin(clk100, 100e6) + sata_pll.create_clkout(self.cd_sata_refclk, 150e6) + plls_locked = plls_locked & sata_pll.locked + self.specials += [ Instance("ECLKSYNCB", i_ECLKI = self.cd_sys2x_i.clk, @@ -69,7 +79,7 @@ def __init__(self, platform, sys_clk_freq): i_CLKI = self.cd_sys2x.clk, i_RST = self.reset, o_CDIVX = self.cd_sys.clk), - AsyncResetSynchronizer(self.cd_sys, ~pll.locked | self.reset), + AsyncResetSynchronizer(self.cd_sys, ~plls_locked | self.reset), ] # BaseSoC ------------------------------------------------------------------------------------------ @@ -81,6 +91,7 @@ def __init__(self, device="85F", sys_clk_freq=75e6, toolchain="trellis", eth_ip = "192.168.1.50", remote_ip = None, eth_dynamic_ip = False, + with_sata = False, with_video_terminal = False, with_video_framebuffer = False, with_led_chaser = True, @@ -88,7 +99,7 @@ def __init__(self, device="85F", sys_clk_freq=75e6, toolchain="trellis", platform = lambdaconcept_ecpix5.Platform(device=device, toolchain=toolchain) # CRG -------------------------------------------------------------------------------------- - self.crg = _CRG(platform, sys_clk_freq) + self.crg = _CRG(platform, sys_clk_freq, with_sata=with_sata) # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__(self, platform, sys_clk_freq, @@ -121,6 +132,21 @@ def __init__(self, device="85F", sys_clk_freq=75e6, toolchain="trellis", if with_ethernet: self.add_ethernet(phy=self.ethphy, dynamic_ip=eth_dynamic_ip, local_ip=eth_ip, remote_ip=remote_ip) + # SATA ------------------------------------------------------------------------------------- + if with_sata: + from litesata.phy import LiteSATAPHY + + self.sata_phy = LiteSATAPHY(platform.device, + refclk = self.crg.cd_sata_refclk.clk, + pads = platform.request("sata"), + gen = "gen2", + clk_freq = sys_clk_freq, + data_width = 16, + dual = 1, + channel = 0, + ) + self.add_sata(phy=self.sata_phy, mode="read+write") + # HDMI ------------------------------------------------------------------------------------- if with_video_terminal or with_video_framebuffer: # PHY + IT6613 I2C initialization. @@ -234,6 +260,7 @@ def main(): parser.add_target_argument("--device", default="85F", help="ECP5 device (45F or 85F).") parser.add_target_argument("--sys-clk-freq", default=75e6, type=float, help="System clock frequency.") parser.add_target_argument("--with-sdcard", action="store_true", help="Enable SDCard support.") + parser.add_target_argument("--with-sata", action="store_true", help="Enable SATA support.") ethopts = parser.target_group.add_mutually_exclusive_group() ethopts.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support.") ethopts.add_argument("--with-etherbone", action="store_true", help="Enable Etherbone support.") @@ -255,6 +282,7 @@ def main(): eth_ip = args.eth_ip, remote_ip = args.remote_ip, eth_dynamic_ip = args.eth_dynamic_ip, + with_sata = args.with_sata, with_video_terminal = args.with_video_terminal, with_video_framebuffer = args.with_video_framebuffer, **parser.soc_argdict