#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2015 Matt O'Gorman <mog@rldn.net>
# SPDX-License-Identifier: BSD-2-Clause

from litex.build.generic_platform import *
from litex.build.xilinx import XilinxPlatform
from litex.build.xilinx.programmer import XC3SProg

# IOs ----------------------------------------------------------------------------------------------

_io = [
    # Clk / Rst
    ("clk32", 0, Pins("J4"), IOStandard("LVCMOS33")),
    ("clk50", 0, Pins("K3"), IOStandard("LVCMOS33")),

    # Leds
    ("user_led", 0, Pins("P11"), IOStandard("LVCMOS33")),
    ("user_led", 1, Pins("N9"),  IOStandard("LVCMOS33")),
    ("user_led", 2, Pins("M9"),  IOStandard("LVCMOS33")),
    ("user_led", 3, Pins("P9"),  IOStandard("LVCMOS33")),
    ("user_led", 4, Pins("T8"),  IOStandard("LVCMOS33")),
    ("user_led", 5, Pins("N8"),  IOStandard("LVCMOS33")),
    ("user_led", 6, Pins("P8"),  IOStandard("LVCMOS33")),
    ("user_led", 7, Pins("P7"),  IOStandard("LVCMOS33")),

    # Switches
    ("user_sw", 0, Pins("L1"), IOStandard("LVCMOS33"), Misc("PULLUP")),
    ("user_sw", 1, Pins("L3"), IOStandard("LVCMOS33"), Misc("PULLUP")),
    ("user_sw", 2, Pins("L4"), IOStandard("LVCMOS33"), Misc("PULLUP")),
    ("user_sw", 3, Pins("L5"), IOStandard("LVCMOS33"), Misc("PULLUP")),


    # SPIFlash
    ("spiflash", 0,
        Subsignal("cs_n", Pins("T3"), IOStandard("LVCMOS33")),
        Subsignal("clk",  Pins("R11"), IOStandard("LVCMOS33")),
        Subsignal("mosi", Pins("T10"), IOStandard("LVCMOS33")),
        Subsignal("miso", Pins("P10"), IOStandard("LVCMOS33"))
    ),

    # Serial
    ("serial", 0,
        Subsignal("tx", Pins("N6"), IOStandard("LVCMOS33")),  # FTDI D1
        Subsignal("rx", Pins("M7"), IOStandard("LVCMOS33"))   # FTDI D0
    ),

    # USB FIFO
    ("usb_fifo", 0,
        Subsignal("data",  Pins("M7 N6 M6 P5 N5 P4 P2 P1")),
        Subsignal("rxf_n", Pins("N3")),
        Subsignal("txe_n", Pins("N1")),
        Subsignal("rd_n",  Pins("M1")),
        Subsignal("wr_n",  Pins("M2")),
        Subsignal("siwua", Pins("M3")),
        Misc("SLEW=FAST"),
        Drive(8),
        IOStandard("LVCMOS33"),
    ),

    # ADC
    ("adc", 0,
        Subsignal("cs_n", Pins("F6"), IOStandard("LVCMOS33")),
        Subsignal("clk",  Pins("G6"), IOStandard("LVCMOS33")),
        Subsignal("mosi", Pins("H4"), IOStandard("LVCMOS33")),
        Subsignal("miso", Pins("H5"), IOStandard("LVCMOS33"))
    ),

    # Audio
    ("audio", 0,
        Subsignal("a0", Pins("B8"), IOStandard("LVCMOS33")),
        Subsignal("a1", Pins("A8"), IOStandard("LVCMOS33"))
    ),

    # SDR SDRAM
    ("sdram_clock", 0, Pins("G16"), IOStandard("LVCMOS33"), Misc("SLEW=FAST")),
    ("sdram", 0,
        Subsignal("a", Pins(
            "T15 R16 P15 P16 N16 M15 M16 L16",
            "K15 K16 R15 J16 H15")),
        Subsignal("dq", Pins(
            "T13 T12 R12  T9  R9  T7  R7  T6",
            "F16 E15 E16 D16 B16 B15 C16 C15")),
        Subsignal("we_n",  Pins("R5")),
        Subsignal("ras_n", Pins("R2")),
        Subsignal("cas_n", Pins("T4")),
        Subsignal("cs_n",  Pins("R1")),
        Subsignal("cke",   Pins("H16")),
        Subsignal("ba",    Pins("R14 T14")),
        Subsignal("dm",    Pins("T5 F15")),
        Misc("SLEW=FAST"),
        IOStandard("LVCMOS33"),
    ),

    # SDCard
    ("spisdcard", 0,
        Subsignal("clk",  Pins("L12")),
        Subsignal("mosi", Pins("K11"), Misc("PULLUP")),
        Subsignal("cs_n", Pins("K12"), Misc("PULLUP")),
        Subsignal("miso", Pins("M10"), Misc("PULLUP")),
        Misc("SLEW=FAST"),
        IOStandard("LVCMOS33"),
    ),
    ("sdcard", 0,
        Subsignal("data", Pins("M10 L10 J11 K12"), Misc("PULLUP")),
        Subsignal("cmd",  Pins("K11"), Misc("PULLUP")),
        Subsignal("clk",  Pins("L12")),
        Misc("SLEW=FAST"),
        IOStandard("LVCMOS33"),
    ),

    # DVI In
    ("dvi_in", 0,
        Subsignal("clk_p",  Pins("C9"), IOStandard("TMDS_33")),
        Subsignal("clk_n",  Pins("A9"), IOStandard("TMDS_33")),
        Subsignal("data_p", Pins("C7 B6 B5"), IOStandard("TMDS_33")),
        Subsignal("data_n", Pins("A7 A6 A5"), IOStandard("TMDS_33")),
        Subsignal("scl",    Pins("C1"), IOStandard("LVCMOS33")),
        Subsignal("sda",    Pins("B1"), IOStandard("LVCMOS33"))
    ),

    # DVI Out
    ("dvi_out", 0,
        Subsignal("clk_p",  Pins("B14"), IOStandard("TMDS_33")),
        Subsignal("clk_n",  Pins("A14"), IOStandard("TMDS_33")),
        Subsignal("data_p", Pins("C13 B12 C11"), IOStandard("TMDS_33")),
        Subsignal("data_n", Pins("A13 A12 A11"), IOStandard("TMDS_33")),
    )
]

# Connectors ---------------------------------------------------------------------------------------

_connectors = [
    ("A", "E7   C8  D8  E8  D9 A10 B10 C10 E10  F9 F10 D11"),
    ("B", "E11 D14 D12 E12 E13 F13 F12 F14 G12 H14 J14"),
    ("C", "J13 J12 K14 L14 L13 M14 M13 N14 M12 N12 P12 M11"),
    ("D", "D6 C6 E6 C5"),
    ("E", "D5 A4 G5 A3 B3 A2 B2 C3 C2 D3 D1 E3"),
    ("F", "E2 E1 E4 F4 F5 G3 F3 G1 H3 H1 H2 J1")
]

# Platform -----------------------------------------------------------------------------------------

class Platform(XilinxPlatform):
    default_clk_name   = "clk32"
    default_clk_period = 1e9/32e6

    def __init__(self, device="xc6slx25"):
        assert device in ["xc6slx9", "xc6slx25"]
        XilinxPlatform.__init__(self, device+"-3-ftg256", _io, _connectors)

    def create_programmer(self):
        return XC3SProg(cable="ftdi")

    def do_finalize(self, fragment):
        XilinxPlatform.do_finalize(self, fragment)
        self.add_period_constraint(self.lookup_request("clk32", loose=True), 1e9/32e6)
        self.add_period_constraint(self.lookup_request("clk50", loose=True), 1e9/50e6)
