Ejemplo n.º 1
0
def get_ddr2_phy_init_sequence(phy_settings, timing_settings):
    cl = phy_settings.cl
    bl = 4
    wr = 2
    mr = log2_int(bl) + (cl << 4) + (wr << 9)
    emr = 0
    emr2 = 0
    emr3 = 0
    reset_dll = 1 << 8
    ocd = 7 << 7

    init_sequence = [
        ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
        ("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
        ("Load Extended Mode Register 3", emr3, 3, cmds["MODE_REGISTER"], 0),
        ("Load Extended Mode Register 2", emr2, 2, cmds["MODE_REGISTER"], 0),
        ("Load Extended Mode Register", emr, 1, cmds["MODE_REGISTER"], 0),
        ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
        ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
        ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
        ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
        ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200),
        ("Load Extended Mode Register / OCD Default", emr+ocd, 1, cmds["MODE_REGISTER"], 0),
        ("Load Extended Mode Register / OCD Exit", emr, 1, cmds["MODE_REGISTER"], 0),
    ]

    return init_sequence, None
Ejemplo n.º 2
0
 def load(cls):
     settings = get_litedram_settings()
     if settings.phy.memtype == "SDR":
         burst_length = settings.phy.nphases
     else:
         from litedram.common import burst_lengths
         burst_length = burst_lengths[settings.phy.memtype]
     address_align = log2_int(burst_length)
     return cls(
         colbits=settings.geom.colbits,
         rowbits=settings.geom.rowbits,
         bankbits=settings.geom.bankbits,
         address_align=address_align,
         address_mapping=settings.address_mapping,
         dram_port_width=settings.phy.nphases * settings.phy.dfi_databits,
     )
Ejemplo n.º 3
0
def get_sdr_phy_init_sequence(phy_settings, timing_settings):
    cl = phy_settings.cl
    bl = 1
    mr = log2_int(bl) + (cl << 4)
    reset_dll = 1 << 8

    init_sequence = [
        ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
        ("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
        ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
        ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
        ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
        ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
        ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
    ]

    return init_sequence, None
Ejemplo n.º 4
0
    def __init__(self, platform, sys_clk_freq):
        self.clock_domains.cd_sys = ClockDomain()
        self.clock_domains.cd_por = ClockDomain()

        # Clock from HFOSC
        self.submodules.sys_clk = sys_osc = NXOSCA()
        sys_osc.create_hf_clk(self.cd_sys, sys_clk_freq)
        # We make the period constraint 10% tighter than our actual system
        # clock frequency, because the CrossLink-NX internal oscillator runs
        # at ±10% of nominal frequency.
        platform.add_period_constraint(self.cd_sys.clk,
                                       1e9 / (sys_clk_freq * 1.1))

        # Power On Reset
        por_cycles = 4096
        por_counter = Signal(log2_int(por_cycles), reset=por_cycles - 1)
        self.comb += self.cd_por.clk.eq(self.cd_sys.clk)
        self.sync.por += If(por_counter != 0, por_counter.eq(por_counter - 1))
        self.specials += AsyncResetSynchronizer(self.cd_sys,
                                                (por_counter != 0))
Ejemplo n.º 5
0
def get_sdram_phy_init_sequence(phy_settings, timing_settings):
    # init sequence
    cmds = {
        "PRECHARGE_ALL": "DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
        "MODE_REGISTER":
        "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
        "AUTO_REFRESH": "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_CS",
        "UNRESET": "DFII_CONTROL_ODT|DFII_CONTROL_RESET_N",
        "CKE": "DFII_CONTROL_CKE|DFII_CONTROL_ODT|DFII_CONTROL_RESET_N"
    }

    cl = phy_settings.cl
    mr1 = None

    if phy_settings.memtype == "SDR":
        bl = 1
        mr = log2_int(bl) + (cl << 4)
        reset_dll = 1 << 8

        init_sequence = [
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(
                cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0,
             cmds["MODE_REGISTER"], 200)
        ]

    elif phy_settings.memtype == "DDR":
        bl = 4
        mr = log2_int(bl) + (cl << 4)
        emr = 0
        reset_dll = 1 << 8

        init_sequence = [
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Load Extended Mode Register", emr, 1, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(
                cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0,
             cmds["MODE_REGISTER"], 200)
        ]

    elif phy_settings.memtype == "LPDDR":
        bl = 4
        mr = log2_int(bl) + (cl << 4)
        emr = 0
        reset_dll = 1 << 8

        init_sequence = [
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Load Extended Mode Register", emr, 2, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(
                cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0,
             cmds["MODE_REGISTER"], 200)
        ]

    elif phy_settings.memtype == "DDR2":
        bl = 4
        wr = 2
        mr = log2_int(bl) + (cl << 4) + (wr << 9)
        emr = 0
        emr2 = 0
        emr3 = 0
        reset_dll = 1 << 8
        ocd = 7 << 7

        init_sequence = [
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Load Extended Mode Register 3", emr3, 3, cmds["MODE_REGISTER"],
             0),
            ("Load Extended Mode Register 2", emr2, 2, cmds["MODE_REGISTER"],
             0),
            ("Load Extended Mode Register", emr, 1, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(
                cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0,
             cmds["MODE_REGISTER"], 200),
            ("Load Extended Mode Register / OCD Default", emr + ocd, 1,
             cmds["MODE_REGISTER"], 0),
            ("Load Extended Mode Register / OCD Exit", emr, 1,
             cmds["MODE_REGISTER"], 0),
        ]
    elif phy_settings.memtype == "DDR3":
        bl = 8
        cwl = phy_settings.cwl

        def format_mr0(bl, cl, wr, dll_reset):
            bl_to_mr0 = {4: 0b10, 8: 0b00}
            cl_to_mr0 = {
                5: 0b0010,
                6: 0b0100,
                7: 0b0110,
                8: 0b1000,
                9: 0b1010,
                10: 0b1100,
                11: 0b1110,
                12: 0b0001,
                13: 0b0011,
                14: 0b0101
            }
            wr_to_mr0 = {
                16: 0b000,
                5: 0b001,
                6: 0b010,
                7: 0b011,
                8: 0b100,
                10: 0b101,
                12: 0b110,
                14: 0b111
            }
            mr0 = bl_to_mr0[bl]
            mr0 |= (cl_to_mr0[cl] & 1) << 2
            mr0 |= ((cl_to_mr0[cl] >> 1) & 0b111) << 4
            mr0 |= dll_reset << 8
            mr0 |= wr_to_mr0[wr] << 9
            return mr0

        def format_mr1(ron, rtt_nom):
            mr1 = ((ron >> 0) & 1) << 1
            mr1 |= ((ron >> 1) & 1) << 5
            mr1 |= ((rtt_nom >> 0) & 1) << 2
            mr1 |= ((rtt_nom >> 1) & 1) << 6
            mr1 |= ((rtt_nom >> 2) & 1) << 9
            return mr1

        def format_mr2(cwl, rtt_wr):
            mr2 = (cwl - 5) << 3
            mr2 |= rtt_wr << 9
            return mr2

        z_to_rtt_nom = {
            "disabled": 0,
            "60ohm": 1,
            "120ohm": 2,
            "40ohm": 3,
            "20ohm": 4,
            "30ohm": 5
        }

        z_to_rtt_wr = {
            "disabled": 0,
            "60ohm": 1,
            "120ohm": 2,
        }

        z_to_ron = {
            "40ohm": 0,
            "34ohm": 1,
        }

        # default electrical settings (point to point)
        rtt_nom = "60ohm"
        rtt_wr = "60ohm"
        ron = "34ohm"

        # override electrical settings if specified
        if hasattr(phy_settings, "rtt_nom"):
            rtt_nom = phy_settings.rtt_nom
        if hasattr(phy_settings, "rtt_wr"):
            rtt_wr = phy_settings.rtt_wr
        if hasattr(phy_settings, "ron"):
            ron = phy_settings.ron

        wr = max(timing_settings.tWTR * phy_settings.nphases,
                 5)  # >= ceiling(tWR/tCK)
        mr0 = format_mr0(bl, cl, wr, 1)
        mr1 = format_mr1(z_to_ron[ron], z_to_rtt_nom[rtt_nom])
        mr2 = format_mr2(cwl, z_to_rtt_wr[rtt_wr])
        mr3 = 0

        init_sequence = [
            ("Release reset", 0x0000, 0, cmds["UNRESET"], 50000),
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 10000),
            ("Load Mode Register 2, CWL={0:d}".format(cwl), mr2, 2,
             cmds["MODE_REGISTER"], 0),
            ("Load Mode Register 3", mr3, 3, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register 1", mr1, 1, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register 0, CL={0:d}, BL={1:d}".format(cl, bl), mr0, 0,
             cmds["MODE_REGISTER"], 200),
            ("ZQ Calibration", 0x0400, 0, "DFII_COMMAND_WE|DFII_COMMAND_CS",
             200),
        ]
    elif phy_settings.memtype == "DDR4":
        bl = 8
        cwl = phy_settings.cwl

        def format_mr0(bl, cl, wr, dll_reset):
            bl_to_mr0 = {4: 0b10, 8: 0b00}
            cl_to_mr0 = {
                9: 0b00000,
                10: 0b00001,
                11: 0b00010,
                12: 0b00011,
                13: 0b00100,
                14: 0b00101,
                15: 0b00110,
                16: 0b00111,
                18: 0b01000,
                20: 0b01001,
                22: 0b01010,
                24: 0b01011,
                23: 0b01100,
                17: 0b01101,
                19: 0b01110,
                21: 0b01111,
                25: 0b10000,
                26: 0b10001,
                27: 0b10010,
                28: 0b10011,
                29: 0b10100,
                30: 0b10101,
                31: 0b10110,
                32: 0b10111,
            }
            wr_to_mr0 = {
                10: 0b0000,
                12: 0b0001,
                14: 0b0010,
                16: 0b0011,
                18: 0b0100,
                20: 0b0101,
                24: 0b0110,
                22: 0b0111,
                26: 0b1000,
                28: 0b1001,
            }
            mr0 = bl_to_mr0[bl]
            mr0 |= (cl_to_mr0[cl] & 0b1) << 2
            mr0 |= ((cl_to_mr0[cl] >> 1) & 0b111) << 4
            mr0 |= ((cl_to_mr0[cl] >> 4) & 0b1) << 12
            mr0 |= dll_reset << 8
            mr0 |= (wr_to_mr0[wr] & 0b111) << 9
            mr0 |= (wr_to_mr0[wr] >> 3) << 13
            return mr0

        def format_mr1(dll_enable, ron, rtt_nom):
            mr1 = dll_enable
            mr1 |= ((ron >> 0) & 0b1) << 1
            mr1 |= ((ron >> 1) & 0b1) << 2
            mr1 |= ((rtt_nom >> 0) & 0b1) << 8
            mr1 |= ((rtt_nom >> 1) & 0b1) << 9
            mr1 |= ((rtt_nom >> 2) & 0b1) << 10
            return mr1

        def format_mr2(cwl, rtt_wr):
            cwl_to_mr2 = {
                9: 0b000,
                10: 0b001,
                11: 0b010,
                12: 0b011,
                14: 0b100,
                16: 0b101,
                18: 0b110,
                20: 0b111
            }
            mr2 = cwl_to_mr2[cwl] << 3
            mr2 |= rtt_wr << 9
            return mr2

        def format_mr6(tccd):
            tccd_to_mr6 = {4: 0b000, 5: 0b001, 6: 0b010, 7: 0b011, 8: 0b100}
            mr6 = tccd_to_mr6[tccd] << 10
            return mr6

        z_to_rtt_nom = {
            "disabled": 0b000,
            "60ohm": 0b001,
            "120ohm": 0b010,
            "40ohm": 0b011,
            "240ohm": 0b100,
            "48ohm": 0b101,
            "80ohm": 0b110,
            "34ohm": 0b111
        }

        z_to_rtt_wr = {
            "disabled": 0b000,
            "120ohm": 0b001,
            "240ohm": 0b010,
            "high-z": 0b011,
            "80ohm": 0b100,
        }

        z_to_ron = {
            "34ohm": 0b00,
            "48ohm": 0b01,
        }

        # default electrical settings (point to point)
        rtt_nom = "40ohm"
        rtt_wr = "120ohm"
        ron = "34ohm"

        # override electrical settings if specified
        if hasattr(phy_settings, "rtt_nom"):
            rtt_nom = phy_settings.rtt_nom
        if hasattr(phy_settings, "rtt_wr"):
            rtt_wr = phy_settings.rtt_wr
        if hasattr(phy_settings, "ron"):
            ron = phy_settings.ron

        wr = max(timing_settings.tWTR * phy_settings.nphases,
                 10)  # >= ceiling(tWR/tCK)
        mr0 = format_mr0(bl, cl, wr, 1)
        mr1 = format_mr1(1, z_to_ron[ron], z_to_rtt_nom[rtt_nom])
        mr2 = format_mr2(cwl, z_to_rtt_wr[rtt_wr])
        mr3 = 0
        mr4 = 0
        mr5 = 0
        mr6 = format_mr6(4)  # FIXME: tCCD

        init_sequence = [
            ("Release reset", 0x0000, 0, cmds["UNRESET"], 50000),
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 10000),
            ("Load Mode Register 3", mr3, 3, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register 6", mr6, 6, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register 5", mr5, 5, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register 4", mr4, 4, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register 2, CWL={0:d}".format(cwl), mr2, 2,
             cmds["MODE_REGISTER"], 0),
            ("Load Mode Register 1", mr1, 1, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register 0, CL={0:d}, BL={1:d}".format(cl, bl), mr0, 0,
             cmds["MODE_REGISTER"], 200),
            ("ZQ Calibration", 0x0400, 0, "DFII_COMMAND_WE|DFII_COMMAND_CS",
             200),
        ]
    else:
        raise NotImplementedError("Unsupported memory type: " +
                                  phy_settings.memtype)

    return init_sequence, mr1
Ejemplo n.º 6
0
 def _get_bus_shift(self, bus_width):
     addr_shift = log2_int(self.dram_port_width // bus_width)
     bus_shift = log2_int(bus_width // 8)
     shift = addr_shift + bus_shift - self.address_align
     return shift
Ejemplo n.º 7
0
def _get_sdram_phy_sequence(sdram_phy_settings):
    nphases = sdram_phy_settings.nphases
    cl = sdram_phy_settings.cl

    consts = {}
    cmds = {
        "PRECHARGE_ALL": "DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
        "MODE_REGISTER":
        "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
        "AUTO_REFRESH": "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_CS",
        "UNRESET": "DFII_CONTROL_ODT|DFII_CONTROL_RESET_N",
        "CKE": "DFII_CONTROL_CKE|DFII_CONTROL_ODT|DFII_CONTROL_RESET_N"
    }

    if sdram_phy_settings.memtype == "SDR":
        bl = sdram_phy_settings.nphases
        mr = log2_int(bl) + (cl << 4)
        reset_dll = 1 << 8

        init_sequence = [
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(
                cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0,
             cmds["MODE_REGISTER"], 200)
        ]

    elif sdram_phy_settings.memtype == "DDR":
        bl = 2 * sdram_phy_settings.nphases
        mr = log2_int(bl) + (cl << 4)
        emr = 0
        reset_dll = 1 << 8

        init_sequence = [
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Load Extended Mode Register", emr, 1, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(
                cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0,
             cmds["MODE_REGISTER"], 200)
        ]

    elif sdram_phy_settings.memtype == "LPDDR":
        bl = 2 * sdram_phy_settings.nphases
        mr = log2_int(bl) + (cl << 4)
        emr = 0
        reset_dll = 1 << 8

        init_sequence = [
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Load Extended Mode Register", emr, 2, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(
                cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0,
             cmds["MODE_REGISTER"], 200)
        ]

    elif sdram_phy_settings.memtype == "DDR2":
        bl = 2 * sdram_phy_settings.nphases
        wr = 2
        mr = log2_int(bl) + (cl << 4) + (wr << 9)
        emr = 0
        emr2 = 0
        emr3 = 0
        reset_dll = 1 << 8
        ocd = 7 << 7

        init_sequence = [
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Load Extended Mode Register 3", emr3, 3, cmds["MODE_REGISTER"],
             0),
            ("Load Extended Mode Register 2", emr2, 2, cmds["MODE_REGISTER"],
             0),
            ("Load Extended Mode Register", emr, 1, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(
                cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0,
             cmds["MODE_REGISTER"], 200),
            ("Load Extended Mode Register / OCD Default", emr + ocd, 1,
             cmds["MODE_REGISTER"], 0),
            ("Load Extended Mode Register / OCD Exit", emr, 1,
             cmds["MODE_REGISTER"], 0),
        ]
    elif sdram_phy_settings.memtype == "DDR3":
        bl = 2 * sdram_phy_settings.nphases

        def format_mr0(bl, cl, wr, dll_reset):
            bl_to_mr0 = {4: 0b10, 8: 0b00}
            cl_to_mr0 = {
                5: 0b0010,
                6: 0b0100,
                7: 0b0110,
                8: 0b1000,
                9: 0b1010,
                10: 0b1100,
                11: 0b1110,
                12: 0b0001,
                13: 0b0011,
                14: 0b0101
            }
            wr_to_mr0 = {
                16: 0b000,
                5: 0b001,
                6: 0b010,
                7: 0b011,
                8: 0b100,
                10: 0b101,
                12: 0b110,
                14: 0b111
            }
            mr0 = bl_to_mr0[bl]
            mr0 |= (cl_to_mr0[cl] & 1) << 2
            mr0 |= ((cl_to_mr0[cl] >> 1) & 0b111) << 4
            mr0 |= dll_reset << 8
            mr0 |= wr_to_mr0[wr] << 9
            return mr0

        def format_mr1(output_drive_strength, rtt_nom):
            mr1 = ((output_drive_strength >> 0) & 1) << 1
            mr1 |= ((output_drive_strength >> 1) & 1) << 5
            mr1 |= ((rtt_nom >> 0) & 1) << 2
            mr1 |= ((rtt_nom >> 1) & 1) << 6
            mr1 |= ((rtt_nom >> 2) & 1) << 9
            return mr1

        def format_mr2(cwl, rtt_wr):
            mr2 = (cwl - 5) << 3
            mr2 |= rtt_wr << 9
            return mr2

        mr0 = format_mr0(bl, cl, 8,
                         1)  # wr=8 FIXME: this should be ceiling(tWR/tCK)
        mr1 = format_mr1(
            1, 1)  # Output Drive Strength RZQ/7 (34 ohm) / Rtt RZQ/4 (60 ohm)
        mr2 = format_mr2(sdram_phy_settings.cwl, 2)  # Rtt(WR) RZQ/4
        mr3 = 0

        init_sequence = [
            ("Release reset", 0x0000, 0, cmds["UNRESET"], 50000),
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 10000),
            ("Load Mode Register 2", mr2, 2, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register 3", mr3, 3, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register 1", mr1, 1, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register 0, CL={0:d}, BL={1:d}".format(cl, bl), mr0, 0,
             cmds["MODE_REGISTER"], 200),
            ("ZQ Calibration", 0x0400, 0, "DFII_COMMAND_WE|DFII_COMMAND_CS",
             200),
        ]

        # the value of MR1 needs to be modified during write leveling
        consts["DDR3_MR1"] = mr1
    else:
        raise NotImplementedError("Unsupported memory type: " +
                                  sdram_phy_settings.memtype)

    return {
        "nphases": sdram_phy_settings.nphases,
        "rdphase": sdram_phy_settings.rdphase,
        "wrphase": sdram_phy_settings.wrphase,
        "consts": consts,
        "init_sequence": init_sequence
    }
Ejemplo n.º 8
0
def get_sdram_phy_header(sdram_phy_settings):
    r = "#ifndef __GENERATED_SDRAM_PHY_H\n#define __GENERATED_SDRAM_PHY_H\n"
    r += "#include <hw/common.h>\n#include <generated/csr.h>\n#include <hw/flags.h>\n\n"

    nphases = sdram_phy_settings.nphases
    r += "#define DFII_NPHASES "+str(nphases)+"\n\n"

    r += "static void cdelay(int i);\n"

    # commands_px functions
    for n in range(nphases):
        r += """
static void command_p{n}(int cmd)
{{
    sdram_dfii_pi{n}_command_write(cmd);
    sdram_dfii_pi{n}_command_issue_write(1);
}}""".format(n=str(n))
    r += "\n\n"

    # rd/wr access macros
    r += """
#define sdram_dfii_pird_address_write(X) sdram_dfii_pi{rdphase}_address_write(X)
#define sdram_dfii_piwr_address_write(X) sdram_dfii_pi{wrphase}_address_write(X)

#define sdram_dfii_pird_baddress_write(X) sdram_dfii_pi{rdphase}_baddress_write(X)
#define sdram_dfii_piwr_baddress_write(X) sdram_dfii_pi{wrphase}_baddress_write(X)

#define command_prd(X) command_p{rdphase}(X)
#define command_pwr(X) command_p{wrphase}(X)
""".format(rdphase=str(sdram_phy_settings.rdphase), wrphase=str(sdram_phy_settings.wrphase))
    r += "\n"

    #
    # sdrrd/sdrwr functions utilities
    #
    r += "#define DFII_PIX_DATA_SIZE CSR_SDRAM_DFII_PI0_WRDATA_SIZE\n"
    sdram_dfii_pix_wrdata_addr = []
    for n in range(nphases):
        sdram_dfii_pix_wrdata_addr.append("CSR_SDRAM_DFII_PI{n}_WRDATA_ADDR".format(n=n))
    r += """
const unsigned int sdram_dfii_pix_wrdata_addr[{n}] = {{
    {sdram_dfii_pix_wrdata_addr}
}};
""".format(n=nphases, sdram_dfii_pix_wrdata_addr=",\n\t".join(sdram_dfii_pix_wrdata_addr))

    sdram_dfii_pix_rddata_addr = []
    for n in range(nphases):
        sdram_dfii_pix_rddata_addr.append("CSR_SDRAM_DFII_PI{n}_RDDATA_ADDR".format(n=n))
    r += """
const unsigned int sdram_dfii_pix_rddata_addr[{n}] = {{
    {sdram_dfii_pix_rddata_addr}
}};
""".format(n=nphases, sdram_dfii_pix_rddata_addr=",\n\t".join(sdram_dfii_pix_rddata_addr))
    r += "\n"

    # init sequence
    cmds = {
        "PRECHARGE_ALL": "DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
        "MODE_REGISTER": "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
        "AUTO_REFRESH":  "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_CS",
        "UNRESET":       "DFII_CONTROL_ODT|DFII_CONTROL_RESET_N",
        "CKE":           "DFII_CONTROL_CKE|DFII_CONTROL_ODT|DFII_CONTROL_RESET_N"
    }

    cl = sdram_phy_settings.cl

    if sdram_phy_settings.memtype == "SDR":
        bl = sdram_phy_settings.nphases
        mr = log2_int(bl) + (cl << 4)
        reset_dll = 1 << 8

        init_sequence = [
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
            ("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
        ]

    elif sdram_phy_settings.memtype == "DDR":
        bl = 2*sdram_phy_settings.nphases
        mr  = log2_int(bl) + (cl << 4)
        emr = 0
        reset_dll = 1 << 8

        init_sequence = [
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
            ("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Load Extended Mode Register", emr, 1, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
        ]

    elif sdram_phy_settings.memtype == "LPDDR":
        bl = 2*sdram_phy_settings.nphases
        mr  = log2_int(bl) + (cl << 4)
        emr = 0
        reset_dll = 1 << 8

        init_sequence = [
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
            ("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Load Extended Mode Register", emr, 2, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
        ]

    elif sdram_phy_settings.memtype == "DDR2":
        bl = 2*sdram_phy_settings.nphases
        wr = 2
        mr = log2_int(bl) + (cl << 4) + (wr << 9)
        emr = 0
        emr2 = 0
        emr3 = 0
        reset_dll = 1 << 8
        ocd = 7 << 7

        init_sequence = [
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
            ("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Load Extended Mode Register 3", emr3, 3, cmds["MODE_REGISTER"], 0),
            ("Load Extended Mode Register 2", emr2, 2, cmds["MODE_REGISTER"], 0),
            ("Load Extended Mode Register", emr, 1, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200),
            ("Load Extended Mode Register / OCD Default", emr+ocd, 1, cmds["MODE_REGISTER"], 0),
            ("Load Extended Mode Register / OCD Exit", emr, 1, cmds["MODE_REGISTER"], 0),
        ]
    elif sdram_phy_settings.memtype == "DDR3":
        bl = 2*sdram_phy_settings.nphases

        def format_mr0(bl, cl, wr, dll_reset):
            bl_to_mr0 = {
                4: 0b10,
                8: 0b00
            }
            cl_to_mr0 = {
                 5: 0b0010,
                 6: 0b0100,
                 7: 0b0110,
                 8: 0b1000,
                 9: 0b1010,
                10: 0b1100,
                11: 0b1110,
                12: 0b0001,
                13: 0b0011,
                14: 0b0101
            }
            wr_to_mr0 = {
                16: 0b000,
                 5: 0b001,
                 6: 0b010,
                 7: 0b011,
                 8: 0b100,
                10: 0b101,
                12: 0b110,
                14: 0b111
            }
            mr0 = bl_to_mr0[bl]
            mr0 |= (cl_to_mr0[cl] & 1) << 2
            mr0 |= ((cl_to_mr0[cl] >> 1) & 0b111) << 4
            mr0 |= dll_reset << 8
            mr0 |= wr_to_mr0[wr] << 9
            return mr0

        def format_mr1(output_drive_strength, rtt_nom):
            mr1 = ((output_drive_strength >> 0) & 1) << 1
            mr1 |= ((output_drive_strength >> 1) & 1) << 5
            mr1 |= ((rtt_nom >> 0) & 1) << 2
            mr1 |= ((rtt_nom >> 1) & 1) << 6
            mr1 |= ((rtt_nom >> 2) & 1) << 9
            return mr1

        def format_mr2(cwl, rtt_wr):
            mr2 = (cwl-5) << 3
            mr2 |= rtt_wr << 9
            return mr2

        mr0 = format_mr0(bl, cl, 8, 1)  # wr=8 FIXME: this should be ceiling(tWR/tCK)
        mr1 = format_mr1(1, 1)  # Output Drive Strength RZQ/7 (34 ohm) / Rtt RZQ/4 (60 ohm)
        mr2 = format_mr2(sdram_phy_settings.cwl, 2)  # Rtt(WR) RZQ/4
        mr3 = 0

        init_sequence = [
            ("Release reset", 0x0000, 0, cmds["UNRESET"], 50000),
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 10000),
            ("Load Mode Register 2", mr2, 2, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register 3", mr3, 3, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register 1", mr1, 1, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register 0, CL={0:d}, BL={1:d}".format(cl, bl), mr0, 0, cmds["MODE_REGISTER"], 200),
            ("ZQ Calibration", 0x0400, 0, "DFII_COMMAND_WE|DFII_COMMAND_CS", 200),
        ]

        # the value of MR1 needs to be modified during write leveling
        r += "#define DDR3_MR1 {}\n\n".format(mr1)
    else:
        raise NotImplementedError("Unsupported memory type: "+sdram_phy_settings.memtype)

    r += "static void init_sequence(void)\n{\n"
    for comment, a, ba, cmd, delay in init_sequence:
        r += "\t/* {0} */\n".format(comment)
        r += "\tsdram_dfii_pi0_address_write({0:#x});\n".format(a)
        r += "\tsdram_dfii_pi0_baddress_write({0:d});\n".format(ba)
        if cmd[:12] == "DFII_CONTROL":
            r += "\tsdram_dfii_control_write({0});\n".format(cmd)
        else:
            r += "\tcommand_p0({0});\n".format(cmd)
        if delay:
            r += "\tcdelay({0:d});\n".format(delay)
        r += "\n"
    r += "}\n"

    r += "#endif\n"

    return r
Ejemplo n.º 9
0
    def __init__(self, ddr_wr_port, ddr_rd_port, udp_port):
        SIZE = 1024 * 1024
        SIZE = 1024
        self.fifo_full = CSRStatus(reset=0)
        self.fifo_error = CSRStatus(reset=0)
        self.fifo_load = CSRStorage(
            reset=0)  # Load the coefficients in memory to the ROI Summer
        self.fifo_read = CSRStorage(reset=0)
        self.fifo_size = CSRStorage(32, reset=SIZE)
        self.dst_ip = CSRStorage(32, reset=convert_ip("192.168.1.114"))
        self.dst_port = CSRStorage(16, reset=7778)

        dw = 64
        print(
            f"Write port: A ({ddr_wr_port.address_width})/ D ({ddr_wr_port.data_width})"
        )
        print(
            f"Read port: A ({ddr_rd_port.address_width})/ D ({ddr_rd_port.data_width})"
        )
        self.submodules.dram_fifo = dram_fifo = LiteDRAMFIFO(
            data_width=dw,
            base=0,
            depth=SIZE,
            write_port=ddr_wr_port,
            read_port=ddr_rd_port,
            with_bypass=True,
        )
        # self.mf = mf = Signal(reset=0)  # mf == More Fragments
        # self.fragment_offset = fragment_offset = Signal(13, reset=0)
        # self.identification = identification = Signal(16, reset=0)

        self.submodules.adcs = adcs = ADCStream(1, dw)
        self.fifo_counter = fifo_counter = Signal(24)
        self.load_fifo = load_fifo = Signal()

        # adc --> buffer_fifo
        self.submodules.buffer_fifo = buffer_fifo = stream.SyncFIFO(
            stream.EndpointDescription([("data", dw)]), 256, buffered=True)
        # buffer_fifo --> dram_fifo
        fifo_size = Signal(32)
        self.sync += [
            fifo_size.eq(self.fifo_size.storage),
            If(self.fifo_load.re & self.fifo_load.storage, fifo_counter.eq(0),
               load_fifo.eq(1)),
            If(load_fifo & adcs.source.valid, self.fifo_full.status.eq(0),
               self.fifo_error.status.eq(~dram_fifo.dram_fifo.ctrl.writable),
               fifo_counter.eq(fifo_counter + 1)),
            If((fifo_counter == fifo_size - 1) & adcs.source.valid,
               load_fifo.eq(0), self.fifo_full.status.eq(1)),
        ]

        self.comb += [
            buffer_fifo.sink.data.eq(adcs.source.data),
            buffer_fifo.sink.valid.eq(adcs.source.valid & load_fifo),
            buffer_fifo.source.connect(dram_fifo.sink),
        ]

        # fifo --> stride converter
        self.submodules.stride_converter = sc = stream.Converter(
            dw, udp_port.dw)

        self.read_from_dram_fifo = read_from_dram_fifo = Signal()
        self.comb += [dram_fifo.source.connect(sc.sink)]
        self.receive_count = receive_count = Signal(24)
        self.sync += [
            If(dram_fifo.source.valid & dram_fifo.source.ready,
               receive_count.eq(receive_count + 1)).Elif(
                   read_from_dram_fifo == 0, receive_count.eq(0))
        ]
        # --> udp fragmenter -->
        self.submodules.udp_fragmenter = udp_fragmenter = UDPFragmenter(
            udp_port.dw)

        self.sync += read_from_dram_fifo.eq(self.fifo_read.storage)
        self.comb += If(
            read_from_dram_fifo,
            # TODO: There is a bug somewhere in the converter,
            # its source.last somehow gets set, no idea why. That signal is of no real use
            # for the fragmenter anyways, so we live without it
            sc.source.connect(udp_fragmenter.sink, omit={'total_size',
                                                         'last'}))

        # TODO: 8 should be adcstream data width // 8
        self.comb += udp_fragmenter.sink.length.eq(fifo_size << log2_int(dw //
                                                                         8))
        self.comb += udp_fragmenter.source.connect(udp_port.sink)
        self.comb += [
            # param
            udp_port.sink.src_port.eq(4321),
            udp_port.sink.dst_port.eq(self.dst_port.storage),
            udp_port.sink.ip_address.eq(self.dst_ip.storage),
            # udp_port.sink.ip_address.eq(convert_ip("192.168.88.101")),
            # payload
            udp_port.sink.error.eq(0)
        ]

        # debug
        self.first_sample, self.last_sample = Signal(16), Signal(16)
        self.sync += [
            If(fifo_counter == 1, self.first_sample.eq(adcs.source.data[:16])),
            If(fifo_counter == SIZE - 2,
               self.last_sample.eq(adcs.source.data[:16])),
        ]
Ejemplo n.º 10
0
    def __init__(self, ddr_wr_port, ddr_rd_port, udp_port, adc_source, adc_dw):
        SIZE = 1024 * 1024
        self.fifo_full = CSRStatus(reset=0)
        self.fifo_error = CSRStatus(reset=0)
        self.fifo_load = CSRStorage(reset=0)
        self.fifo_read = CSRStorage(reset=0)
        self.fifo_size = CSRStorage(32, reset=SIZE)
        self.dst_ip = CSRStorage(32, reset=convert_ip("192.168.1.114"))
        self.dst_port = CSRStorage(16, reset=7778)

        self.fifo_counter = fifo_counter = Signal(24)
        self.load_fifo = load_fifo = Signal()

        dw = ddr_wr_port.data_width

        print(
            f"Write port: A ({ddr_wr_port.address_width})/ D ({ddr_wr_port.data_width})"
        )
        print(
            f"Read port: A ({ddr_rd_port.address_width})/ D ({ddr_rd_port.data_width})"
        )
        print(f"dw: {dw}; adc_dw: {adc_dw}")
        self.submodules.dram_fifo = dram_fifo = LiteDRAMFIFO(
            data_width=dw,
            base=0,
            depth=SIZE * (dw // 8),  # liteDRAM expects this in bytes
            write_port=ddr_wr_port,
            read_port=ddr_rd_port,
        )

        self.adc_data = adc_data = Signal(dw)
        DW_RATIO = dw // adc_dw
        log_dw_ratio = log2_int(DW_RATIO)
        word_count = Signal(log_dw_ratio)
        word_count_d = Signal(log_dw_ratio)

        self.sync += [
            If(adc_source.valid,
               adc_data.eq(Cat(adc_data[adc_dw:], adc_source.data)),
               word_count.eq(word_count + 1)),
            word_count_d.eq(word_count),
        ]

        self.comb += [
            dram_fifo.sink.valid.eq((word_count == 0) & (word_count_d != 0)
                                    & load_fifo),
            dram_fifo.sink.data.eq(adc_data)
        ]

        fifo_size = Signal(32)
        self.sync += [
            fifo_size.eq(self.fifo_size.storage),
            If(self.fifo_load.re & self.fifo_load.storage, fifo_counter.eq(0),
               load_fifo.eq(1)),
            If(load_fifo & adc_source.valid, self.fifo_full.status.eq(0),
               self.fifo_error.status.eq(~dram_fifo.dram_fifo.ctrl.writable),
               fifo_counter.eq(fifo_counter + 1)),
            If((fifo_counter == fifo_size - 1) & adc_source.valid,
               load_fifo.eq(0), self.fifo_full.status.eq(1)),
        ]

        # fifo --> stride converter
        self.submodules.stride_converter = sc = stream.Converter(
            dw, udp_port.dw)

        self.read_from_dram_fifo = read_from_dram_fifo = Signal()
        self.comb += [dram_fifo.source.connect(sc.sink)]
        self.receive_count = receive_count = Signal(24)
        self.sync += [
            If(dram_fifo.source.valid & dram_fifo.source.ready,
               receive_count.eq(receive_count + 1)).Elif(
                   read_from_dram_fifo == 0, receive_count.eq(0))
        ]
        # --> udp fragmenter -->
        self.submodules.udp_fragmenter = udp_fragmenter = UDPFragmenter(
            udp_port.dw)

        self.sync += read_from_dram_fifo.eq(self.fifo_read.storage)
        self.comb += If(
            read_from_dram_fifo,
            # TODO: There is a bug somewhere in the converter,
            # its source.last somehow gets set, no idea why. That signal is of no real use
            # for the fragmenter anyways, so we live without it
            sc.source.connect(udp_fragmenter.sink, omit={'total_size',
                                                         'last'}))

        # TODO: 8 should be adcstream data width // 8
        self.comb += udp_fragmenter.sink.length.eq(
            fifo_size << log2_int(adc_dw // 8))
        self.comb += udp_fragmenter.source.connect(udp_port.sink)
        self.comb += [
            # param
            udp_port.sink.src_port.eq(4321),
            udp_port.sink.dst_port.eq(self.dst_port.storage),
            udp_port.sink.ip_address.eq(self.dst_ip.storage),
            # udp_port.sink.ip_address.eq(convert_ip("192.168.88.101")),
            # payload
            udp_port.sink.error.eq(0)
        ]
Ejemplo n.º 11
0
def _get_sdram_phy_sequence(sdram_phy_settings):
    nphases = sdram_phy_settings.nphases
    cl = sdram_phy_settings.cl

    consts = {}
    cmds = {
        "PRECHARGE_ALL": "DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
        "MODE_REGISTER": "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
        "AUTO_REFRESH":  "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_CS",
        "UNRESET":       "DFII_CONTROL_ODT|DFII_CONTROL_RESET_N",
        "CKE":           "DFII_CONTROL_CKE|DFII_CONTROL_ODT|DFII_CONTROL_RESET_N"
    }

    if sdram_phy_settings.memtype == "SDR":
        bl = sdram_phy_settings.nphases
        mr = log2_int(bl) + (cl << 4)
        reset_dll = 1 << 8

        init_sequence = [
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
            ("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl),
             mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl),
             mr, 0, cmds["MODE_REGISTER"], 200)
        ]

    elif sdram_phy_settings.memtype == "DDR":
        bl = 2*sdram_phy_settings.nphases
        mr  = log2_int(bl) + (cl << 4)
        emr = 0
        reset_dll = 1 << 8

        init_sequence = [
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
            ("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Load Extended Mode Register", emr, 1, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl),
             mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl),
             mr, 0, cmds["MODE_REGISTER"], 200)
        ]

    elif sdram_phy_settings.memtype == "LPDDR":
        bl = 2*sdram_phy_settings.nphases
        mr  = log2_int(bl) + (cl << 4)
        emr = 0
        reset_dll = 1 << 8

        init_sequence = [
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
            ("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Load Extended Mode Register", emr, 2, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl),
             mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl),
             mr, 0, cmds["MODE_REGISTER"], 200)
        ]

    elif sdram_phy_settings.memtype == "DDR2":
        bl = 2*sdram_phy_settings.nphases
        wr = 2
        mr = log2_int(bl) + (cl << 4) + (wr << 9)
        emr = 0
        emr2 = 0
        emr3 = 0
        reset_dll = 1 << 8
        ocd = 7 << 7

        init_sequence = [
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
            ("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Load Extended Mode Register 3", emr3, 3, cmds["MODE_REGISTER"], 0),
            ("Load Extended Mode Register 2", emr2, 2, cmds["MODE_REGISTER"], 0),
            ("Load Extended Mode Register", emr, 1, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl),
             mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl),
             mr, 0, cmds["MODE_REGISTER"], 200),
            ("Load Extended Mode Register / OCD Default", emr+ocd, 1, cmds["MODE_REGISTER"], 0),
            ("Load Extended Mode Register / OCD Exit", emr, 1, cmds["MODE_REGISTER"], 0),
        ]
    elif sdram_phy_settings.memtype == "DDR3":
        bl = 2*sdram_phy_settings.nphases

        def format_mr0(bl, cl, wr, dll_reset):
            bl_to_mr0 = {
                4: 0b10,
                8: 0b00
            }
            cl_to_mr0 = {
                 5: 0b0010,
                 6: 0b0100,
                 7: 0b0110,
                 8: 0b1000,
                 9: 0b1010,
                10: 0b1100,
                11: 0b1110,
                12: 0b0001,
                13: 0b0011,
                14: 0b0101
            }
            wr_to_mr0 = {
                16: 0b000,
                 5: 0b001,
                 6: 0b010,
                 7: 0b011,
                 8: 0b100,
                10: 0b101,
                12: 0b110,
                14: 0b111
            }
            mr0 = bl_to_mr0[bl]
            mr0 |= (cl_to_mr0[cl] & 1) << 2
            mr0 |= ((cl_to_mr0[cl] >> 1) & 0b111) << 4
            mr0 |= dll_reset << 8
            mr0 |= wr_to_mr0[wr] << 9
            return mr0

        def format_mr1(output_drive_strength, rtt_nom):
            mr1 = ((output_drive_strength >> 0) & 1) << 1
            mr1 |= ((output_drive_strength >> 1) & 1) << 5
            mr1 |= ((rtt_nom >> 0) & 1) << 2
            mr1 |= ((rtt_nom >> 1) & 1) << 6
            mr1 |= ((rtt_nom >> 2) & 1) << 9
            return mr1

        def format_mr2(cwl, rtt_wr):
            mr2 = (cwl-5) << 3
            mr2 |= rtt_wr << 9
            return mr2

        mr0 = format_mr0(bl, cl, 8, 1)  # wr=8 FIXME: this should be ceiling(tWR/tCK)
        mr1 = format_mr1(1, 1)  # Output Drive Strength RZQ/7 (34 ohm) / Rtt RZQ/4 (60 ohm)
        mr2 = format_mr2(sdram_phy_settings.cwl, 2)  # Rtt(WR) RZQ/4
        mr3 = 0

        init_sequence = [
            ("Release reset", 0x0000, 0, cmds["UNRESET"], 50000),
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 10000),
            ("Load Mode Register 2", mr2, 2, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register 3", mr3, 3, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register 1", mr1, 1, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register 0, CL={0:d}, BL={1:d}".format(cl, bl),
             mr0, 0, cmds["MODE_REGISTER"], 200),
            ("ZQ Calibration", 0x0400, 0, "DFII_COMMAND_WE|DFII_COMMAND_CS", 200),
        ]

        # the value of MR1 needs to be modified during write leveling
        consts["DDR3_MR1"] = mr1
    else:
        raise NotImplementedError("Unsupported memory type: "+sdram_phy_settings.memtype)

    return {
        "nphases": sdram_phy_settings.nphases,
        "rdphase": sdram_phy_settings.rdphase,
        "wrphase": sdram_phy_settings.wrphase,
        "consts": consts,
        "init_sequence": init_sequence
    }
Ejemplo n.º 12
0
def get_sdram_phy_header(sdram_phy_settings):
    r = "#ifndef __GENERATED_SDRAM_PHY_H\n#define __GENERATED_SDRAM_PHY_H\n"
    r += "#include <hw/common.h>\n#include <generated/csr.h>\n#include <hw/flags.h>\n\n"

    nphases = sdram_phy_settings.nphases
    r += "#define DFII_NPHASES "+str(nphases)+"\n\n"

    r += "static void cdelay(int i);\n"

    # commands_px functions
    for n in range(nphases):
        r += """
static void command_p{n}(int cmd)
{{
    dfii_pi{n}_command_write(cmd);
    dfii_pi{n}_command_issue_write(1);
}}""".format(n=str(n))
    r += "\n\n"

    # rd/wr access macros
    r += """
#define dfii_pird_address_write(X) dfii_pi{rdphase}_address_write(X)
#define dfii_piwr_address_write(X) dfii_pi{wrphase}_address_write(X)

#define dfii_pird_baddress_write(X) dfii_pi{rdphase}_baddress_write(X)
#define dfii_piwr_baddress_write(X) dfii_pi{wrphase}_baddress_write(X)

#define command_prd(X) command_p{rdphase}(X)
#define command_pwr(X) command_p{wrphase}(X)
""".format(rdphase=str(sdram_phy_settings.rdphase), wrphase=str(sdram_phy_settings.wrphase))
    r += "\n"

    #
    # sdrrd/sdrwr functions utilities
    #
    r += "#define DFII_PIX_DATA_SIZE CSR_DFII_PI0_WRDATA_SIZE\n"
    dfii_pix_wrdata_addr = []
    for n in range(nphases):
        dfii_pix_wrdata_addr.append("CSR_DFII_PI{n}_WRDATA_ADDR".format(n=n))
    r += """
const unsigned int dfii_pix_wrdata_addr[{n}] = {{
    {dfii_pix_wrdata_addr}
}};
""".format(n=nphases, dfii_pix_wrdata_addr=",\n\t".join(dfii_pix_wrdata_addr))

    dfii_pix_rddata_addr = []
    for n in range(nphases):
        dfii_pix_rddata_addr.append("CSR_DFII_PI{n}_RDDATA_ADDR".format(n=n))
    r += """
const unsigned int dfii_pix_rddata_addr[{n}] = {{
    {dfii_pix_rddata_addr}
}};
""".format(n=nphases, dfii_pix_rddata_addr=",\n\t".join(dfii_pix_rddata_addr))
    r += "\n"

    # init sequence
    cmds = {
        "PRECHARGE_ALL": "DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
        "MODE_REGISTER": "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
        "AUTO_REFRESH":  "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_CS",
        "UNRESET":       "DFII_CONTROL_ODT|DFII_CONTROL_RESET_N",
        "CKE":           "DFII_CONTROL_CKE|DFII_CONTROL_ODT|DFII_CONTROL_RESET_N"
    }

    cl = sdram_phy_settings.cl

    if sdram_phy_settings.memtype == "SDR":
        bl = sdram_phy_settings.nphases
        mr = log2_int(bl) + (cl << 4)
        reset_dll = 1 << 8

        init_sequence = [
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
            ("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
        ]

    elif sdram_phy_settings.memtype == "DDR":
        bl = 2*sdram_phy_settings.nphases
        mr  = log2_int(bl) + (cl << 4)
        emr = 0
        reset_dll = 1 << 8

        init_sequence = [
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
            ("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Load Extended Mode Register", emr, 1, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
        ]

    elif sdram_phy_settings.memtype == "LPDDR":
        bl = 2*sdram_phy_settings.nphases
        mr  = log2_int(bl) + (cl << 4)
        emr = 0
        reset_dll = 1 << 8

        init_sequence = [
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
            ("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Load Extended Mode Register", emr, 2, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
        ]

    elif sdram_phy_settings.memtype == "DDR2":
        bl = 2*sdram_phy_settings.nphases
        wr = 2
        mr = log2_int(bl) + (cl << 4) + (wr << 9)
        emr = 0
        emr2 = 0
        emr3 = 0
        reset_dll = 1 << 8
        ocd = 7 << 7

        init_sequence = [
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
            ("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Load Extended Mode Register 3", emr3, 3, cmds["MODE_REGISTER"], 0),
            ("Load Extended Mode Register 2", emr2, 2, cmds["MODE_REGISTER"], 0),
            ("Load Extended Mode Register", emr, 1, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
            ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
            ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200),
            ("Load Extended Mode Register / OCD Default", emr+ocd, 1, cmds["MODE_REGISTER"], 0),
            ("Load Extended Mode Register / OCD Exit", emr, 1, cmds["MODE_REGISTER"], 0),
        ]
    elif sdram_phy_settings.memtype == "DDR3":
        bl = 2*sdram_phy_settings.nphases

        def format_mr0(bl, cl, wr, dll_reset):
            bl_to_mr0 = {
                4: 0b10,
                8: 0b00
            }
            cl_to_mr0 = {
                 5: 0b0010,
                 6: 0b0100,
                 7: 0b0110,
                 8: 0b1000,
                 9: 0b1010,
                10: 0b1100,
                11: 0b1110,
                12: 0b0001,
                13: 0b0011,
                14: 0b0101
            }
            wr_to_mr0 = {
                16: 0b000,
                 5: 0b001,
                 6: 0b010,
                 7: 0b011,
                 8: 0b100,
                10: 0b101,
                12: 0b110,
                14: 0b111
            }
            mr0 = bl_to_mr0[bl]
            mr0 |= (cl_to_mr0[cl] & 1) << 2
            mr0 |= ((cl_to_mr0[cl] >> 1) & 0b111) << 4
            mr0 |= dll_reset << 8
            mr0 |= wr_to_mr0[wr] << 9
            return mr0

        def format_mr1(output_drive_strength, rtt_nom):
            mr1 = ((output_drive_strength >> 0) & 1) << 1
            mr1 |= ((output_drive_strength >> 1) & 1) << 5
            mr1 |= ((rtt_nom >> 0) & 1) << 2
            mr1 |= ((rtt_nom >> 1) & 1) << 6
            mr1 |= ((rtt_nom >> 2) & 1) << 9
            return mr1

        def format_mr2(cwl, rtt_wr):
            mr2 = (cwl-5) << 3
            mr2 |= rtt_wr << 9
            return mr2

        mr0 = format_mr0(bl, cl, 8, 1)  # wr=8 FIXME: this should be ceiling(tWR/tCK)
        mr1 = format_mr1(1, 1)  # Output Drive Strength RZQ/7 (34 ohm) / Rtt RZQ/4 (60 ohm)
        mr2 = format_mr2(sdram_phy_settings.cwl, 2)  # Rtt(WR) RZQ/4
        mr3 = 0

        init_sequence = [
            ("Release reset", 0x0000, 0, cmds["UNRESET"], 50000),
            ("Bring CKE high", 0x0000, 0, cmds["CKE"], 10000),
            ("Load Mode Register 2", mr2, 2, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register 3", mr3, 3, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register 1", mr1, 1, cmds["MODE_REGISTER"], 0),
            ("Load Mode Register 0, CL={0:d}, BL={1:d}".format(cl, bl), mr0, 0, cmds["MODE_REGISTER"], 200),
            ("ZQ Calibration", 0x0400, 0, "DFII_COMMAND_WE|DFII_COMMAND_CS", 200),
        ]

        # the value of MR1 needs to be modified during write leveling
        r += "#define DDR3_MR1 {}\n\n".format(mr1)
    else:
        raise NotImplementedError("Unsupported memory type: "+sdram_phy_settings.memtype)

    r += "static void init_sequence(void)\n{\n"
    for comment, a, ba, cmd, delay in init_sequence:
        r += "\t/* {0} */\n".format(comment)
        r += "\tdfii_pi0_address_write({0:#x});\n".format(a)
        r += "\tdfii_pi0_baddress_write({0:d});\n".format(ba)
        if cmd[:12] == "DFII_CONTROL":
            r += "\tdfii_control_write({0});\n".format(cmd)
        else:
            r += "\tcommand_p0({0});\n".format(cmd)
        if delay:
            r += "\tcdelay({0:d});\n".format(delay)
        r += "\n"
    r += "}\n"

    r += "#endif\n"

    return r