From 91a1520655405f821c7b3552d5d98da008747b3c Mon Sep 17 00:00:00 2001 From: Antti Lukats Date: Tue, 10 Sep 2019 11:25:57 +0200 Subject: [PATCH] add initial Trenz Cyclone 10 LP RefKit support with SDRAM/HyperRAM/Ethernet --- litex_boards/partner/platforms/c10lprefkit.py | 125 ++++++++++++++ litex_boards/partner/targets/c10lprefkit.py | 155 ++++++++++++++++++ 2 files changed, 280 insertions(+) create mode 100644 litex_boards/partner/platforms/c10lprefkit.py create mode 100755 litex_boards/partner/targets/c10lprefkit.py diff --git a/litex_boards/partner/platforms/c10lprefkit.py b/litex_boards/partner/platforms/c10lprefkit.py new file mode 100644 index 0000000..20c8102 --- /dev/null +++ b/litex_boards/partner/platforms/c10lprefkit.py @@ -0,0 +1,125 @@ +# This file is Copyright (c) 2019 Antti Lukats +# This file is Copyright (c) 2019 Florent Kermarrec +# License: BSD + +from litex.build.generic_platform import * +from litex.build.altera import AlteraPlatform +from litex.build.altera.programmer import USBBlaster + +# IOs ---------------------------------------------------------------------------------------------- + +_io = [ + ("clk12", 0, Pins("G21"), IOStandard("3.3-V LVTTL")), + ("clk25", 0, Pins("AA12"), IOStandard("3.3-V LVTTL")), + + ("user_led", 0, Pins("C18"), IOStandard("3.3-V LVTTL")), + ("user_led", 1, Pins("D19"), IOStandard("3.3-V LVTTL")), + ("user_led", 2, Pins("C19"), IOStandard("3.3-V LVTTL")), + ("user_led", 3, Pins("C17"), IOStandard("3.3-V LVTTL")), + ("user_led", 4, Pins("D18"), IOStandard("3.3-V LVTTL")), + + + ("cpu_reset", 0, Pins("V15"), IOStandard("3.3-V LVTTL")), + + ("sw", 0, Pins("U10"), IOStandard("3.3-V LVTTL")), + ("sw", 1, Pins("U11"), IOStandard("3.3-V LVTTL")), + ("sw", 2, Pins("V11"), IOStandard("3.3-V LVTTL")), + ("sw", 3, Pins("T10"), IOStandard("3.3-V LVTTL")), + ("sw", 4, Pins("T11"), IOStandard("3.3-V LVTTL")), + + ("serial", 0, + Subsignal("tx", Pins("B21"), IOStandard("3.3-V LVTTL")), + Subsignal("rx", Pins("C20"), IOStandard("3.3-V LVTTL")), + ), + + ("sdram_clock", 0, Pins("AA3"), IOStandard("3.3-V LVTTL")), + ("sdram", 0, + Subsignal("a", Pins( + "V5 Y3 W6 Y4 AB5 AB6 AA6 AA7", + "AB7 AA5 V6 AA8 AB8")), + Subsignal("ba", Pins("Y6 V7")), + Subsignal("cs_n", Pins("W7")), + Subsignal("cke", Pins("AA4")), + Subsignal("ras_n", Pins("V8")), + Subsignal("cas_n", Pins("Y7")), + Subsignal("we_n", Pins("W8")), + Subsignal("dq", Pins( + "AB16 Y17 AA16 AA19 AB18 AA20 AB19 AB20", + "Y13 Y15 AA13 AB15 AB13 AA15 AA14 AB14")), + Subsignal("dm", Pins("Y14 W13")), + IOStandard("3.3-V LVTTL") + ), + + ("epcs", 0, + Subsignal("data0", Pins("K1")), + Subsignal("dclk", Pins("K2")), + Subsignal("ncs0", Pins("E2")), + Subsignal("asd0", Pins("D1")), + IOStandard("3.3-V LVTTL") + ), + + ("hyperram", 0, + Subsignal("clk", Pins("T16")), + Subsignal("rst_n", Pins("U12")), + Subsignal("dq", Pins("T15 W17 U14 R15 R14 V16 U16 U17")), + Subsignal("cs_n", Pins("V13")), + Subsignal("rwds", Pins("U13")), + IOStandard("3.3-V LVTTL") + ), + + ("gpio_leds", 0, + Pins("AB10 AA10 AA9 Y10 W10 U9 U8 U7"), + IOStandard("3.3-V LVTTL") + ), + + ("eth_clocks", 0, + Subsignal("tx", Pins("U21")), + Subsignal("rx", Pins("V22")), + IOStandard("3.3-V LVTTL"), + ), + ("eth", 0, + Subsignal("rst_n", Pins("R19")), + Subsignal("mdio", Pins("AA21")), + Subsignal("mdc", Pins("AA22")), + Subsignal("rx_dv", Pins("W21")), + Subsignal("rx_er", Pins("V21")), + Subsignal("rx_data", Pins("W22 W20 Y21 Y22")), + Subsignal("tx_en", Pins("T18")), + Subsignal("tx_data", Pins("T17 U20 U19 T20")), + Subsignal("col", Pins("T19")), + Subsignal("crs", Pins("R20")), + IOStandard("3.3-V LVTTL"), + ), + + ("eth_clocks", 1, + Subsignal("tx", Pins("N16")), + Subsignal("rx", Pins("V22")), + IOStandard("3.3-V LVTTL"), + ), + ("eth", 1, + Subsignal("rst_n", Pins("M21")), + Subsignal("mdio", Pins("N20")), + Subsignal("mdc", Pins("N18")), + Subsignal("rx_dv", Pins("R18")), + Subsignal("rx_er", Pins("P17")), + Subsignal("rx_data", Pins("M20 M19 M16 N19")), + Subsignal("tx_en", Pins("R22")), + Subsignal("tx_data", Pins("R21 N21 M22 N22")), + Subsignal("col", Pins("P21")), + Subsignal("crs", Pins("P22")), + IOStandard("3.3-V LVTTL"), + ), +] + +# Platform ----------------------------------------------------------------------------------------- + +class Platform(AlteraPlatform): + default_clk_name = "clk12" + default_clk_period = 1e9/12e6 + + def __init__(self): + AlteraPlatform.__init__(self, "10CL055YU484A7G", _io) + self.add_platform_command("set_global_assignment -name FAMILY \"Cyclone 10 LP\"") + + def create_programmer(self): + return USBBlaster() diff --git a/litex_boards/partner/targets/c10lprefkit.py b/litex_boards/partner/targets/c10lprefkit.py new file mode 100755 index 0000000..3b95fa8 --- /dev/null +++ b/litex_boards/partner/targets/c10lprefkit.py @@ -0,0 +1,155 @@ +#!/usr/bin/env python3 + +# This file is Copyright (c) 2019 Antti Lukats +# This file is Copyright (c) 2019 msloniewski +# This file is Copyright (c) 2019 Florent Kermarrec +# License: BSD + +import argparse + +from migen import * + +from litex_boards.platforms import c10lprefkit + +from litex.soc.integration.soc_core import * +from litex.soc.integration.soc_sdram import * +from litex.soc.integration.builder import * + +from litedram.modules import MT48LC16M16 +from litedram.phy import GENSDRPHY + +from liteeth.phy.mii import LiteEthPHYMII +from liteeth.mac import LiteEthMAC + +from litex.soc.cores.hyperbus import HyperRAM + +# CRG ---------------------------------------------------------------------------------------------- +class _CRG(Module): + def __init__(self, platform): + self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_sys_ps = ClockDomain() + self.clock_domains.cd_por = ClockDomain(reset_less=True) + + # # # + + self.cd_sys.clk.attr.add("keep") + self.cd_sys_ps.clk.attr.add("keep") + self.cd_por.clk.attr.add("keep") + + clk12 = platform.request("clk12") + + # power on rst + rst_n = Signal() + self.sync.por += rst_n.eq(platform.request("cpu_reset")) + self.comb += [ + self.cd_por.clk.eq(clk12), + self.cd_sys.rst.eq(~rst_n), + self.cd_sys_ps.rst.eq(~rst_n) + ] + + # sys clk / sdram clk + clk_outs = Signal(5) + self.specials += \ + Instance("ALTPLL", + p_BANDWIDTH_TYPE="AUTO", + p_CLK0_DIVIDE_BY=6, + p_CLK0_DUTY_CYCLE=50, + p_CLK0_MULTIPLY_BY=25, + p_CLK0_PHASE_SHIFT="0", + p_CLK1_DIVIDE_BY=6, + p_CLK1_DUTY_CYCLE=50, + p_CLK1_MULTIPLY_BY=25, + p_CLK1_PHASE_SHIFT="-10000", + p_COMPENSATE_CLOCK="CLK0", + p_INCLK0_INPUT_FREQUENCY=83000, + p_INTENDED_DEVICE_FAMILY="MAX 10", + p_LPM_TYPE="altpll", + p_OPERATION_MODE="NORMAL", + i_INCLK=clk12, + o_CLK=clk_outs, + i_ARESET=0, + i_CLKENA=0x3f, + i_EXTCLKENA=0xf, + i_FBIN=1, + i_PFDENA=1, + i_PLLENA=1, + ) + self.comb += self.cd_sys.clk.eq(clk_outs[0]) + self.comb += self.cd_sys_ps.clk.eq(clk_outs[1]) + self.comb += platform.request("sdram_clock").eq(self.cd_sys_ps.clk) + +# BaseSoC ------------------------------------------------------------------------------------------ + +class BaseSoC(SoCSDRAM): + mem_map = { + "hyperram": 0x20000000, + } + mem_map.update(SoCCore.mem_map) + + + def __init__(self, sys_clk_freq=int(50e6), **kwargs): + assert sys_clk_freq == int(50e6) + platform = c10lprefkit.Platform() + SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq, + integrated_rom_size=0x8000, + **kwargs) + + self.submodules.crg = _CRG(platform) + + self.submodules.hyperram = HyperRAM(platform.request("hyperram")) + self.add_wb_slave(mem_decoder(self.mem_map["hyperram"]), self.hyperram.bus) + self.add_memory_region("hyperram", self.mem_map["hyperram"], 8*1024*1024) + + if not self.integrated_main_ram_size: + self.submodules.sdrphy = GENSDRPHY(platform.request("sdram")) + sdram_module = MT48LC16M16(self.clk_freq, "1:1") + self.register_sdram(self.sdrphy, + sdram_module.geom_settings, + sdram_module.timing_settings) + + +class EthernetSoC(BaseSoC): + mem_map = { + "ethmac": 0x30000000, # (shadow @0xb0000000) + } + mem_map.update(BaseSoC.mem_map) + + def __init__(self, eth_port=0, **kwargs): + BaseSoC.__init__(self, **kwargs) + + self.submodules.ethphy = LiteEthPHYMII(self.platform.request("eth_clocks", eth_port), + self.platform.request("eth", eth_port)) + self.add_csr("ethphy") + 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"] | self.shadow_base, 0x2000) + self.add_csr("ethmac") + self.add_interrupt("ethmac") + + self.platform.add_period_constraint(self.platform.lookup_request("eth_clocks").tx, 1e9/12.5e6) + self.platform.add_period_constraint(self.platform.lookup_request("eth_clocks").rx, 1e9/12.5e6) + self.platform.add_false_path_constraints( + self.platform.lookup_request("clk12"), + self.platform.lookup_request("eth_clocks").tx, + self.platform.lookup_request("eth_clocks").rx + ) + +# Build -------------------------------------------------------------------------------------------- + +def main(): + parser = argparse.ArgumentParser(description="LiteX SoC on C10 LP RefKit") + builder_args(parser) + soc_sdram_args(parser) + parser.add_argument("--with-ethernet", action="store_true", + help="enable Ethernet support") + args = parser.parse_args() + + cls = EthernetSoC if args.with_ethernet else BaseSoC + soc = cls(**soc_sdram_argdict(args)) + builder = Builder(soc, **builder_argdict(args)) + builder.build() + + +if __name__ == "__main__": + main()