From 684c1640bba9c5786d46667b4d139cca0ce5986f Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Sat, 18 Jan 2020 21:40:04 +0100 Subject: [PATCH] add Linsn RV901T support --- .../partner/platforms/linsn_rv901t.py | 289 ++++++++++++++++++ litex_boards/partner/targets/linsn_rv901t.py | 120 ++++++++ 2 files changed, 409 insertions(+) create mode 100644 litex_boards/partner/platforms/linsn_rv901t.py create mode 100755 litex_boards/partner/targets/linsn_rv901t.py diff --git a/litex_boards/partner/platforms/linsn_rv901t.py b/litex_boards/partner/platforms/linsn_rv901t.py new file mode 100644 index 0000000..4f0c250 --- /dev/null +++ b/litex_boards/partner/platforms/linsn_rv901t.py @@ -0,0 +1,289 @@ +# This file is Copyright (c) 2019-2020 Florent Kermarrec +# This file is Copyright (c) 2019-2020 Serge Bazanski +# License: BSD + +# The Linsn RV901T PCB and IOs have been documented with Chubby75 project +# available at: https://github.com/q3k/chubby75 + +from litex.build.generic_platform import * +from litex.build.xilinx import XilinxPlatform + +# IOs ---------------------------------------------------------------------------------------------- + +_io = [ + # clock + ("clk25", 0, Pins("M9"), IOStandard("LVCMOS33")), + + # led + ("user_led", 0, Pins("F7"), IOStandard("LVCMOS33")), + + # serial + ("serial", 0, + Subsignal("tx", Pins("H5")), + Subsignal("rx", Pins("G6")), + IOStandard("LVCMOS33") + ), + + # ethernet + ("eth_clocks", 0, + Subsignal("tx", Pins("D1")), + Subsignal("rx", Pins("F1")), + IOStandard("LVCMOS33") + ), + ("eth", 0, + Subsignal("rx_ctl", Pins("H1")), + Subsignal("rx_data", Pins("F2 F4 G1 G3")), + Subsignal("tx_ctl", Pins("E4")), + Subsignal("tx_data", Pins("E3 E2 E1 F3")), + IOStandard("LVCMOS33") + ), + + ("eth_clocks", 1, + Subsignal("tx", Pins("J1")), + Subsignal("rx", Pins("K3")), + IOStandard("LVCMOS33") + ), + ("eth", 1, + Subsignal("rx_ctl", Pins("M3")), + Subsignal("rx_data", Pins("L1 L3 M1 M2")), + Subsignal("tx_ctl", Pins("H2")), + Subsignal("tx_data", Pins("J3 K1 K2 H3")), + IOStandard("LVCMOS33") + ), + + # sdram + ("sdram_clock", 0, Pins("K11"), IOStandard("LVCMOS33"), Misc("SLEW=FAST")), + ("sdram_clock", 1, Pins("K12"), IOStandard("LVCMOS33"), Misc("SLEW=FAST")), + ("sdram", 0, + Subsignal("a", Pins("L16 M14 M16 K14 J12 J13 J11 H13 H11 G12 L14")), + Subsignal("dq", Pins( + "C15 C16 D14 E15 E16 F14 F16 G14", + "G11 E12 H14 G16 F15 D16 B16 B15", + "N16 P16 P15 R15 R16 R14 T14 R12", + "T12 T13 T15 M13 N14 M15 L12 L13")), + Subsignal("we_n", Pins("H16")), + Subsignal("ras_n", Pins("J14")), + Subsignal("cas_n", Pins("H15")), + Subsignal("cs_n", Pins("J16")), + Subsignal("ba", Pins("K16 K15")), + IOStandard("LVCMOS33"), Misc("SLEW=FAST") + ), + + # Direction pin for buffers U600 to U607. 1 is input, 0 is output. + ("bufdir", 0, Pins("F13"), IOStandard("LVCMOS33")), +] + +# Connectors --------------------------------------------------------------------------------------- + +_connectors = [ + # Lower connector on board. Pin 1 marked with silkscreen layer, pins then + # alternating through the two rows of the connector. + ("J600", { + # Buffered through U610, shared with J601 + 4: "J6", + # Buffered through U608, shared with J601 + 6: "A11", + + # Buffered through U600 + 7: "P4", + 8: "R1", + 9: "M4", + 10: "L5", + 11: "M5", + 12: "K6", + 13: "T4", + 14: "P5", + + # Buffered through U604 + 15: "P6", + 16: "M7", + 17: "N6", + 18: "M6", + 19: "L7", + 20: "L8", + 21: "P7", + 22: "N8", + + # Buffered through U601 + 23: "M12", + 24: "N11", + 25: "M11", + 26: "M10", + 27: "L10", + 28: "N9", + 29: "P11", + 30: "T11", + + # Buffered through U605 + 31: "R9", + 32: "T9", + 33: "T8", + 34: "R7", + 35: "T7", + 36: "T6", + 37: "R5", + 38: "T5", + + # Buffered through U608, shared with J601 + 39: "A12", + 40: "B12", + 41: "A13", + 42: "C13", + 43: "A14", + 44: "B14", + 45: "C11", + + # Shared with J601 + 47: "E13", + }), + # Upper connector on board. Same numbering as J600. + ("J601", { + # Buffered through U610, shared with J601 + 4: "J6", + # Buffered through U609, shared with J601 + 6: "A11", + + # Buffered through U603 + 7: "D3", + 8: "C3", + 9: "B3", + 10: "D5", + 11: "A4", + 12: "B2", + 13: "A2", + 14: "A3", + + # Buffered through U607 + 15: "A5", + 16: "A6", + 17: "A7", + 18: "A8", + 19: "B8", + 20: "A9", + 21: "A10", + 22: "B10", + + # Buffered through U602 + 23: "E11", + 24: "D12", + 25: "D11", + 26: "E10", + 27: "D9", + 28: "F9", + 29: "D8", + 30: "E8", + + # Buffered through U606 + 31: "E7", + 32: "D6", + 33: "E6", + 34: "C9", + 35: "C8", + 36: "C7", + 37: "C6", + 38: "B6", + + # Buffered through U609, shared with J600 + 39: "A12", + 40: "B12", + 41: "A13", + 42: "C13", + 43: "A14", + 44: "B14", + 45: "C11", + + # Shared with J600 + 47: "E13", + }) +] + +# Extension for HUB75e 'hat' (marked "Huidu Hub75E-10 Support 1/32 ") +hub75e = [ + ("hub75_control", 0, + # bank select (a, b, c, d, e) + Subsignal("bank", Pins("J601:42 J601:41 J601:40 J601:39 J600:6")), + Subsignal("oe", Pins("J600:45")), + Subsignal("stb", Pins("J601:43")), + Subsignal("clk", Pins("J601:44")), + IOStandard("LVCMOS33"), + ), + # J1 + ("hub75_chain", 0, + Subsignal("r", Pins("J601:38 J601:35")), + Subsignal("g", Pins("J601:37 J601:34")), + Subsignal("b", Pins("J601:36 J601:33")), + IOStandard("LVCMOS33"), + ), + # J2 + ("hub75_chain", 1, + Subsignal("r", Pins("J601:32 J601:29")), + Subsignal("g", Pins("J601:31 J601:28")), + Subsignal("b", Pins("J601:30 J601:27")), + IOStandard("LVCMOS33"), + ), + # J3 + ("hub75_chain", 2, + Subsignal("r", Pins("J601:26 J601:23")), + Subsignal("g", Pins("J601:25 J601:22")), + Subsignal("b", Pins("J601:24 J601:21")), + IOStandard("LVCMOS33"), + ), + # J4 + ("hub75_chain", 3, + Subsignal("r", Pins("J601:20 J601:17")), + Subsignal("g", Pins("J601:19 J601:16")), + Subsignal("b", Pins("J601:18 J601:15")), + IOStandard("LVCMOS33"), + ), + # J5 + ("hub75_chain", 4, + Subsignal("r", Pins("J601:14 J601:11")), + Subsignal("g", Pins("J601:13 J601:10")), + Subsignal("b", Pins("J601:12 J601:9")), + IOStandard("LVCMOS33"), + ), + # J6 + ("hub75_chain", 5, + Subsignal("r", Pins("J600:38 J600:35")), + Subsignal("g", Pins("J600:37 J600:34")), + Subsignal("b", Pins("J600:36 J600:33")), + IOStandard("LVCMOS33"), + ), + # J7 + ("hub75_chain", 6, + Subsignal("r", Pins("J600:32 J600:29")), + Subsignal("g", Pins("J600:31 J600:28")), + Subsignal("b", Pins("J600:30 J600:27")), + IOStandard("LVCMOS33"), + ), + # J8 + ("hub75_chain", 7, + Subsignal("r", Pins("J600:26 J600:23")), + Subsignal("g", Pins("J600:25 J600:22")), + Subsignal("b", Pins("J600:24 J600:21")), + IOStandard("LVCMOS33"), + ), + # J9 + ("hub75_chain", 8, + Subsignal("r", Pins("J600:20 J600:17")), + Subsignal("g", Pins("J600:19 J600:16")), + Subsignal("b", Pins("J600:18 J600:15")), + IOStandard("LVCMOS33"), + ), + # J10 + ("hub75_chain", 9, + Subsignal("r", Pins("J600:14 J600:11")), + Subsignal("g", Pins("J600:13 J600:10")), + Subsignal("b", Pins("J600:12 J600:9")), + IOStandard("LVCMOS33"), + ), +] + +# Platform ----------------------------------------------------------------------------------------- + +class Platform(XilinxPlatform): + default_clk_name = "clk25" + default_clk_period = 1e9/25e6 + + def __init__(self): + XilinxPlatform.__init__(self, "xc6slx16-2-ftg256", _io, _connectors) diff --git a/litex_boards/partner/targets/linsn_rv901t.py b/litex_boards/partner/targets/linsn_rv901t.py new file mode 100755 index 0000000..c920c12 --- /dev/null +++ b/litex_boards/partner/targets/linsn_rv901t.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python3 + +# This file is Copyright (c) 2019-2020 Florent Kermarrec +# License: BSD + +import argparse + +from migen import * + +from litex_boards.platforms import linsn_rv901t + +from litex.soc.integration.soc_sdram import * +from litex.soc.integration.builder import * +from litex.soc.cores.clock import S6PLL + +from litedram.modules import M12L64322A +from litedram.phy import GENSDRPHY + +from liteeth.phy.s6rgmii import LiteEthPHYRGMII +from liteeth.mac import LiteEthMAC + +# CRG ---------------------------------------------------------------------------------------------- + +class _CRG(Module): + def __init__(self, platform, sys_clk_freq): + self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_sys_ps = ClockDomain(reset_less=True) + + # # # + + clk25 = platform.request("clk25") + platform.add_period_constraint(clk25, 1e9/25e6) + + self.submodules.pll = pll = S6PLL(speedgrade=-2) + pll.register_clkin(clk25, 25e6) + pll.create_clkout(self.cd_sys, sys_clk_freq) + pll.create_clkout(self.cd_sys_ps, sys_clk_freq, phase=270) + + self.specials += Instance("ODDR2", + p_DDR_ALIGNMENT="NONE", + p_INIT=0, p_SRTYPE="SYNC", + i_D0=0, i_D1=1, i_S=0, i_R=0, i_CE=1, + i_C0=self.cd_sys.clk, i_C1=~self.cd_sys.clk, + o_Q=platform.request("sdram_clock")) + +# BaseSoC ------------------------------------------------------------------------------------------ + +class BaseSoC(SoCSDRAM): + def __init__(self, **kwargs): + platform = linsn_rv901t.Platform() + sys_clk_freq = int(75e6) + + # SoCSDRAM --------------------------------------------------------------------------------- + SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + + # SDR SDRAM -------------------------------------------------------------------------------- + self.submodules.sdrphy = GENSDRPHY(platform.request("sdram")) + sdram_module = M12L64322A(sys_clk_freq, "1:1") + self.register_sdram(self.sdrphy, sdram_module.geom_settings, sdram_module.timing_settings) + +# EthernetSoC -------------------------------------------------------------------------------------- + +class EthernetSoC(BaseSoC): + mem_map = { + "ethmac": 0xb0000000, + } + mem_map.update(BaseSoC.mem_map) + + def __init__(self, eth_phy=0, **kwargs): + BaseSoC.__init__(self, **kwargs) + + # Ethernet --------------------------------------------------------------------------------- + # phy + self.submodules.ethphy = LiteEthPHYRGMII( + clock_pads = self.platform.request("eth_clocks", eth_phy), + pads = self.platform.request("eth", eth_phy)) + self.add_csr("ethphy") + # mac + self.submodules.ethmac = LiteEthMAC( + phy = self.ethphy, + dw = 32, + interface = "wishbone", + endianness = self.cpu.endianness) + self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus, 0x2000) + self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") + self.add_csr("ethmac") + self.add_interrupt("ethmac") + # timing constraints + self.platform.add_period_constraint(self.ethphy.crg.cd_eth_rx.clk, 1e9/125e6) + self.platform.add_period_constraint(self.ethphy.crg.cd_eth_tx.clk, 1e9/125e6) + self.platform.add_false_path_constraints( + self.crg.cd_sys.clk, + self.ethphy.crg.cd_eth_rx.clk, + self.ethphy.crg.cd_eth_tx.clk) + +# Build -------------------------------------------------------------------------------------------- + +def main(): + parser = argparse.ArgumentParser(description="LiteX SoC on Linsn RV901T") + builder_args(parser) + soc_sdram_args(parser) + parser.add_argument("--with-ethernet", action="store_true", + help="enable Ethernet support") + parser.add_argument("--eth-phy", default=0, type=int, + help="Ethernet PHY 0 or 1 (default=0)") + args = parser.parse_args() + + if args.with_ethernet: + soc = EthernetSoC(eth_phy=args.eth_phy, **soc_sdram_argdict(args)) + else: + soc = BaseSoC(**soc_sdram_argdict(args)) + builder = Builder(soc, **builder_argdict(args)) + builder.build() + + +if __name__ == "__main__": + main()