From 3df677cfeb21f9a07aca425abe74db71d502aa56 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Thu, 21 Sep 2023 09:19:57 +0200 Subject: [PATCH] Add initial Analog Pocket platform/target with Clk/SDRAM, able to run a simple SoC with SDRAM over JTAG-UART. $ ./analog_pocket.py --uart-name=jtag_uart --build --load $ litex_term jtag --jtag-config=openocd_usb_blaster.cfg __ _ __ _ __ / / (_) /____ | |/_/ / /__/ / __/ -_)> < /____/_/\__/\__/_/|_| Build your hardware, easily! (c) Copyright 2012-2023 Enjoy-Digital (c) Copyright 2007-2015 M-Labs BIOS built on Sep 21 2023 08:53:57 BIOS CRC passed (1e2b3f44) LiteX git sha1: 7d738737 --=============== SoC ==================-- CPU: VexRiscv @ 50MHz BUS: WISHBONE 32-bit @ 4GiB CSR: 32-bit data ROM: 128.0KiB SRAM: 8.0KiB L2: 8.0KiB SDRAM: 64.0MiB 16-bit @ 50MT/s (CL-2 CWL-2) MAIN-RAM: 64.0MiB --========== Initialization ============-- Initializing SDRAM @0x40000000... Switching SDRAM to software control. Switching SDRAM to hardware control. Memtest at 0x40000000 (2.0MiB)... Write: 0x40000000-0x40200000 2.0MiB Read: 0x40000000-0x40200000 2.0MiB Memtest OK Memspeed at 0x40000000 (Sequential, 2.0MiB)... Write speed: 15.6MiB/s Read speed: 22.1MiB/s --============== Boot ==================-- Booting from serial... Press Q or ESC to abort boot completely. sL5DdSMmkekro Timeout No boot medium found --============= Console ================-- litex> --- litex_boards/platforms/analog_pocket.py | 213 ++++++++++++++++++++++++ litex_boards/targets/analog_pocket.py | 94 +++++++++++ 2 files changed, 307 insertions(+) create mode 100644 litex_boards/platforms/analog_pocket.py create mode 100644 litex_boards/targets/analog_pocket.py diff --git a/litex_boards/platforms/analog_pocket.py b/litex_boards/platforms/analog_pocket.py new file mode 100644 index 0000000..c55d5b1 --- /dev/null +++ b/litex_boards/platforms/analog_pocket.py @@ -0,0 +1,213 @@ +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2023 Florent Kermarrec +# SPDX-License-Identifier: BSD-2-Clause + +from litex.build.generic_platform import * +from litex.build.altera import AlteraPlatform +from litex.build.openfpgaloader import OpenFPGALoader + +# IOs (LiteX) -------------------------------------------------------------------------------------- + +_io_physical_litex = [ + # Clk. + ("clk74a", 0, Pins("V15"), IOStandard("3.3-V LVCMOS")), + ("clk74b", 0, Pins("H16"), IOStandard("1.8 V")), + + # SDR SDRAM + ("sdram_clock", 0, Pins("G12"), IOStandard("1.8V")), + ("sdram", 0, + Subsignal("a", Pins( + "D17 D12 F12 E14 F13 E16 E15 F14", + "J18 G17 C13 F15 J17")), + Subsignal("ba", Pins("C16 E12")), + #Subsignal("cs_n", Pins("")), + Subsignal("cke", Pins("G18")), + Subsignal("ras_n", Pins("B11")), + Subsignal("cas_n", Pins("B16")), + Subsignal("we_n", Pins("C11")), + Subsignal("dq", Pins( + "C15 B15 A15 B13 A14 B12 A13 A12", + "J13 G15 G16 G13 H13 J19 G11 K20", + )), + Subsignal("dm", Pins("D13 H18")), + IOStandard("1.8V"), + ), +] + +_io_fpga2fpga_litex = [] + +# IOs (Analog) ------------------------------------------------------------------------------------- + +_io_physical_analog = [ + # Clk. + ("clk_74a", 0, Pins("V15"), IOStandard("3.3-V LVCMOS")), + ("clk_74b", 0, Pins("H16"), IOStandard("1.8 V")), + + # Cartbrige. + ("cart", 0, + Subsignal("tran_bank0", Pins("AB7 AA8 AB8 AA9")), + Subsignal("tran_bank0_dir", Pins("AB6")), + Subsignal("tran_bank1", Pins("AB13 AA12 AB12 Y11 AB11 Y10 AB10 AA10")), + Subsignal("tran_bank1_dir", Pins("AA13")), + Subsignal("tran_bank2", Pins("AB20 AA19 AA18 AB18 AA17 AB17 AA15 AB15")), + Subsignal("tran_bank2_dir", Pins("AA14")), + Subsignal("tran_bank3", Pins("W22 W21 Y22 Y21 AA22 AB22 AB21 AA20")), + Subsignal("tran_bank3_dir", Pins("V21")), + Subsignal("tran_pin30", Pins("L8"), IOStandard("1.8 V")), + Subsignal("tran_pin30_dir", Pins("AB5")), + Subsignal("pin30_pwroff_reset",Pins("L17"), IOStandard("1.8 V")), + Subsignal("tran_pin31", Pins("K9"), IOStandard("1.8 V")), + Subsignal("tran_pin31_dir", Pins("U22")), + IOStandard("3.3-V LVCMOS"), + ), + + # Infrared. + ("port_ir", 0, + Subsignal("rx", Pins("H10")), + Subsignal("tx", Pins("H11")), + Subsignal("rx_disable", Pins("L18")), + IOStandard("1.8 V"), + ), + + # GBA Link Port. + ("port_tran", 0, + Subsignal("si", Pins("V10")), + Subsignal("si_dir", Pins("V9")), + Subsignal("so", Pins("J11"), IOStandard("1.8 V")), + Subsignal("so_dir", Pins("T13")), + Subsignal("sck", Pins("AA7")), + Subsignal("sck_dir", Pins("Y9")), + Subsignal("sd", Pins("R9")), + Subsignal("sd_dir", Pins("T9")), + IOStandard("3.3-V LVCMOS"), + ), + + # PSRAM0 (AS1C8M16). + ("cram0", 0, + Subsignal("a", Pins("H6 C6 B6 B7 H9 H8")), + Subsignal("dq", Pins("B10 C8 A9 D7 E9 F10 G6 J7 C9 A10 D9 A8 E7 F9 L7 J9")), + Subsignal("wait", Pins("K7")), + Subsignal("clk", Pins("G10")), + Subsignal("adv_n", Pins("J8")), + Subsignal("cre", Pins("F7")), + Subsignal("ce0_n", Pins("B5")), + Subsignal("ce1_n", Pins("E10")), + Subsignal("oe_n", Pins("D6")), + Subsignal("we_n", Pins("G8")), + Subsignal("ub_n", Pins("A7")), + Subsignal("lb_n", Pins("A5")), + IOStandard("1.8 V"), + ), + + # PSRAM1 (AS1C8M16). + ("cram1", 0, + Subsignal("a", Pins("U2 U1 N1 L2 AA2 Y3")), + Subsignal("dq", Pins("C1 G2 E2 P6 R5 M6 U7 V6 D3 C2 N6 P7 R6 R7 U6 W8")), + Subsignal("wait", Pins("W9")), + Subsignal("clk", Pins("W2")), + Subsignal("adv_n", Pins("U8")), + Subsignal("cre", Pins("T7")), + Subsignal("ce0_n", Pins("N2")), + Subsignal("ce1_n", Pins("T8")), + Subsignal("oe_n", Pins("M7")), + Subsignal("we_n", Pins("AA1")), + Subsignal("ub_n", Pins("G1")), + Subsignal("lb_n", Pins("L1")), + IOStandard("1.8 V"), + ), + + # SDRAM (AS4C32M16). + ("dram", 0, + Subsignal("a", Pins("D17 D12 F12 E14 F13 E16 E15 F14 J18 G17 C13 F15 J17")), + Subsignal("ba", Pins("C16 E12")), + Subsignal("dq", Pins("C15 B15 A15 B13 A14 B12 A13 A12 J13 G15 G16 G13 H13 J19 G11 K20")), + Subsignal("dqm", Pins("D13 H18")), + Subsignal("clk", Pins("G12")), + Subsignal("cke", Pins("G18")), + Subsignal("ras_n", Pins("B11")), + Subsignal("cas_n", Pins("B16")), + Subsignal("we_n", Pins("C11")), + IOStandard("1.8 V"), + ), + + # SRAM (AS6C2016). + ("sram", 0, + Subsignal("a", Pins("T14 M9 M8 U21 N9 V19 P8 Y19 U13 Y14 U11 T10 V14 R10 U15 U12 V16")), + Subsignal("dq", Pins("N8 P9 P14 Y20 W19 T12 V13 R12 U16 U20 V18 V20 Y17 Y16 W16 Y15")), + Subsignal("oe_n", Pins("R14")), + Subsignal("we_n", Pins("R11")), + Subsignal("ub_n", Pins("U17")), + Subsignal("lb_n", Pins("P12")), + IOStandard("3.3-V LVCMOS"), + ), + + # Debug. + ("dbg_tx", 0, Pins("K21"), IOStandard("1.8 V")), + ("dbg_rx", 0, Pins("K22"), IOStandard("1.8 V")), + ("user1", 0, Pins("M22"), IOStandard("1.8 V")), + ("user2", 0, Pins("L22"), IOStandard("1.8 V")), + + # Aux I2C. + ("aux_sda", 0, Pins("M18"), IOStandard("1.8 V")), + ("aux_scl", 0, Pins("M16"), IOStandard("1.8 V")), + + # Others. + ("vblank", 0, Pins("N19"), IOStandard("1.8 V")), + ("bist", 0, Pins("U10"), IOStandard("3.3-V LVCMOS")), + ("vpll_feed", 0, Pins("P16"), IOStandard("1.8 V")), +] + +_io_fpga2fpga_analog = [ + # Scaler. + ("scal", 0, + Subsignal("vid", Pins("R21 P22 N16 P18 P19 T20 T19 T18 T22 R22 R15 R16")), + Subsignal("clk", Pins("R17")), + Subsignal("de", Pins("N20")), + Subsignal("skip", Pins("N21")), + Subsignal("vs", Pins("T15")), + Subsignal("hs", Pins("P17")), + + Subsignal("audmclk", Pins("K16")), + Subsignal("audadc", Pins("H15")), + Subsignal("auddac", Pins("K19")), + Subsignal("audlrck", Pins("K17")), + IOStandard("1.8 V"), + ), + + # Bridge. + ("bridge", 0, + Subsignal("spimosi", Pins("M20")), + Subsignal("spimiso", Pins("M21")), + Subsignal("spiclk", Pins("T17")), + Subsignal("spiss", Pins("H14")), + Subsignal("lwire", Pins("L19")), + IOStandard("1.8 V"), + ), +] + +# Connectors --------------------------------------------------------------------------------------- + +_connectors = [] + +# Platform ----------------------------------------------------------------------------------------- + +class Platform(AlteraPlatform): + default_clk_name = "clk74a" + default_clk_period = 1e9/74.25e6 + + def __init__(self, ios="litex", toolchain="quartus"): + _io = { + "litex" : _io_physical_litex + _io_fpga2fpga_litex, + "analog" : _io_physical_analog + _io_fpga2fpga_analog, + }[ios] + AlteraPlatform.__init__(self, "5CEBA4F23C8", _io, _connectors, toolchain=toolchain) + + def create_programmer(self): + return OpenFPGALoader(cable="usb-blaster") + + def do_finalize(self, fragment): + AlteraPlatform.do_finalize(self, fragment) + self.add_period_constraint(self.lookup_request("clk74a", loose=True), 1e9/74.25e6) + self.add_period_constraint(self.lookup_request("clk74b", loose=True), 1e9/74.25e6) diff --git a/litex_boards/targets/analog_pocket.py b/litex_boards/targets/analog_pocket.py new file mode 100644 index 0000000..b7a42aa --- /dev/null +++ b/litex_boards/targets/analog_pocket.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python3 + +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2023 Florent Kermarrec +# SPDX-License-Identifier: BSD-2-Clause + +# ./analog_pocket.py --uart-name=jtag_uart --build --load +# litex_term jtag --jtag-config=openocd_usb_blaster.cfg + +from migen import * + +from litex.gen import * + +from litex_boards.platforms import analog_pocket + +from litex.soc.integration.soc_core import * +from litex.soc.integration.builder import * + +from litex.build.io import DDROutput + +from litex.soc.cores.clock import CycloneVPLL + +from litedram.modules import AS4C32M16 +from litedram.phy import GENSDRPHY + +# CRG ---------------------------------------------------------------------------------------------- + +class _CRG(LiteXModule): + def __init__(self, platform, sys_clk_freq): + self.rst = Signal() + self.cd_sys = ClockDomain() + self.cd_sys_ps = ClockDomain() + + # # # + + # Clk / Rst + clk74 = platform.request("clk74a") + + # PLL + self.pll = pll = CycloneVPLL() + self.comb += pll.reset.eq(self.rst) + pll.register_clkin(clk74, 74.25e6) + pll.create_clkout(self.cd_sys, sys_clk_freq) + pll.create_clkout(self.cd_sys_ps, sys_clk_freq, phase=90) + + # SDRAM clock + sdram_clk = ClockSignal("sys_ps") + self.specials += DDROutput(1, 0, platform.request("sdram_clock"), sdram_clk) + +# BaseSoC ------------------------------------------------------------------------------------------ + +class BaseSoC(SoCCore): + def __init__(self, sys_clk_freq=50e6, **kwargs): + platform = analog_pocket.Platform() + + # CRG -------------------------------------------------------------------------------------- + self.crg = _CRG(platform, sys_clk_freq) + + # SoCCore ---------------------------------------------------------------------------------- + SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on Analog Pocket", **kwargs) + + # SDR SDRAM -------------------------------------------------------------------------------- + if not self.integrated_main_ram_size: + self.sdrphy = GENSDRPHY(platform.request("sdram"), sys_clk_freq) + self.add_sdram("sdram", + phy = self.sdrphy, + module = AS4C32M16(sys_clk_freq, "1:1"), + l2_cache_size = kwargs.get("l2_size", 8192) + ) + +# Build -------------------------------------------------------------------------------------------- + +def main(): + from litex.build.parser import LiteXArgumentParser + parser = LiteXArgumentParser(platform=analog_pocket.Platform, description="LiteX SoC on Analog Pocket.") + parser.add_target_argument("--sys-clk-freq", default=50e6, type=float, help="System clock frequency.") + args = parser.parse_args() + + soc = BaseSoC( + sys_clk_freq = args.sys_clk_freq, + **parser.soc_argdict + ) + builder = Builder(soc, **parser.builder_argdict) + if args.build: + builder.build(**parser.toolchain_argdict) + + if args.load: + prog = soc.platform.create_programmer() + prog.load_bitstream(builder.get_bitstream_filename(mode="sram").replace(".sof", ".rbf")) + +if __name__ == "__main__": + main()