#
# This file is part of LiteSPI
#
# Copyright (c) 2020 Antmicro <www.antmicro.com>
# SPDX-License-Identifier: BSD-2-Clause

from migen import *
from migen.genlib.cdc import MultiReg
from migen.genlib.misc import WaitTimer

from litespi.common import *

from litex.soc.interconnect.csr import *

from litex.soc.integration.doc import AutoDoc, ModuleDoc

from litespi.phy.generic_sdr import LiteSPISDRPHYCore
from litespi.phy.generic_ddr import LiteSPIDDRPHYCore

# LiteSPI PHY --------------------------------------------------------------------------------------

class LiteSPIPHY(Module,AutoDoc, AutoCSR,  ModuleDoc):
    """LiteSPI PHY instantiator

    The ``LiteSPIPHY`` class instantiate generic PHY - ``LiteSPIPHYCore`` that can be connected to the ``LiteSPICore``,
    handles optional clock domain wrapping for whole PHY and interfaces streams and CS signal from PHY logic.

    Parameters
    ----------
    pads : Object
        SPI pads description.

    flash : SpiNorFlashModule
        SpiNorFlashModule configuration object.

    device : str
        Device type for use by the ``LiteSPIClkGen``.

    clock_domain : str
        Name of LiteSPI clock domain.

    default_divisor : int (1:1 rate)
        Default frequency divisor for clkgen.

    rate : str
        Rate: 1:1 SDR, 1:2 DDR.

    Attributes
    ----------
    source : Endpoint(spi_phy2core_layout), out
        Data stream from ``LiteSPIPHYCore``.

    sink : Endpoint(spi_core2phy_layout), in
        Control stream from ``LiteSPIPHYCore``.

    cs : Signal(), in
        Flash CS signal from ``LiteSPIPHYCore``.
    """

    def __init__(self, pads, flash, device="xc7", clock_domain="sys", default_divisor=9, cs_delay=10, rate="1:1"):
        self.phy = {
            "1:1": LiteSPISDRPHYCore(pads, flash, device, clock_domain, default_divisor, cs_delay),
            "1:2": LiteSPIDDRPHYCore(pads, flash, cs_delay)
        }[rate]

        self.flash = flash

        self.source = self.phy.source
        self.sink   = self.phy.sink
        self.cs     = self.phy.cs

        # # #

        if clock_domain != "sys":
            self.phy = ClockDomainsRenamer(clock_domain)(self.phy)

        self.submodules.spiflash_phy = self.phy

    def get_csrs(self):
        return self.spiflash_phy.get_csrs()

@@ -1726,39 +1726,86 @@
     
-self.phy = %7B%0A            %221:1%22:
+assert rate in %5B%221:1%22, %221:2%22%5D%0A        if rate == %221:1%22:%0A            self.phy =
  Lit
@@ -1880,17 +1880,16 @@
 s_delay)
-,
 %0A       
@@ -1893,18 +1893,48 @@
     
-    %221:2%22:
+if rate == %221:2%22:%0A            self.phy =
  Lit
@@ -1974,24 +1974,8 @@
 lay)
-%0A        %7D%5Brate%5D
 %0A%0A  

Fix PHY selection.