From 0f8b8defb402acded517bcdc2f6e0ff7e4d3b5db Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Mon, 26 Aug 2024 11:29:27 +0200 Subject: [PATCH 01/10] efinix ti375 c529 dev kit bios OK --- .../platforms/efinix_ti375_c529_dev_kit.py | 78 +++++ .../targets/efinix_ti375_c529_dev_kit.py | 313 ++++++++++++++++++ 2 files changed, 391 insertions(+) create mode 100644 litex_boards/platforms/efinix_ti375_c529_dev_kit.py create mode 100755 litex_boards/targets/efinix_ti375_c529_dev_kit.py diff --git a/litex_boards/platforms/efinix_ti375_c529_dev_kit.py b/litex_boards/platforms/efinix_ti375_c529_dev_kit.py new file mode 100644 index 0000000..f64472f --- /dev/null +++ b/litex_boards/platforms/efinix_ti375_c529_dev_kit.py @@ -0,0 +1,78 @@ +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2021 Franck Jullien +# Copyright (c) 2021 Florent Kermarrec +# SPDX-License-Identifier: BSD-2-Clause + +from litex.build.generic_platform import * +from litex.build.efinix.platform import EfinixPlatform +from litex.build.efinix import EfinixProgrammer + +# IOs ---------------------------------------------------------------------------------------------- + +_io = [ + # Clk + ("clk25", 0, Pins("L17"), IOStandard("1.8_V_LVCMOS")), + ("clk100", 0, Pins("U4"), IOStandard("3.3_V_LVCMOS")), + + # Serial + ("serial", 0, + Subsignal("tx", Pins("E9")), + Subsignal("rx", Pins("E10")), + IOStandard("3.3_V_LVTTL"), Misc("WEAK_PULLUP") + ), + + # Buttons + ("user_btn", 0, Pins("U19"), IOStandard("3.3_V_LVCMOS")), +] + + + +# Bank voltage --------------------------------------------------------------------------------------- + +_bank_info = [ + ("2A" , "1.8 V LVCMOS"), # is_dyn_voltage="false" mode_sel_name="2A_MODE_SEL"/> + ("2B" , "1.8 V LVCMOS"), # is_dyn_voltage="false" mode_sel_name="2B_MODE_SEL"/> + ("2C" , "1.8 V LVCMOS"), # is_dyn_voltage="false" mode_sel_name="2C_MODE_SEL"/> + ("2D" , "1.8 V LVCMOS"), # is_dyn_voltage="false" mode_sel_name="2D_MODE_SEL"/> + ("2E" , "1.8 V LVCMOS"), # is_dyn_voltage="false" mode_sel_name="2E_MODE_SEL"/> + ("4A_4B" , "1.8 V LVCMOS"), # is_dyn_voltage="false" mode_sel_name="4A_4B_MODE_SEL"/> + ("4C" , "1.8 V LVCMOS"), # is_dyn_voltage="false" mode_sel_name="4C_MODE_SEL"/> + ("4D" , "1.8 V LVCMOS"), # is_dyn_voltage="false" mode_sel_name="4D_MODE_SEL"/> + ("BL2_BL3" , "3.3 V LVCMOS"), # is_dyn_voltage="false"> + ("BR0" , "3.3 V LVCMOS"), # is_dyn_voltage="false" mode_sel_name="BR0_MODE_SEL"/> + ("BR3_BR4" , "3.3 V LVCMOS"), # is_dyn_voltage="false"> + ("TL1_TL5" , "3.3 V LVCMOS"), # is_dyn_voltage="false"> + ("TR0" , "3.3 V LVCMOS"), # is_dyn_voltage="false" mode_sel_name="TR0_MODE_SEL"/> + ("TR1" , "3.3 V LVCMOS"), # is_dyn_voltage="false" mode_sel_name="TR1_MODE_SEL"/> + ("TR2" , "3.3 V LVCMOS"), # is_dyn_voltage="false" mode_sel_name="TR2_MODE_SEL"/> +] + +# Connectors --------------------------------------------------------------------------------------- + +_connectors = [ + ("pmod0", "G15 G16 F16 F17 G17 A11 A13 A12"), + ("pmod1", "B12 C14 C13 C12 D12 F12 D13 E13"), +] + +# PMODS -------------------------------------------------------------------------------------------- + +def raw_pmod_io(pmod): + return [(pmod, 0, Pins(" ".join([f"{pmod}:{i:d}" for i in range(8)])), IOStandard("3.3_V_LVTTL_/_LVCMOS"))] + +# Platform ----------------------------------------------------------------------------------------- + +class Platform(EfinixPlatform): + default_clk_name = "clk25" + default_clk_period = 1e9/25e6 + + def __init__(self, toolchain="efinity"): + EfinixPlatform.__init__(self, "Ti375C529C4", _io, _connectors, iobank_info=_bank_info, toolchain=toolchain) + + def create_programmer(self): + return EfinixProgrammer() + + def do_finalize(self, fragment): + EfinixPlatform.do_finalize(self, fragment) + self.add_period_constraint(self.lookup_request("clk25", loose=True), 1e9/25e6) diff --git a/litex_boards/targets/efinix_ti375_c529_dev_kit.py b/litex_boards/targets/efinix_ti375_c529_dev_kit.py new file mode 100755 index 0000000..d811ed5 --- /dev/null +++ b/litex_boards/targets/efinix_ti375_c529_dev_kit.py @@ -0,0 +1,313 @@ +#!/usr/bin/env python3 + +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2021 Franck Jullien +# Copyright (c) 2021 Florent Kermarrec +# SPDX-License-Identifier: BSD-2-Clause + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + +from litex.gen import * + +from litex_boards.platforms import efinix_ti375_c529_dev_kit + +from litex.soc.cores.clock import * +from litex.soc.integration.soc_core import * +from litex.soc.integration.soc import SoCRegion +from litex.soc.integration.builder import * +from litex.soc.cores.led import LedChaser +from litex.soc.interconnect import axi + +from liteeth.phy.trionrgmii import LiteEthPHYRGMII + +# CRG ---------------------------------------------------------------------------------------------- + +class _CRG(LiteXModule): + def __init__(self, platform, sys_clk_freq): + #self.rst = Signal() + self.cd_sys = ClockDomain() + + # # # + + clk25 = platform.request("clk25") + rst_n = platform.request("user_btn", 0) + + # PLL + self.pll = pll = TITANIUMPLL(platform) + self.comb += pll.reset.eq(~rst_n) + pll.register_clkin(clk25, 25e6) + # You can use CLKOUT0 only for clocks with a maximum frequency of 4x + # (integer) of the reference clock. If all your system clocks do not fall within + # this range, you should dedicate one unused clock for CLKOUT0. + pll.create_clkout(None, 25e6) + pll.create_clkout(self.cd_sys, sys_clk_freq, with_reset=True) + + +# BaseSoC ------------------------------------------------------------------------------------------ + +class BaseSoC(SoCCore): + def __init__(self, sys_clk_freq=100e6, + **kwargs): + platform = efinix_ti375_c529_dev_kit.Platform() + + # CRG -------------------------------------------------------------------------------------- + self.crg = _CRG(platform, sys_clk_freq) + + # SoCCore ---------------------------------------------------------------------------------- + SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on Efinix Ti375 C529 Dev Kit", **kwargs) + + # LPDDR4 SDRAM ----------------------------------------------------------------------------- + if not self.integrated_main_ram_size: + # DRAM / PLL Blocks. + # ------------------ + dram_pll_refclk = platform.request("dram_pll_refclk") + platform.toolchain.excluded_ios.append(dram_pll_refclk) + self.platform.toolchain.additional_sdc_commands.append(f"create_clock -period {1e9/50e6} dram_pll_refclk") + + from litex.build.efinix import InterfaceWriterBlock, InterfaceWriterXMLBlock + import xml.etree.ElementTree as et + + class PLLDRAMBlock(InterfaceWriterBlock): + @staticmethod + def generate(): + return """ +design.create_block("dram_pll", block_type="PLL") +design.set_property("dram_pll", {"REFCLK_FREQ":"50.0"}, block_type="PLL") +design.gen_pll_ref_clock("dram_pll", pll_res="PLL_BR0", refclk_src="EXTERNAL", refclk_name="dram_pll_clkin", ext_refclk_no="0") +design.set_property("dram_pll","LOCKED_PIN","dram_pll_locked", block_type="PLL") +design.set_property("dram_pll","RSTN_PIN","dram_pll_rst_n", block_type="PLL") +design.set_property("dram_pll", {"CLKOUT0_PIN" : "dram_pll_CLKOUT0"}, block_type="PLL") +design.set_property("dram_pll","CLKOUT0_PHASE","0","PLL") +calc_result = design.auto_calc_pll_clock("dram_pll", {"CLKOUT0_FREQ": "400.0"}) +""" + platform.toolchain.ifacewriter.blocks.append(PLLDRAMBlock()) + + class DRAMXMLBlock(InterfaceWriterXMLBlock): + @staticmethod + def generate(root, namespaces): + # CHECKME: Switch to DDRDesignService? + ddr_info = root.find("efxpt:ddr_info", namespaces) + + ddr = et.SubElement(ddr_info, "efxpt:ddr", + name = "ddr_inst1", + ddr_def = "DDR_0", + cs_preset_id = "173", + cs_mem_type = "LPDDR3", + cs_ctrl_width = "x32", + cs_dram_width = "x32", + cs_dram_density = "8G", + cs_speedbin = "800", + target0_enable = "true", + target1_enable = "true", + ctrl_type = "none" + ) + + gen_pin_target0 = et.SubElement(ddr, "efxpt:gen_pin_target0") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_wdata", type_name=f"WDATA_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_wready", type_name=f"WREADY_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_wid", type_name=f"WID_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_bready", type_name=f"BREADY_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_rdata", type_name=f"RDATA_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_aid", type_name=f"AID_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_bvalid", type_name=f"BVALID_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_rlast", type_name=f"RLAST_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_bid", type_name=f"BID_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_asize", type_name=f"ASIZE_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_atype", type_name=f"ATYPE_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_aburst", type_name=f"ABURST_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_wvalid", type_name=f"WVALID_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_wlast", type_name=f"WLAST_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_aaddr", type_name=f"AADDR_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_rid", type_name=f"RID_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_avalid", type_name=f"AVALID_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_rvalid", type_name=f"RVALID_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_alock", type_name=f"ALOCK_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_rready", type_name=f"RREADY_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_rresp", type_name=f"RRESP_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_wstrb", type_name=f"WSTRB_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_aready", type_name=f"AREADY_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_alen", type_name=f"ALEN_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="axi_clk", type_name=f"ACLK_0", is_bus="false", is_clk="true", is_clk_invert="false") + + gen_pin_target1 = et.SubElement(ddr, "efxpt:gen_pin_target1") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_wdata", type_name=f"WDATA_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_wready", type_name=f"WREADY_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_wid", type_name=f"WID_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_bready", type_name=f"BREADY_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_rdata", type_name=f"RDATA_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_aid", type_name=f"AID_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_bvalid", type_name=f"BVALID_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_rlast", type_name=f"RLAST_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_bid", type_name=f"BID_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_asize", type_name=f"ASIZE_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_atype", type_name=f"ATYPE_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_aburst", type_name=f"ABURST_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_wvalid", type_name=f"WVALID_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_wlast", type_name=f"WLAST_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_aaddr", type_name=f"AADDR_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_rid", type_name=f"RID_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_avalid", type_name=f"AVALID_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_rvalid", type_name=f"RVALID_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_alock", type_name=f"ALOCK_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_rready", type_name=f"RREADY_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_rresp", type_name=f"RRESP_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_wstrb", type_name=f"WSTRB_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_aready", type_name=f"AREADY_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_alen", type_name=f"ALEN_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="axi_clk", type_name=f"ACLK_1", is_bus="false", is_clk="true", is_clk_invert="false") + + gen_pin_config = et.SubElement(ddr, "efxpt:gen_pin_config") + et.SubElement(gen_pin_config, "efxpt:pin", name="", type_name="CFG_SEQ_RST", is_bus="false") + et.SubElement(gen_pin_config, "efxpt:pin", name="", type_name="CFG_SCL_IN", is_bus="false") + et.SubElement(gen_pin_config, "efxpt:pin", name="", type_name="CFG_SEQ_START", is_bus="false") + et.SubElement(gen_pin_config, "efxpt:pin", name="", type_name="RSTN", is_bus="false") + et.SubElement(gen_pin_config, "efxpt:pin", name="", type_name="CFG_SDA_IN", is_bus="false") + et.SubElement(gen_pin_config, "efxpt:pin", name="", type_name="CFG_SDA_OEN", is_bus="false") + + cs_fpga = et.SubElement(ddr, "efxpt:cs_fpga") + et.SubElement(cs_fpga, "efxpt:param", name="FPGA_ITERM", value="120", value_type="str") + et.SubElement(cs_fpga, "efxpt:param", name="FPGA_OTERM", value="34", value_type="str") + + cs_memory = et.SubElement(ddr, "efxpt:cs_memory") + et.SubElement(cs_memory, "efxpt:param", name="RTT_NOM", value="RZQ/2", value_type="str") + et.SubElement(cs_memory, "efxpt:param", name="MEM_OTERM", value="40", value_type="str") + et.SubElement(cs_memory, "efxpt:param", name="CL", value="RL=6/WL=3", value_type="str") + + timing = et.SubElement(ddr, "efxpt:cs_memory_timing") + et.SubElement(timing, "efxpt:param", name="tRAS", value="42.000", value_type="float") + et.SubElement(timing, "efxpt:param", name="tRC", value="60.000", value_type="float") + et.SubElement(timing, "efxpt:param", name="tRP", value="18.000", value_type="float") + et.SubElement(timing, "efxpt:param", name="tRCD", value="18.000", value_type="float") + et.SubElement(timing, "efxpt:param", name="tREFI", value="3.900", value_type="float") + et.SubElement(timing, "efxpt:param", name="tRFC", value="210.000", value_type="float") + et.SubElement(timing, "efxpt:param", name="tRTP", value="10.000", value_type="float") + et.SubElement(timing, "efxpt:param", name="tWTR", value="10.000", value_type="float") + et.SubElement(timing, "efxpt:param", name="tRRD", value="10.000", value_type="float") + et.SubElement(timing, "efxpt:param", name="tFAW", value="50.000", value_type="float") + + cs_control = et.SubElement(ddr, "efxpt:cs_control") + et.SubElement(cs_control, "efxpt:param", name="AMAP", value="ROW-COL_HIGH-BANK-COL_LOW", value_type="str") + et.SubElement(cs_control, "efxpt:param", name="EN_AUTO_PWR_DN", value="Off", value_type="str") + et.SubElement(cs_control, "efxpt:param", name="EN_AUTO_SELF_REF", value="No", value_type="str") + + cs_gate_delay = et.SubElement(ddr, "efxpt:cs_gate_delay") + et.SubElement(cs_gate_delay, "efxpt:param", name="EN_DLY_OVR", value="No", value_type="str") + et.SubElement(cs_gate_delay, "efxpt:param", name="GATE_C_DLY", value="3", value_type="int") + et.SubElement(cs_gate_delay, "efxpt:param", name="GATE_F_DLY", value="0", value_type="int") + + platform.toolchain.ifacewriter.xml_blocks.append(DRAMXMLBlock()) + + # DRAM Rst. + # --------- + dram_pll_rst_n = platform.add_iface_io("dram_pll_rst_n") + self.comb += dram_pll_rst_n.eq(platform.request("user_btn", 1)) + + # DRAM AXI-Ports. + # -------------- + for n, data_width in { + 0: 256, # target0: 256-bit. + 1: 128, # target1: 128-bit + }.items(): + axi_port = axi.AXIInterface(data_width=data_width, address_width=28, id_width=8) # 256MB. + ios = [(f"axi{n}", 0, + Subsignal("wdata", Pins(data_width)), + Subsignal("wready", Pins(1)), + Subsignal("wid", Pins(8)), + Subsignal("bready", Pins(1)), + Subsignal("rdata", Pins(data_width)), + Subsignal("aid", Pins(8)), + Subsignal("bvalid", Pins(1)), + Subsignal("rlast", Pins(1)), + Subsignal("bid", Pins(8)), + Subsignal("asize", Pins(3)), + Subsignal("atype", Pins(1)), + Subsignal("aburst", Pins(2)), + Subsignal("wvalid", Pins(1)), + Subsignal("aaddr", Pins(32)), + Subsignal("rid", Pins(8)), + Subsignal("avalid", Pins(1)), + Subsignal("rvalid", Pins(1)), + Subsignal("alock", Pins(2)), + Subsignal("rready", Pins(1)), + Subsignal("rresp", Pins(2)), + Subsignal("wstrb", Pins(data_width//8)), + Subsignal("aready", Pins(1)), + Subsignal("alen", Pins(8)), + Subsignal("wlast", Pins(1)), + )] + io = platform.add_iface_ios(ios) + rw_n = axi_port.ar.valid + self.comb += [ + # Pseudo AW/AR Channels. + io.atype.eq(~rw_n), + io.aaddr.eq( Mux(rw_n, axi_port.ar.addr, axi_port.aw.addr)), + io.aid.eq( Mux(rw_n, axi_port.ar.id, axi_port.aw.id)), + io.alen.eq( Mux(rw_n, axi_port.ar.len, axi_port.aw.len)), + io.asize.eq( Mux(rw_n, axi_port.ar.size, axi_port.aw.size)), + io.aburst.eq( Mux(rw_n, axi_port.ar.burst, axi_port.aw.burst)), + io.alock.eq( Mux(rw_n, axi_port.ar.lock, axi_port.aw.lock)), + io.avalid.eq( Mux(rw_n, axi_port.ar.valid, axi_port.aw.valid)), + axi_port.aw.ready.eq(~rw_n & io.aready), + axi_port.ar.ready.eq( rw_n & io.aready), + + # R Channel. + axi_port.r.id.eq(io.rid), + axi_port.r.data.eq(io.rdata), + axi_port.r.last.eq(io.rlast), + axi_port.r.resp.eq(io.rresp), + axi_port.r.valid.eq(io.rvalid), + io.rready.eq(axi_port.r.ready), + + # W Channel. + io.wid.eq(axi_port.w.id), + io.wstrb.eq(axi_port.w.strb), + io.wdata.eq(axi_port.w.data), + io.wlast.eq(axi_port.w.last), + io.wvalid.eq(axi_port.w.valid), + axi_port.w.ready.eq(io.wready), + + # B Channel. + axi_port.b.id.eq(io.bid), + axi_port.b.valid.eq(io.bvalid), + io.bready.eq(axi_port.b.ready), + ] + + # Connect AXI interface to the main bus of the SoC. + axi_lite_port = axi.AXILiteInterface(data_width=data_width, address_width=28) + self.submodules += axi.AXILite2AXI(axi_lite_port, axi_port) + self.bus.add_slave(f"target{n}", axi_lite_port, SoCRegion(origin=0x4000_0000 + 0x1000_0000*n, size=0x1000_0000)) # 256MB. + + # Use DRAM's target0 port as Main Ram ----------------------------------------------------- + self.bus.add_region("main_ram", SoCRegion( + origin = 0x4000_0000, + size = 0x1000_0000, # 256MB. + linker = True) + ) + +# Build -------------------------------------------------------------------------------------------- + +def main(): + from litex.build.parser import LiteXArgumentParser + parser = LiteXArgumentParser(platform=efinix_ti375_c529_dev_kit.Platform, description="LiteX SoC on Efinix Ti375 C529 Dev Kit.") + args = parser.parse_args() + + soc = BaseSoC( + **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")) + + # if args.flash: + # from litex.build.openfpgaloader import OpenFPGALoader + # prog = OpenFPGALoader("titanium_ti375_c529") + # prog.flash(0, builder.get_bitstream_filename(mode="flash", ext=".hex")) # FIXME + +if __name__ == "__main__": + main() From e604745c7db2096cbaa3c1827f10ffd6bad94cc7 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Mon, 26 Aug 2024 13:05:57 +0200 Subject: [PATCH 02/10] wip --- .../platforms/efinix_ti375_c529_dev_kit.py | 13 +- .../targets/efinix_ti375_c529_dev_kit.py | 182 +++++++++--------- 2 files changed, 100 insertions(+), 95 deletions(-) diff --git a/litex_boards/platforms/efinix_ti375_c529_dev_kit.py b/litex_boards/platforms/efinix_ti375_c529_dev_kit.py index f64472f..26a7c83 100644 --- a/litex_boards/platforms/efinix_ti375_c529_dev_kit.py +++ b/litex_boards/platforms/efinix_ti375_c529_dev_kit.py @@ -13,8 +13,8 @@ from litex.build.efinix import EfinixProgrammer _io = [ # Clk - ("clk25", 0, Pins("L17"), IOStandard("1.8_V_LVCMOS")), - ("clk100", 0, Pins("U4"), IOStandard("3.3_V_LVCMOS")), + ("clk25", None, Pins("L17"), IOStandard("1.8_V_LVCMOS")), + ("clk100", None, Pins("U4"), IOStandard("3.3_V_LVCMOS")), # Serial ("serial", 0, @@ -25,6 +25,9 @@ _io = [ # Buttons ("user_btn", 0, Pins("U19"), IOStandard("3.3_V_LVCMOS")), + + # DRAM. + ("dram_pll_refclk", 0, Pins("XXX"), IOStandard("3.3_V_LVTTL_/_LVCMOS")), ] @@ -64,8 +67,8 @@ def raw_pmod_io(pmod): # Platform ----------------------------------------------------------------------------------------- class Platform(EfinixPlatform): - default_clk_name = "clk25" - default_clk_period = 1e9/25e6 + default_clk_name = "clk100" + default_clk_period = 1e9/100e6 def __init__(self, toolchain="efinity"): EfinixPlatform.__init__(self, "Ti375C529C4", _io, _connectors, iobank_info=_bank_info, toolchain=toolchain) @@ -75,4 +78,4 @@ class Platform(EfinixPlatform): def do_finalize(self, fragment): EfinixPlatform.do_finalize(self, fragment) - self.add_period_constraint(self.lookup_request("clk25", loose=True), 1e9/25e6) + self.add_period_constraint(self.lookup_request("clk100", loose=True), 1e9/100e6) diff --git a/litex_boards/targets/efinix_ti375_c529_dev_kit.py b/litex_boards/targets/efinix_ti375_c529_dev_kit.py index d811ed5..0a27489 100755 --- a/litex_boards/targets/efinix_ti375_c529_dev_kit.py +++ b/litex_boards/targets/efinix_ti375_c529_dev_kit.py @@ -32,17 +32,17 @@ class _CRG(LiteXModule): # # # - clk25 = platform.request("clk25") + clk100 = platform.request("clk100") rst_n = platform.request("user_btn", 0) # PLL self.pll = pll = TITANIUMPLL(platform) self.comb += pll.reset.eq(~rst_n) - pll.register_clkin(clk25, 25e6) + pll.register_clkin(clk100, 100e6) # You can use CLKOUT0 only for clocks with a maximum frequency of 4x # (integer) of the reference clock. If all your system clocks do not fall within # this range, you should dedicate one unused clock for CLKOUT0. - pll.create_clkout(None, 25e6) + pll.create_clkout(None, 100e6) pll.create_clkout(self.cd_sys, sys_clk_freq, with_reset=True) @@ -60,30 +60,30 @@ class BaseSoC(SoCCore): SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on Efinix Ti375 C529 Dev Kit", **kwargs) # LPDDR4 SDRAM ----------------------------------------------------------------------------- - if not self.integrated_main_ram_size: + if None and not self.integrated_main_ram_size: # DRAM / PLL Blocks. # ------------------ dram_pll_refclk = platform.request("dram_pll_refclk") platform.toolchain.excluded_ios.append(dram_pll_refclk) - self.platform.toolchain.additional_sdc_commands.append(f"create_clock -period {1e9/50e6} dram_pll_refclk") + self.platform.toolchain.additional_sdc_commands.append(f"create_clock -period {1e9/100e6} dram_pll_refclk") from litex.build.efinix import InterfaceWriterBlock, InterfaceWriterXMLBlock import xml.etree.ElementTree as et - class PLLDRAMBlock(InterfaceWriterBlock): - @staticmethod - def generate(): - return """ -design.create_block("dram_pll", block_type="PLL") -design.set_property("dram_pll", {"REFCLK_FREQ":"50.0"}, block_type="PLL") -design.gen_pll_ref_clock("dram_pll", pll_res="PLL_BR0", refclk_src="EXTERNAL", refclk_name="dram_pll_clkin", ext_refclk_no="0") -design.set_property("dram_pll","LOCKED_PIN","dram_pll_locked", block_type="PLL") -design.set_property("dram_pll","RSTN_PIN","dram_pll_rst_n", block_type="PLL") -design.set_property("dram_pll", {"CLKOUT0_PIN" : "dram_pll_CLKOUT0"}, block_type="PLL") -design.set_property("dram_pll","CLKOUT0_PHASE","0","PLL") -calc_result = design.auto_calc_pll_clock("dram_pll", {"CLKOUT0_FREQ": "400.0"}) -""" - platform.toolchain.ifacewriter.blocks.append(PLLDRAMBlock()) +# class PLLDRAMBlock(InterfaceWriterBlock): +# @staticmethod +# def generate(): +# return """ +# design.create_block("dram_pll", block_type="PLL") +# design.set_property("dram_pll", {"REFCLK_FREQ":"100.0"}, block_type="PLL") +# design.gen_pll_ref_clock("dram_pll", pll_res="PLL_BL0", refclk_src="EXTERNAL", refclk_name="dram_pll_clkin", ext_refclk_no="0") +# design.set_property("dram_pll","LOCKED_PIN","dram_pll_locked", block_type="PLL") +# design.set_property("dram_pll","RSTN_PIN","dram_pll_rst_n", block_type="PLL") +# design.set_property("dram_pll", {"CLKOUT0_PIN" : "dram_pll_CLKOUT0"}, block_type="PLL") +# design.set_property("dram_pll","CLKOUT0_PHASE","0","PLL") +# calc_result = design.auto_calc_pll_clock("dram_pll", {"CLKOUT0_FREQ": "400.0"}) +# """ +# platform.toolchain.ifacewriter.blocks.append(PLLDRAMBlock()) class DRAMXMLBlock(InterfaceWriterXMLBlock): @staticmethod @@ -94,82 +94,84 @@ calc_result = design.auto_calc_pll_clock("dram_pll", {"CLKOUT0_FREQ": "400.0"}) ddr = et.SubElement(ddr_info, "efxpt:ddr", name = "ddr_inst1", ddr_def = "DDR_0", - cs_preset_id = "173", - cs_mem_type = "LPDDR3", - cs_ctrl_width = "x32", - cs_dram_width = "x32", - cs_dram_density = "8G", - cs_speedbin = "800", - target0_enable = "true", - target1_enable = "true", - ctrl_type = "none" + clkin_sel="0", + data_width="32", + physical_rank="1", + mem_type="LPDDR4x", + mem_density="8G" + # cs_preset_id = "173", + # cs_mem_type = "LPDDR3", + # cs_ctrl_width = "x32", + # cs_dram_width = "x32", + # cs_dram_density = "8G", + # cs_speedbin = "800", + # target0_enable = "true", + # target1_enable = "true", + # ctrl_type = "none" ) - gen_pin_target0 = et.SubElement(ddr, "efxpt:gen_pin_target0") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_wdata", type_name=f"WDATA_0", is_bus="true") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_wready", type_name=f"WREADY_0", is_bus="false") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_wid", type_name=f"WID_0", is_bus="true") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_bready", type_name=f"BREADY_0", is_bus="false") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_rdata", type_name=f"RDATA_0", is_bus="true") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_aid", type_name=f"AID_0", is_bus="true") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_bvalid", type_name=f"BVALID_0", is_bus="false") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_rlast", type_name=f"RLAST_0", is_bus="false") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_bid", type_name=f"BID_0", is_bus="true") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_asize", type_name=f"ASIZE_0", is_bus="true") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_atype", type_name=f"ATYPE_0", is_bus="false") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_aburst", type_name=f"ABURST_0", is_bus="true") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_wvalid", type_name=f"WVALID_0", is_bus="false") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_wlast", type_name=f"WLAST_0", is_bus="false") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_aaddr", type_name=f"AADDR_0", is_bus="true") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_rid", type_name=f"RID_0", is_bus="true") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_avalid", type_name=f"AVALID_0", is_bus="false") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_rvalid", type_name=f"RVALID_0", is_bus="false") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_alock", type_name=f"ALOCK_0", is_bus="true") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_rready", type_name=f"RREADY_0", is_bus="false") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_rresp", type_name=f"RRESP_0", is_bus="true") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_wstrb", type_name=f"WSTRB_0", is_bus="true") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_aready", type_name=f"AREADY_0", is_bus="false") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi0_alen", type_name=f"ALEN_0", is_bus="true") - et.SubElement(gen_pin_target0, "efxpt:pin", name="axi_clk", type_name=f"ACLK_0", is_bus="false", is_clk="true", is_clk_invert="false") + axi_target0 = et.SubElement(ddr, "efxpt:axi_target0",is_axi_width_256="false", is_axi_enable="true") + gen_pin_target0 = et.SubElement(axi_target0, "efxpt:gen_pin_axi") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_clk", type_name=f"ACLK_0", is_bus="false", is_clk="true", is_clk_invert="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_ar_apcmd", type_name="ARAPCMD_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_ar_ready", type_name="ARREADY_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_ar_valid", type_name="ARVALID_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_ar_qos", type_name="ARQOS_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_aw_apcmd", type_name="AWAPCMD_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_aw_allstrb", type_name="AWALLSTRB_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_awcobuf", type_name="AWCOBUF_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_aw_ready", type_name="AWREADY_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_aw_valid", type_name="AWVALID_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_aw_lock", type_name="AWLOCK_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_aw_qos", type_name="AWQOS_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_b_ready", type_name="BREADY_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_b_valid", type_name="BVALID_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_r_last", type_name="RLAST_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_r_ready", type_name="RREADY_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_r_valid", type_name="RVALID_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_w_last", type_name="WLAST_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_w_ready", type_name="WREADY_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_w_valid", type_name="WVALID_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_ar_addr", type_name="ARADDR_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_ar_burst", type_name="ARBURST_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_ar_id", type_name="ARID_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_ar_len", type_name="ARLEN_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_ar_size", type_name="ARSIZE_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_ar_lock", type_name="ARLOCK_0", is_bus="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_aw_addr", type_name="AWADDR_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_aw_burst", type_name="AWBURST_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_aw_id", type_name="AWID_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_aw_len", type_name="AWLEN_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_aw_size", type_name="AWSIZE_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_aw_cache", type_name="AWCACHE_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_b_id", type_name="BID_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_b_resp", type_name="BRESP_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_r_data", type_name="RDATA_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_r_id", type_name="RID_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_r_resp", type_name="RRESP_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_w_data", type_name="WDATA_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_w_strb", type_name="WSTRB_0", is_bus="true") + et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_resetn", type_name="ARSTN_0", is_bus="false") - gen_pin_target1 = et.SubElement(ddr, "efxpt:gen_pin_target1") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_wdata", type_name=f"WDATA_1", is_bus="true") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_wready", type_name=f"WREADY_1", is_bus="false") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_wid", type_name=f"WID_1", is_bus="true") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_bready", type_name=f"BREADY_1", is_bus="false") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_rdata", type_name=f"RDATA_1", is_bus="true") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_aid", type_name=f"AID_1", is_bus="true") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_bvalid", type_name=f"BVALID_1", is_bus="false") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_rlast", type_name=f"RLAST_1", is_bus="false") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_bid", type_name=f"BID_1", is_bus="true") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_asize", type_name=f"ASIZE_1", is_bus="true") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_atype", type_name=f"ATYPE_1", is_bus="false") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_aburst", type_name=f"ABURST_1", is_bus="true") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_wvalid", type_name=f"WVALID_1", is_bus="false") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_wlast", type_name=f"WLAST_1", is_bus="false") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_aaddr", type_name=f"AADDR_1", is_bus="true") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_rid", type_name=f"RID_1", is_bus="true") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_avalid", type_name=f"AVALID_1", is_bus="false") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_rvalid", type_name=f"RVALID_1", is_bus="false") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_alock", type_name=f"ALOCK_1", is_bus="true") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_rready", type_name=f"RREADY_1", is_bus="false") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_rresp", type_name=f"RRESP_1", is_bus="true") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_wstrb", type_name=f"WSTRB_1", is_bus="true") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_aready", type_name=f"AREADY_1", is_bus="false") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi1_alen", type_name=f"ALEN_1", is_bus="true") - et.SubElement(gen_pin_target1, "efxpt:pin", name="axi_clk", type_name=f"ACLK_1", is_bus="false", is_clk="true", is_clk_invert="false") + gen_pin_config = et.SubElement(ddr, "efxpt:gen_pin_controller") + et.SubElement(gen_pin_config, name="", type_name="CTRL_CLK", is_bus="false", is_clk="true", is_clk_invert="false") + et.SubElement(gen_pin_config, name="", type_name="CTRL_INT", is_bus="false") + et.SubElement(gen_pin_config, name="", type_name="CTRL_MEM_RST_VALID", is_bus="false") + et.SubElement(gen_pin_config, name="", type_name="CTRL_REFRESH", is_bus="false") + et.SubElement(gen_pin_config, name="", type_name="CTRL_BUSY", is_bus="false") + et.SubElement(gen_pin_config, name="", type_name="CTRL_CMD_Q_ALMOST_FULL", is_bus="false") + et.SubElement(gen_pin_config, name="", type_name="CTRL_DP_IDLE", is_bus="false") + et.SubElement(gen_pin_config, name="", type_name="CTRL_CKE", is_bus="true") + et.SubElement(gen_pin_config, name="", type_name="CTRL_PORT_BUSY", is_bus="true") - gen_pin_config = et.SubElement(ddr, "efxpt:gen_pin_config") - et.SubElement(gen_pin_config, "efxpt:pin", name="", type_name="CFG_SEQ_RST", is_bus="false") - et.SubElement(gen_pin_config, "efxpt:pin", name="", type_name="CFG_SCL_IN", is_bus="false") - et.SubElement(gen_pin_config, "efxpt:pin", name="", type_name="CFG_SEQ_START", is_bus="false") - et.SubElement(gen_pin_config, "efxpt:pin", name="", type_name="RSTN", is_bus="false") - et.SubElement(gen_pin_config, "efxpt:pin", name="", type_name="CFG_SDA_IN", is_bus="false") - et.SubElement(gen_pin_config, "efxpt:pin", name="", type_name="CFG_SDA_OEN", is_bus="false") + gen_pin_cfg_ctrl = et.SubElement(ddr, "efxpt:gen_pin_cfg_ctrl") + et.SubElement(gen_pin_cfg_ctrl, name="cfg_done", type_name="CFG_DONE", is_bus="false") + et.SubElement(gen_pin_cfg_ctrl, name="cfg_start", type_name="CFG_START", is_bus="false") + et.SubElement(gen_pin_cfg_ctrl, name="cfg_reset", type_name="CFG_RESET", is_bus="false") + et.SubElement(gen_pin_cfg_ctrl, name="cfg_sel", type_name="CFG_SEL", is_bus="false") + + ctrl_reg_inf = et.SubElement(ddr, "efxpt:ctrl_reg_inf") - cs_fpga = et.SubElement(ddr, "efxpt:cs_fpga") - et.SubElement(cs_fpga, "efxpt:param", name="FPGA_ITERM", value="120", value_type="str") - et.SubElement(cs_fpga, "efxpt:param", name="FPGA_OTERM", value="34", value_type="str") cs_memory = et.SubElement(ddr, "efxpt:cs_memory") et.SubElement(cs_memory, "efxpt:param", name="RTT_NOM", value="RZQ/2", value_type="str") From d2cc8ad815c5e443d313cb329a85049cc71670dc Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Mon, 26 Aug 2024 16:54:53 +0200 Subject: [PATCH 03/10] Got LPDDR4 to work --- .../targets/efinix_ti375_c529_dev_kit.py | 424 +++++++++++++----- 1 file changed, 310 insertions(+), 114 deletions(-) diff --git a/litex_boards/targets/efinix_ti375_c529_dev_kit.py b/litex_boards/targets/efinix_ti375_c529_dev_kit.py index 0a27489..2ea960d 100755 --- a/litex_boards/targets/efinix_ti375_c529_dev_kit.py +++ b/litex_boards/targets/efinix_ti375_c529_dev_kit.py @@ -22,6 +22,7 @@ from litex.soc.cores.led import LedChaser from litex.soc.interconnect import axi from liteeth.phy.trionrgmii import LiteEthPHYRGMII +from litex.build.generic_platform import Subsignal, Pins, Misc, IOStandard # CRG ---------------------------------------------------------------------------------------------- @@ -43,7 +44,9 @@ class _CRG(LiteXModule): # (integer) of the reference clock. If all your system clocks do not fall within # this range, you should dedicate one unused clock for CLKOUT0. pll.create_clkout(None, 100e6) - pll.create_clkout(self.cd_sys, sys_clk_freq, with_reset=True) + pll.create_clkout(self.cd_sys, sys_clk_freq, with_reset=True, name="cd_sys_clkout") + pll.create_clkout(None, 100e6) + pll.create_clkout(None, 800e6, name="dram_clk") # LPDDR4 ctrl # BaseSoC ------------------------------------------------------------------------------------------ @@ -60,7 +63,7 @@ class BaseSoC(SoCCore): SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on Efinix Ti375 C529 Dev Kit", **kwargs) # LPDDR4 SDRAM ----------------------------------------------------------------------------- - if None and not self.integrated_main_ram_size: + if not self.integrated_main_ram_size: # DRAM / PLL Blocks. # ------------------ dram_pll_refclk = platform.request("dram_pll_refclk") @@ -84,14 +87,15 @@ class BaseSoC(SoCCore): # calc_result = design.auto_calc_pll_clock("dram_pll", {"CLKOUT0_FREQ": "400.0"}) # """ # platform.toolchain.ifacewriter.blocks.append(PLLDRAMBlock()) - + data_width = 512 + axi_bus = axi.AXIInterface(data_width=data_width, address_width=28, id_width=8) # 256MB. class DRAMXMLBlock(InterfaceWriterXMLBlock): @staticmethod def generate(root, namespaces): # CHECKME: Switch to DDRDesignService? ddr_info = root.find("efxpt:ddr_info", namespaces) - ddr = et.SubElement(ddr_info, "efxpt:ddr", + ddr = et.SubElement(ddr_info, "efxpt:adv_ddr", name = "ddr_inst1", ddr_def = "DDR_0", clkin_sel="0", @@ -112,7 +116,7 @@ class BaseSoC(SoCCore): axi_target0 = et.SubElement(ddr, "efxpt:axi_target0",is_axi_width_256="false", is_axi_enable="true") gen_pin_target0 = et.SubElement(axi_target0, "efxpt:gen_pin_axi") - et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_clk", type_name=f"ACLK_0", is_bus="false", is_clk="true", is_clk_invert="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name="cd_sys_clkout", type_name=f"ACLK_0", is_bus="false", is_clk="true", is_clk_invert="false") et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_ar_apcmd", type_name="ARAPCMD_0", is_bus="false") et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_ar_ready", type_name="ARREADY_0", is_bus="false") et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_ar_valid", type_name="ARVALID_0", is_bus="false") @@ -153,141 +157,333 @@ class BaseSoC(SoCCore): et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_w_strb", type_name="WSTRB_0", is_bus="true") et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_resetn", type_name="ARSTN_0", is_bus="false") - gen_pin_config = et.SubElement(ddr, "efxpt:gen_pin_controller") - et.SubElement(gen_pin_config, name="", type_name="CTRL_CLK", is_bus="false", is_clk="true", is_clk_invert="false") - et.SubElement(gen_pin_config, name="", type_name="CTRL_INT", is_bus="false") - et.SubElement(gen_pin_config, name="", type_name="CTRL_MEM_RST_VALID", is_bus="false") - et.SubElement(gen_pin_config, name="", type_name="CTRL_REFRESH", is_bus="false") - et.SubElement(gen_pin_config, name="", type_name="CTRL_BUSY", is_bus="false") - et.SubElement(gen_pin_config, name="", type_name="CTRL_CMD_Q_ALMOST_FULL", is_bus="false") - et.SubElement(gen_pin_config, name="", type_name="CTRL_DP_IDLE", is_bus="false") - et.SubElement(gen_pin_config, name="", type_name="CTRL_CKE", is_bus="true") - et.SubElement(gen_pin_config, name="", type_name="CTRL_PORT_BUSY", is_bus="true") + axi_target1 = et.SubElement(ddr, "efxpt:axi_target1",is_axi_width_256="false", is_axi_enable="false") + gen_pin_target1 = et.SubElement(axi_target1, "efxpt:gen_pin_axi") + et.SubElement(gen_pin_target1, "efxpt:pin", name="cd_sys_clkout", type_name=f"ACLK_1", is_bus="false", is_clk="true", is_clk_invert="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_ar_apcmd", type_name="ARAPCMD_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_ar_ready", type_name="ARREADY_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_ar_valid", type_name="ARVALID_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_ar_qos", type_name="ARQOS_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_aw_apcmd", type_name="AWAPCMD_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_aw_allstrb", type_name="AWALLSTRB_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_awcobuf", type_name="AWCOBUF_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_aw_ready", type_name="AWREADY_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_aw_valid", type_name="AWVALID_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_aw_lock", type_name="AWLOCK_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_aw_qos", type_name="AWQOS_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_b_ready", type_name="BREADY_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_b_valid", type_name="BVALID_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_r_last", type_name="RLAST_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_r_ready", type_name="RREADY_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_r_valid", type_name="RVALID_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_w_last", type_name="WLAST_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_w_ready", type_name="WREADY_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_w_valid", type_name="WVALID_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_ar_addr", type_name="ARADDR_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_ar_burst", type_name="ARBURST_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_ar_id", type_name="ARID_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_ar_len", type_name="ARLEN_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_ar_size", type_name="ARSIZE_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_ar_lock", type_name="ARLOCK_1", is_bus="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_aw_addr", type_name="AWADDR_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_aw_burst", type_name="AWBURST_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_aw_id", type_name="AWID_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_aw_len", type_name="AWLEN_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_aw_size", type_name="AWSIZE_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_aw_cache", type_name="AWCACHE_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_b_id", type_name="BID_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_b_resp", type_name="BRESP_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_r_data", type_name="RDATA_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_r_id", type_name="RID_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_r_resp", type_name="RRESP_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_w_data", type_name="WDATA_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_w_strb", type_name="WSTRB_1", is_bus="true") + et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_resetn", type_name="ARSTN_1", is_bus="false") + + gen_pin_controller = et.SubElement(ddr, "efxpt:gen_pin_controller") + et.SubElement(gen_pin_controller,"efxpt:pin", name="", type_name="CTRL_CLK", is_bus="false", is_clk="true", is_clk_invert="false") + et.SubElement(gen_pin_controller,"efxpt:pin", name="", type_name="CTRL_INT", is_bus="false") + et.SubElement(gen_pin_controller,"efxpt:pin", name="", type_name="CTRL_MEM_RST_VALID", is_bus="false") + et.SubElement(gen_pin_controller,"efxpt:pin", name="", type_name="CTRL_REFRESH", is_bus="false") + et.SubElement(gen_pin_controller,"efxpt:pin", name="", type_name="CTRL_BUSY", is_bus="false") + et.SubElement(gen_pin_controller,"efxpt:pin", name="", type_name="CTRL_CMD_Q_ALMOST_FULL", is_bus="false") + et.SubElement(gen_pin_controller,"efxpt:pin", name="", type_name="CTRL_DP_IDLE", is_bus="false") + et.SubElement(gen_pin_controller,"efxpt:pin", name="", type_name="CTRL_CKE", is_bus="true") + et.SubElement(gen_pin_controller,"efxpt:pin", name="", type_name="CTRL_PORT_BUSY", is_bus="true") gen_pin_cfg_ctrl = et.SubElement(ddr, "efxpt:gen_pin_cfg_ctrl") - et.SubElement(gen_pin_cfg_ctrl, name="cfg_done", type_name="CFG_DONE", is_bus="false") - et.SubElement(gen_pin_cfg_ctrl, name="cfg_start", type_name="CFG_START", is_bus="false") - et.SubElement(gen_pin_cfg_ctrl, name="cfg_reset", type_name="CFG_RESET", is_bus="false") - et.SubElement(gen_pin_cfg_ctrl, name="cfg_sel", type_name="CFG_SEL", is_bus="false") + et.SubElement(gen_pin_cfg_ctrl,"efxpt:pin", name="cfg_done", type_name="CFG_DONE", is_bus="false") + et.SubElement(gen_pin_cfg_ctrl,"efxpt:pin", name="cfg_start", type_name="CFG_START", is_bus="false") + et.SubElement(gen_pin_cfg_ctrl,"efxpt:pin", name="cfg_reset", type_name="CFG_RESET", is_bus="false") + et.SubElement(gen_pin_cfg_ctrl,"efxpt:pin", name="cfg_sel", type_name="CFG_SEL", is_bus="false") - ctrl_reg_inf = et.SubElement(ddr, "efxpt:ctrl_reg_inf") + ctrl_reg_inf = et.SubElement(ddr, "efxpt:ctrl_reg_inf", is_reg_ena= "false") + gen_pin_ctrl_reg_inf = et.SubElement(ctrl_reg_inf, "efxpt:gen_pin_ctrl_reg_inf") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="axi0_ACLK", type_name="CR_ACLK", is_bus="false", is_clk="true", is_clk_invert="false") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regARESETn", type_name="CR_ARESETN", is_bus="false") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regARVALID", type_name="CR_ARVALID", is_bus="false") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regARREADY", type_name="CR_ARREADY", is_bus="false") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regAWVALID", type_name="CR_AWVALID", is_bus="false") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regAWREADY", type_name="CR_AWREADY", is_bus="false") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regBVALID", type_name="CR_BVALID", is_bus="false") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regBREADY", type_name="CR_BREADY", is_bus="false") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regRLAST", type_name="CR_RLAST", is_bus="false") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regRVALID", type_name="CR_RVALID", is_bus="false") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regRREADY", type_name="CR_RREADY", is_bus="false") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regWLAST", type_name="CR_WLAST", is_bus="false") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regWVALID", type_name="CR_WVALID", is_bus="false") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regWREADY", type_name="CR_WREADY", is_bus="false") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regARADDR", type_name="CR_ARADDR", is_bus="true") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regARID", type_name="CR_ARID", is_bus="true") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regARLEN", type_name="CR_ARLEN", is_bus="true") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regARSIZE", type_name="CR_ARSIZE", is_bus="true") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regARBURST", type_name="CR_ARBURST", is_bus="true") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regAWADDR", type_name="CR_AWADDR", is_bus="true") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regAWID", type_name="CR_AWID", is_bus="true") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regAWLEN", type_name="CR_AWLEN", is_bus="true") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regAWSIZE", type_name="CR_AWSIZE", is_bus="true") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regAWBURST", type_name="CR_AWBURST", is_bus="true") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regBID", type_name="CR_BID", is_bus="true") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regBRESP", type_name="CR_BRESP", is_bus="true") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regRDATA", type_name="CR_RDATA", is_bus="true") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regRID", type_name="CR_RID", is_bus="true") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regRRESP", type_name="CR_RRESP", is_bus="true") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regWDATA", type_name="CR_WDATA", is_bus="true") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="regWSTRB", type_name="CR_WSTRB", is_bus="true") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="" ,type_name="CFG_PHY_RSTN", is_bus="false") + et.SubElement(gen_pin_ctrl_reg_inf,"efxpt:pin", name="" ,type_name="CTRL_RSTN", is_bus="false") + cs_fpga = et.SubElement(ddr, "efxpt:cs_fpga") + et.SubElement(cs_fpga,"efxpt:param", name="DQ_PULLDOWN_DRV", value="34.3", value_type="str") + et.SubElement(cs_fpga,"efxpt:param", name="DQ_PULLDOWN_ODT", value="60", value_type="str") + et.SubElement(cs_fpga,"efxpt:param", name="DQ_PULLUP_DRV", value="34.3", value_type="str") + et.SubElement(cs_fpga,"efxpt:param", name="DQ_PULLUP_ODT", value="Hi-Z", value_type="str") + et.SubElement(cs_fpga,"efxpt:param", name="FPGA_VREF_RANGE0", value="22.040", value_type="float") + et.SubElement(cs_fpga,"efxpt:param", name="FPGA_VREF_RANGE1", value="23.000", value_type="float") + et.SubElement(cs_fpga,"efxpt:param", name="MEM_FPGA_VREF_RANGE", value="Range 1", value_type="str") cs_memory = et.SubElement(ddr, "efxpt:cs_memory") - et.SubElement(cs_memory, "efxpt:param", name="RTT_NOM", value="RZQ/2", value_type="str") - et.SubElement(cs_memory, "efxpt:param", name="MEM_OTERM", value="40", value_type="str") - et.SubElement(cs_memory, "efxpt:param", name="CL", value="RL=6/WL=3", value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="BLEN", value="BL=16 Sequential", value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="CA_ODT_CS0", value="RZQ/4", value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="CA_ODT_CS1", value="Disable", value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="CA_VREF_RANGE0", value="27.200", value_type="float") + et.SubElement(cs_memory,"efxpt:param", name="CA_VREF_RANGE1", value="22.000", value_type="float") + et.SubElement(cs_memory,"efxpt:param", name="DQ_ODT_CS0", value="RZQ/4", value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="DQ_ODT_CS1", value="Disable", value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="DQ_VREF_RANGE0", value="20.000", value_type="float") + et.SubElement(cs_memory,"efxpt:param", name="DQ_VREF_RANGE1", value="27.200", value_type="float") + et.SubElement(cs_memory,"efxpt:param", name="MEM_CA_RANGE", value="RANGE[1]", value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="MEM_DQ_RANGE", value="RANGE[1]", value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="NWR", value="nWR=6", value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="ODTD_CA_CS0", value="Obeys ODT_CA Bond Pad", value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="ODTD_CA_CS1", value="Obeys ODT_CA Bond Pad", value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="ODTE_CK_CS0", value="Override Disabled" ,value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="ODTE_CK_CS1", value="Override Disabled" ,value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="ODTE_CS_CS0", value="Override Disabled" ,value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="ODTE_CS_CS1", value="Override Disabled" ,value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="PDDS_CS0", value="RZQ/6", value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="PDDS_CS1", value="RFU", value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="RL_DBI_READ", value="Yes", value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="RL_DBI_READ_DISABLED", value="RL=6,nRTP=8", value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="RL_DBI_READ_ENABLED", value="RL=6,nRTP=8", value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="RL_DBI_WRITE", value="Yes", value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="WL_SET", value="Set A" ,value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="WL_SET_A", value="WL=4", value_type="str") + et.SubElement(cs_memory,"efxpt:param", name="WL_SET_B", value="WL=4", value_type="str") - timing = et.SubElement(ddr, "efxpt:cs_memory_timing") - et.SubElement(timing, "efxpt:param", name="tRAS", value="42.000", value_type="float") - et.SubElement(timing, "efxpt:param", name="tRC", value="60.000", value_type="float") - et.SubElement(timing, "efxpt:param", name="tRP", value="18.000", value_type="float") - et.SubElement(timing, "efxpt:param", name="tRCD", value="18.000", value_type="float") - et.SubElement(timing, "efxpt:param", name="tREFI", value="3.900", value_type="float") - et.SubElement(timing, "efxpt:param", name="tRFC", value="210.000", value_type="float") - et.SubElement(timing, "efxpt:param", name="tRTP", value="10.000", value_type="float") - et.SubElement(timing, "efxpt:param", name="tWTR", value="10.000", value_type="float") - et.SubElement(timing, "efxpt:param", name="tRRD", value="10.000", value_type="float") - et.SubElement(timing, "efxpt:param", name="tFAW", value="50.000", value_type="float") + cs_memory_timing = et.SubElement(ddr, "efxpt:cs_memory_timing") + et.SubElement(cs_memory_timing,"efxpt:param", name="tCCD", value="8", value_type="int") + et.SubElement(cs_memory_timing,"efxpt:param", name="tCCDMW", value="32", value_type="int") + et.SubElement(cs_memory_timing,"efxpt:param", name="tFAW", value="40.000", value_type="float") + et.SubElement(cs_memory_timing,"efxpt:param", name="tPPD", value="4", value_type="int") + et.SubElement(cs_memory_timing,"efxpt:param", name="tRAS", value="42.000", value_type="float") + et.SubElement(cs_memory_timing,"efxpt:param", name="tRCD", value="18.000", value_type="float") + et.SubElement(cs_memory_timing,"efxpt:param", name="tRPab", value="21.000", value_type="float") + et.SubElement(cs_memory_timing,"efxpt:param", name="tRPpb", value="18.000", value_type="float") + et.SubElement(cs_memory_timing,"efxpt:param", name="tRRD", value="10.000", value_type="float") + et.SubElement(cs_memory_timing,"efxpt:param", name="tRTP", value="7.500", value_type="float") + et.SubElement(cs_memory_timing,"efxpt:param", name="tSR", value="15.000", value_type="float") + et.SubElement(cs_memory_timing,"efxpt:param", name="tWR", value="18.000", value_type="float") + et.SubElement(cs_memory_timing,"efxpt:param", name="tWTR", value="10.000", value_type="float") - cs_control = et.SubElement(ddr, "efxpt:cs_control") - et.SubElement(cs_control, "efxpt:param", name="AMAP", value="ROW-COL_HIGH-BANK-COL_LOW", value_type="str") - et.SubElement(cs_control, "efxpt:param", name="EN_AUTO_PWR_DN", value="Off", value_type="str") - et.SubElement(cs_control, "efxpt:param", name="EN_AUTO_SELF_REF", value="No", value_type="str") - cs_gate_delay = et.SubElement(ddr, "efxpt:cs_gate_delay") - et.SubElement(cs_gate_delay, "efxpt:param", name="EN_DLY_OVR", value="No", value_type="str") - et.SubElement(cs_gate_delay, "efxpt:param", name="GATE_C_DLY", value="3", value_type="int") - et.SubElement(cs_gate_delay, "efxpt:param", name="GATE_F_DLY", value="0", value_type="int") + pin_swap = et.SubElement(ddr, "efxpt:pin_swap") + et.SubElement(pin_swap,"efxpt:param", name="CA[0]", value="CA[0]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="CA[1]", value="CA[1]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="CA[2]", value="CA[2]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="CA[3]", value="CA[3]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="CA[4]", value="CA[4]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="CA[5]", value="CA[5]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DM[0]", value="DM[0]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DM[1]", value="DM[1]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DM[2]", value="DM[2]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DM[3]", value="DM[3]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[0]", value="DQ[3]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[10]", value="DQ[12]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[11]", value="DQ[11]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[12]", value="DQ[8]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[13]", value="DQ[10]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[14]", value="DQ[13]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[15]", value="DQ[14]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[16]", value="DQ[22]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[17]", value="DQ[17]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[18]", value="DQ[18]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[19]", value="DQ[19]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[1]", value="DQ[6]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[20]", value="DQ[16]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[21]", value="DQ[20]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[22]", value="DQ[21]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[23]", value="DQ[23]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[24]", value="DQ[29]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[25]", value="DQ[31]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[26]", value="DQ[28]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[27]", value="DQ[30]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[28]", value="DQ[25]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[29]", value="DQ[27]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[2]", value="DQ[4]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[30]", value="DQ[26]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[31]", value="DQ[24]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[3]", value="DQ[5]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[4]", value="DQ[0]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[5]", value="DQ[1]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[6]", value="DQ[7]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[7]", value="DQ[2]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[8]", value="DQ[15]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="DQ[9]", value="DQ[9]", value_type="str") + et.SubElement(pin_swap,"efxpt:param", name="ENABLE_PIN_SWAP", value="true", value_type="bool") platform.toolchain.ifacewriter.xml_blocks.append(DRAMXMLBlock()) # DRAM Rst. # --------- - dram_pll_rst_n = platform.add_iface_io("dram_pll_rst_n") - self.comb += dram_pll_rst_n.eq(platform.request("user_btn", 1)) + #dram_pll_rst_n = platform.add_iface_io("dram_pll_rst_n") + #self.comb += dram_pll_rst_n.eq(platform.request("user_btn", 1)) # DRAM AXI-Ports. # -------------- - for n, data_width in { - 0: 256, # target0: 256-bit. - 1: 128, # target1: 128-bit - }.items(): - axi_port = axi.AXIInterface(data_width=data_width, address_width=28, id_width=8) # 256MB. - ios = [(f"axi{n}", 0, - Subsignal("wdata", Pins(data_width)), - Subsignal("wready", Pins(1)), - Subsignal("wid", Pins(8)), - Subsignal("bready", Pins(1)), - Subsignal("rdata", Pins(data_width)), - Subsignal("aid", Pins(8)), - Subsignal("bvalid", Pins(1)), - Subsignal("rlast", Pins(1)), - Subsignal("bid", Pins(8)), - Subsignal("asize", Pins(3)), - Subsignal("atype", Pins(1)), - Subsignal("aburst", Pins(2)), - Subsignal("wvalid", Pins(1)), - Subsignal("aaddr", Pins(32)), - Subsignal("rid", Pins(8)), - Subsignal("avalid", Pins(1)), - Subsignal("rvalid", Pins(1)), - Subsignal("alock", Pins(2)), - Subsignal("rready", Pins(1)), - Subsignal("rresp", Pins(2)), - Subsignal("wstrb", Pins(data_width//8)), - Subsignal("aready", Pins(1)), - Subsignal("alen", Pins(8)), - Subsignal("wlast", Pins(1)), - )] - io = platform.add_iface_ios(ios) - rw_n = axi_port.ar.valid - self.comb += [ - # Pseudo AW/AR Channels. - io.atype.eq(~rw_n), - io.aaddr.eq( Mux(rw_n, axi_port.ar.addr, axi_port.aw.addr)), - io.aid.eq( Mux(rw_n, axi_port.ar.id, axi_port.aw.id)), - io.alen.eq( Mux(rw_n, axi_port.ar.len, axi_port.aw.len)), - io.asize.eq( Mux(rw_n, axi_port.ar.size, axi_port.aw.size)), - io.aburst.eq( Mux(rw_n, axi_port.ar.burst, axi_port.aw.burst)), - io.alock.eq( Mux(rw_n, axi_port.ar.lock, axi_port.aw.lock)), - io.avalid.eq( Mux(rw_n, axi_port.ar.valid, axi_port.aw.valid)), - axi_port.aw.ready.eq(~rw_n & io.aready), - axi_port.ar.ready.eq( rw_n & io.aready), + ios = [(f"ddr0", 0, + Subsignal("ar_valid", Pins(1)), # + Subsignal("ar_ready", Pins(1)), # + Subsignal("ar_addr", Pins(33)), #32:0] + Subsignal("ar_id", Pins(6)), #5:0] + Subsignal("ar_len", Pins(8)), #7:0] + Subsignal("ar_size", Pins(3)), #2:0] + Subsignal("ar_burst", Pins(2)), #1:0] + Subsignal("ar_lock", Pins(1)), # + Subsignal("ar_apcmd", Pins(1)), # + Subsignal("ar_qos", Pins(1)), # + Subsignal("aw_valid", Pins(1)), # + Subsignal("aw_ready", Pins(1)), # + Subsignal("aw_addr", Pins(33)), #32:0] + Subsignal("aw_id", Pins(6)), #5:0] + Subsignal("aw_len", Pins(8)), #7:0] + Subsignal("aw_size", Pins(3)), #2:0] + Subsignal("aw_burst", Pins(2)), #1:0] + Subsignal("aw_lock", Pins(1)), # + Subsignal("aw_cache", Pins(4)), #3:0] + Subsignal("aw_qos", Pins(1)), # + Subsignal("aw_allstrb", Pins(1)), # + Subsignal("aw_apcmd", Pins(1)), # + Subsignal("awcobuf", Pins(1)), # + Subsignal("w_valid", Pins(1)), # + Subsignal("w_ready", Pins(1)), # + Subsignal("w_data", Pins(data_width)), #512-1:0] + Subsignal("w_strb", Pins(data_width//8)), #64-1:0] + Subsignal("w_last", Pins(1)), # + Subsignal("b_valid", Pins(1)), # + Subsignal("b_ready", Pins(1)), # + Subsignal("b_resp", Pins(1)), #1:0] + Subsignal("b_id", Pins(6)), #5:0] + Subsignal("r_valid", Pins(1)), # + Subsignal("r_ready", Pins(1)), # + Subsignal("r_data", Pins(data_width)), #512-1:0] + Subsignal("r_id", Pins(6)), #5:0] + Subsignal("r_resp", Pins(2)), #1:0] + Subsignal("r_last", Pins(1)), # + )] - # R Channel. - axi_port.r.id.eq(io.rid), - axi_port.r.data.eq(io.rdata), - axi_port.r.last.eq(io.rlast), - axi_port.r.resp.eq(io.rresp), - axi_port.r.valid.eq(io.rvalid), - io.rready.eq(axi_port.r.ready), + io = platform.add_iface_ios(ios) + self.comb += [ + io.ar_valid.eq(axi_bus.ar.valid), + axi_bus.ar.ready.eq(io.ar_ready), + io.ar_addr.eq(axi_bus.ar.addr), + io.ar_id.eq(axi_bus.ar.id), + io.ar_len.eq(axi_bus.ar.len), + io.ar_size.eq(axi_bus.ar.size), + io.ar_burst.eq(axi_bus.ar.burst), + io.ar_lock.eq(axi_bus.ar.lock), + io.ar_apcmd.eq(0), + io.ar_qos.eq(axi_bus.ar.qos), + io.aw_valid.eq(axi_bus.aw.valid), + axi_bus.aw.ready.eq(io.aw_ready), + io.aw_addr.eq(axi_bus.aw.addr), + io.aw_id.eq(axi_bus.aw.id), + io.aw_len.eq(axi_bus.aw.len), + io.aw_size.eq(axi_bus.aw.size), + io.aw_burst.eq(axi_bus.aw.burst), + io.aw_lock.eq(axi_bus.aw.lock), + io.aw_cache.eq(axi_bus.aw.cache), + io.aw_qos.eq(axi_bus.aw.qos), + io.aw_allstrb.eq(0), + io.aw_apcmd.eq(0), + io.awcobuf.eq(0), + io.w_valid.eq(axi_bus.w.valid), + axi_bus.w.ready.eq(io.w_ready), + io.w_data.eq(axi_bus.w.data), + io.w_strb.eq(axi_bus.w.strb), + io.w_last.eq(axi_bus.w.last), + axi_bus.b.valid.eq(io.b_valid), + io.b_ready.eq(axi_bus.b.ready), + axi_bus.b.resp.eq(io.b_resp), + axi_bus.b.id.eq(io.b_id), + axi_bus.r.valid.eq(io.r_valid), + io.r_ready.eq(axi_bus.r.ready), + axi_bus.r.data.eq(io.r_data), + axi_bus.r.id.eq(io.r_id), + axi_bus.r.resp.eq(io.r_resp), + axi_bus.r.last.eq(io.r_last), + ] - # W Channel. - io.wid.eq(axi_port.w.id), - io.wstrb.eq(axi_port.w.strb), - io.wdata.eq(axi_port.w.data), - io.wlast.eq(axi_port.w.last), - io.wvalid.eq(axi_port.w.valid), - axi_port.w.ready.eq(io.wready), + if hasattr(self.cpu, "add_memory_buses"): + self.cpu.add_memory_buses(address_width = 32, data_width = data_width) - # B Channel. - axi_port.b.id.eq(io.bid), - axi_port.b.valid.eq(io.bvalid), - io.bready.eq(axi_port.b.ready), - ] + assert len(self.cpu.memory_buses) == 1 + mbus = self.cpu.memory_buses[0] + self.comb +=mbus.connect(axi_bus) + + cfgs = [(f"cfg", 0, + Subsignal("start", Pins(1)), + Subsignal("reset", Pins(1)), + Subsignal("sel", Pins(1)), + Subsignal("done", Pins(1)), + )] - # Connect AXI interface to the main bus of the SoC. - axi_lite_port = axi.AXILiteInterface(data_width=data_width, address_width=28) - self.submodules += axi.AXILite2AXI(axi_lite_port, axi_port) - self.bus.add_slave(f"target{n}", axi_lite_port, SoCRegion(origin=0x4000_0000 + 0x1000_0000*n, size=0x1000_0000)) # 256MB. + cfg = platform.add_iface_ios(cfgs) + self.cfg_state = Signal(1, reset=0) + self.cfg_count = Signal(8, reset=0) + + self.comb += [ + cfg.sel.eq(0), + cfg.reset.eq(self.cfg_state == 0), + cfg.start.eq(self.cfg_state != 0), + ] + + self.sync += self.cfg_count.eq(self.cfg_count + (self.cfg_count != 0xFF)) + self.sync += self.cfg_state.eq(self.cfg_state | (self.cfg_count == 0xFF)) + + + + # Connect AXI interface to the main bus of the SoC. + # axi_lite_port = axi.AXILiteInterface(data_width=data_width, address_width=28) + # self.submodules += axi.AXILite2AXI(axi_lite_port, axi_port) + # self.bus.add_slave(f"target{n}", axi_lite_port, SoCRegion(origin=0x4000_0000 + 0x1000_0000*n, size=0x1000_0000)) # 256MB. # Use DRAM's target0 port as Main Ram ----------------------------------------------------- self.bus.add_region("main_ram", SoCRegion( origin = 0x4000_0000, size = 0x1000_0000, # 256MB. - linker = True) - ) + mode="rwx", + )) # Build -------------------------------------------------------------------------------------------- From 144462e8622fc6309c7fa5120050bc0c8f8d2005 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Mon, 26 Aug 2024 18:08:09 +0200 Subject: [PATCH 04/10] add jtag --- .../platforms/efinix_ti375_c529_dev_kit.py | 11 ++++- .../targets/efinix_ti375_c529_dev_kit.py | 48 ++++++++----------- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/litex_boards/platforms/efinix_ti375_c529_dev_kit.py b/litex_boards/platforms/efinix_ti375_c529_dev_kit.py index 26a7c83..9957057 100644 --- a/litex_boards/platforms/efinix_ti375_c529_dev_kit.py +++ b/litex_boards/platforms/efinix_ti375_c529_dev_kit.py @@ -63,7 +63,16 @@ _connectors = [ def raw_pmod_io(pmod): return [(pmod, 0, Pins(" ".join([f"{pmod}:{i:d}" for i in range(8)])), IOStandard("3.3_V_LVTTL_/_LVCMOS"))] - +def jtag_pmod_io(pmod): + return [ + ("usb_uart", 0, + Subsignal("tck", Pins(f"{pmod}:0")), + Subsignal("tdi", Pins(f"{pmod}:1")), + Subsignal("tdo", Pins(f"{pmod}:2")), + Subsignal("tms", Pins(f"{pmod}:3")), + IOStandard("3.3_V_LVCMOS") + ), + ] # Platform ----------------------------------------------------------------------------------------- class Platform(EfinixPlatform): diff --git a/litex_boards/targets/efinix_ti375_c529_dev_kit.py b/litex_boards/targets/efinix_ti375_c529_dev_kit.py index 2ea960d..70c41ee 100755 --- a/litex_boards/targets/efinix_ti375_c529_dev_kit.py +++ b/litex_boards/targets/efinix_ti375_c529_dev_kit.py @@ -62,6 +62,24 @@ class BaseSoC(SoCCore): # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on Efinix Ti375 C529 Dev Kit", **kwargs) + if hasattr(self.cpu, "jtag_clk"): + _jtag_io = [ + ("jtag", 0, + Subsignal("tck", Pins("pmod0:0")), + Subsignal("tdi", Pins("pmod0:1")), + Subsignal("tdo", Pins("pmod0:2")), + Subsignal("tms", Pins("pmod0:3")), + IOStandard("3.3_V_LVCMOS"), + ) + ] + self.platform.add_extension(_jtag_io) + jtag_pads = platform.request("jtag") + self.comb += self.cpu.jtag_clk.eq(jtag_pads.tck) + self.comb += self.cpu.jtag_tms.eq(jtag_pads.tms) + self.comb += self.cpu.jtag_tdi.eq(jtag_pads.tdi) + self.comb += jtag_pads.tdo.eq(self.cpu.jtag_tdo) + platform.add_false_path_constraints(self.crg.cd_sys.clk, jtag_pads.tck) + # LPDDR4 SDRAM ----------------------------------------------------------------------------- if not self.integrated_main_ram_size: # DRAM / PLL Blocks. @@ -73,22 +91,8 @@ class BaseSoC(SoCCore): from litex.build.efinix import InterfaceWriterBlock, InterfaceWriterXMLBlock import xml.etree.ElementTree as et -# class PLLDRAMBlock(InterfaceWriterBlock): -# @staticmethod -# def generate(): -# return """ -# design.create_block("dram_pll", block_type="PLL") -# design.set_property("dram_pll", {"REFCLK_FREQ":"100.0"}, block_type="PLL") -# design.gen_pll_ref_clock("dram_pll", pll_res="PLL_BL0", refclk_src="EXTERNAL", refclk_name="dram_pll_clkin", ext_refclk_no="0") -# design.set_property("dram_pll","LOCKED_PIN","dram_pll_locked", block_type="PLL") -# design.set_property("dram_pll","RSTN_PIN","dram_pll_rst_n", block_type="PLL") -# design.set_property("dram_pll", {"CLKOUT0_PIN" : "dram_pll_CLKOUT0"}, block_type="PLL") -# design.set_property("dram_pll","CLKOUT0_PHASE","0","PLL") -# calc_result = design.auto_calc_pll_clock("dram_pll", {"CLKOUT0_FREQ": "400.0"}) -# """ -# platform.toolchain.ifacewriter.blocks.append(PLLDRAMBlock()) data_width = 512 - axi_bus = axi.AXIInterface(data_width=data_width, address_width=28, id_width=8) # 256MB. + axi_bus = axi.AXIInterface(data_width=data_width, address_width=30, id_width=8) # 256MB. class DRAMXMLBlock(InterfaceWriterXMLBlock): @staticmethod def generate(root, namespaces): @@ -354,11 +358,6 @@ class BaseSoC(SoCCore): platform.toolchain.ifacewriter.xml_blocks.append(DRAMXMLBlock()) - # DRAM Rst. - # --------- - #dram_pll_rst_n = platform.add_iface_io("dram_pll_rst_n") - #self.comb += dram_pll_rst_n.eq(platform.request("user_btn", 1)) - # DRAM AXI-Ports. # -------------- ios = [(f"ddr0", 0, @@ -471,17 +470,10 @@ class BaseSoC(SoCCore): self.sync += self.cfg_count.eq(self.cfg_count + (self.cfg_count != 0xFF)) self.sync += self.cfg_state.eq(self.cfg_state | (self.cfg_count == 0xFF)) - - - # Connect AXI interface to the main bus of the SoC. - # axi_lite_port = axi.AXILiteInterface(data_width=data_width, address_width=28) - # self.submodules += axi.AXILite2AXI(axi_lite_port, axi_port) - # self.bus.add_slave(f"target{n}", axi_lite_port, SoCRegion(origin=0x4000_0000 + 0x1000_0000*n, size=0x1000_0000)) # 256MB. - # Use DRAM's target0 port as Main Ram ----------------------------------------------------- self.bus.add_region("main_ram", SoCRegion( origin = 0x4000_0000, - size = 0x1000_0000, # 256MB. + size = 0x4000_0000, # 1GB. mode="rwx", )) From abaa9c404c9c1aa198e69f69acb410c61a189797 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Mon, 26 Aug 2024 18:27:55 +0200 Subject: [PATCH 05/10] Fix the reset --- litex_boards/targets/efinix_ti375_c529_dev_kit.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/litex_boards/targets/efinix_ti375_c529_dev_kit.py b/litex_boards/targets/efinix_ti375_c529_dev_kit.py index 70c41ee..7592bfb 100755 --- a/litex_boards/targets/efinix_ti375_c529_dev_kit.py +++ b/litex_boards/targets/efinix_ti375_c529_dev_kit.py @@ -399,6 +399,7 @@ class BaseSoC(SoCCore): Subsignal("r_id", Pins(6)), #5:0] Subsignal("r_resp", Pins(2)), #1:0] Subsignal("r_last", Pins(1)), # + Subsignal("resetn", Pins(1)), )] io = platform.add_iface_ios(ios) @@ -441,6 +442,7 @@ class BaseSoC(SoCCore): axi_bus.r.id.eq(io.r_id), axi_bus.r.resp.eq(io.r_resp), axi_bus.r.last.eq(io.r_last), + io.resetn.eq(~self.crg.cd_sys.rst), ] if hasattr(self.cpu, "add_memory_buses"): From 30e26cacace61d0ed4b632631d14a2cad8b49b3d Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Tue, 27 Aug 2024 08:31:53 +0200 Subject: [PATCH 06/10] Add sdcard and usb ohci support --- .../platforms/efinix_ti375_c529_dev_kit.py | 15 +++++++ .../targets/efinix_ti375_c529_dev_kit.py | 40 ++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/litex_boards/platforms/efinix_ti375_c529_dev_kit.py b/litex_boards/platforms/efinix_ti375_c529_dev_kit.py index 9957057..745973f 100644 --- a/litex_boards/platforms/efinix_ti375_c529_dev_kit.py +++ b/litex_boards/platforms/efinix_ti375_c529_dev_kit.py @@ -28,6 +28,21 @@ _io = [ # DRAM. ("dram_pll_refclk", 0, Pins("XXX"), IOStandard("3.3_V_LVTTL_/_LVCMOS")), + + # SD-Card + ("spisdcard", 0, + Subsignal("clk", Pins("C9")), + Subsignal("mosi", Pins("C10"), Misc("WEAK_PULLUP")), + Subsignal("cs_n", Pins("A9"), Misc("WEAK_PULLUP")), + Subsignal("miso", Pins("B9"), Misc("WEAK_PULLUP")), + IOStandard("3.3_V_LVCMOS"), + ), + ("sdcard", 0, + Subsignal("data", Pins("B9 B10 A8 A9"), Misc("WEAK_PULLUP")), + Subsignal("cmd", Pins("C10"), Misc("WEAK_PULLUP")), + Subsignal("clk", Pins("C9")), + IOStandard("3.3_V_LVCMOS"), + ), ] diff --git a/litex_boards/targets/efinix_ti375_c529_dev_kit.py b/litex_boards/targets/efinix_ti375_c529_dev_kit.py index 7592bfb..041bbb9 100755 --- a/litex_boards/targets/efinix_ti375_c529_dev_kit.py +++ b/litex_boards/targets/efinix_ti375_c529_dev_kit.py @@ -24,12 +24,17 @@ from litex.soc.interconnect import axi from liteeth.phy.trionrgmii import LiteEthPHYRGMII from litex.build.generic_platform import Subsignal, Pins, Misc, IOStandard +# python3 -m litex_boards.targets.efinix_ti375_c529_dev_kit --cpu-type=vexiiriscv --cpu-variant=debian --update-repo=no --with-jtag-tap --with-sdcard --with-coherent-dma +# python3 -m litex.tools.litex_json2dts_linux build/efinix_ti375_c529_dev_kit/csr.json --root-device=mmcblk0p2 > build/efinix_ti375_c529_dev_kit/linux.dts + + # CRG ---------------------------------------------------------------------------------------------- class _CRG(LiteXModule): def __init__(self, platform, sys_clk_freq): #self.rst = Signal() self.cd_sys = ClockDomain() + self.cd_usb = ClockDomain() # # # @@ -45,14 +50,19 @@ class _CRG(LiteXModule): # this range, you should dedicate one unused clock for CLKOUT0. pll.create_clkout(None, 100e6) pll.create_clkout(self.cd_sys, sys_clk_freq, with_reset=True, name="cd_sys_clkout") - pll.create_clkout(None, 100e6) + pll.create_clkout(self.cd_usb, 60e6, margin=0) pll.create_clkout(None, 800e6, name="dram_clk") # LPDDR4 ctrl # BaseSoC ------------------------------------------------------------------------------------------ class BaseSoC(SoCCore): + mem_map = {**SoCCore.mem_map, **{ + "usb_ohci": 0xE0000000, + }} + def __init__(self, sys_clk_freq=100e6, + with_ohci=False, **kwargs): platform = efinix_ti375_c529_dev_kit.Platform() @@ -62,6 +72,25 @@ class BaseSoC(SoCCore): # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on Efinix Ti375 C529 Dev Kit", **kwargs) + # OHCI + if with_ohci: + from litex.soc.cores.usb_ohci import USBOHCI + from litex.build.generic_platform import Subsignal, Pins, IOStandard + from litex.soc.integration.soc import SoCRegion + _usb_pmod_ios = [ + ("usb_pmod1", 0, + Subsignal("dp", Pins("pmod1:0", "pmod1:1", "pmod1:2", "pmod1:3")), + Subsignal("dm", Pins("pmod1:4", "pmod1:5", "pmod1:6", "pmod1:7")), + IOStandard("3.3_V_LVCMOS"), + ) + ] + platform.add_extension(_usb_pmod_ios) + self.submodules.usb_ohci = USBOHCI(platform, platform.request("usb_pmod1"), usb_clk_freq=int(60e6)) + self.bus.add_slave("usb_ohci_ctrl", self.usb_ohci.wb_ctrl, region=SoCRegion(origin=self.mem_map["usb_ohci"], size=0x100000, cached=False)) + self.dma_bus.add_master("usb_ohci_dma", master=self.usb_ohci.wb_dma) + self.comb += self.cpu.interrupt[16].eq(self.usb_ohci.interrupt) + + # JTAG if hasattr(self.cpu, "jtag_clk"): _jtag_io = [ ("jtag", 0, @@ -484,10 +513,19 @@ class BaseSoC(SoCCore): def main(): from litex.build.parser import LiteXArgumentParser parser = LiteXArgumentParser(platform=efinix_ti375_c529_dev_kit.Platform, description="LiteX SoC on Efinix Ti375 C529 Dev Kit.") + parser.add_target_argument("--with-ohci", action="store_true", help="Enable USB OHCI.") + sdopts = parser.target_group.add_mutually_exclusive_group() + sdopts.add_argument("--with-spi-sdcard", action="store_true", help="Enable SPI-mode SDCard support.") + sdopts.add_argument("--with-sdcard", action="store_true", help="Enable SDCard support.") args = parser.parse_args() soc = BaseSoC( + with_ohci = args.with_ohci, **parser.soc_argdict) + if args.with_spi_sdcard: + soc.add_spi_sdcard() + if args.with_sdcard: + soc.add_sdcard() builder = Builder(soc, **parser.builder_argdict) if args.build: builder.build(**parser.toolchain_argdict) From 664525471f0658537e5e1080e6dd08e4193e2930 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Wed, 28 Aug 2024 20:19:33 +0200 Subject: [PATCH 07/10] Got HDMI to work on hardware --- .../platforms/efinix_ti375_c529_dev_kit.py | 29 +++++ .../targets/efinix_ti375_c529_dev_kit.py | 107 +++++++++++++++++- 2 files changed, 132 insertions(+), 4 deletions(-) diff --git a/litex_boards/platforms/efinix_ti375_c529_dev_kit.py b/litex_boards/platforms/efinix_ti375_c529_dev_kit.py index 745973f..40f33a7 100644 --- a/litex_boards/platforms/efinix_ti375_c529_dev_kit.py +++ b/litex_boards/platforms/efinix_ti375_c529_dev_kit.py @@ -72,6 +72,16 @@ _bank_info = [ _connectors = [ ("pmod0", "G15 G16 F16 F17 G17 A11 A13 A12"), ("pmod1", "B12 C14 C13 C12 D12 F12 D13 E13"), + ("pmod2", "E14 E16 F13 E15 F14 E11 F11 D11"), + ["p1", + "---", # 0 + # 3V3 5V GND GND GND GND GND GND ↓ + "--- B21 --- A21 --- --- C22 E21 B22 D21 --- --- B23 F21 A22 F22 --- --- D22 G21", + # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ↑ + # 21 22 23 24 25 26 27 28 28 30 31 32 33 34 35 36 37 38 39 40 ↓ + "D23 G22 --- --- F23 H20 E23 G20 --- --- H22 K23 H23 L23 --- --- L19 M21 M19 M22", + # GND GND GND GND GND GND ↑ + ], ] # PMODS -------------------------------------------------------------------------------------------- @@ -88,6 +98,25 @@ def jtag_pmod_io(pmod): IOStandard("3.3_V_LVCMOS") ), ] +def hdmi_px(px): + return [ + ("hdmi_i2c", 0, + Subsignal("sda", Pins(f"{px}:26")), + Subsignal("scl", Pins(f"{px}:28")), + IOStandard("1.8_V_LVCMOS"), Misc("WEAK_PULLUP"), Misc("SCHMITT_TRIGGER") + ), + ("hdmi_data", 0, + Subsignal("clk", Pins(f"{px}:4")), + Subsignal("de", Pins(f"{px}:33")), + Subsignal("d", Pins(f"{px}:31 {px}:27 {px}:25 {px}:21 {px}:19 {px}:15 {px}:13 {px}:9 {px}:7 {px}:2 {px}:8 {px}:10 {px}:14 {px}:16 {px}:20 {px}:22")), + IOStandard("1.8_V_LVCMOS") + ), + ("hdmi_sync", 0, + Subsignal("hsync", Pins(f"{px}:37")), + Subsignal("vsync", Pins(f"{px}:39")), + IOStandard("1.8_V_LVCMOS") + ), + ] # Platform ----------------------------------------------------------------------------------------- class Platform(EfinixPlatform): diff --git a/litex_boards/targets/efinix_ti375_c529_dev_kit.py b/litex_boards/targets/efinix_ti375_c529_dev_kit.py index 041bbb9..8441b07 100755 --- a/litex_boards/targets/efinix_ti375_c529_dev_kit.py +++ b/litex_boards/targets/efinix_ti375_c529_dev_kit.py @@ -20,10 +20,14 @@ from litex.soc.integration.soc import SoCRegion from litex.soc.integration.builder import * from litex.soc.cores.led import LedChaser from litex.soc.interconnect import axi +from litex.soc.cores.bitbang import I2CMaster from liteeth.phy.trionrgmii import LiteEthPHYRGMII from litex.build.generic_platform import Subsignal, Pins, Misc, IOStandard - +from litex.soc.cores.usb_ohci import USBOHCI +from litex.soc.integration.soc import SoCRegion +from litex.build.io import DDROutput +from litex.build.io import SDRTristate # python3 -m litex_boards.targets.efinix_ti375_c529_dev_kit --cpu-type=vexiiriscv --cpu-variant=debian --update-repo=no --with-jtag-tap --with-sdcard --with-coherent-dma # python3 -m litex.tools.litex_json2dts_linux build/efinix_ti375_c529_dev_kit/csr.json --root-device=mmcblk0p2 > build/efinix_ti375_c529_dev_kit/linux.dts @@ -35,6 +39,7 @@ class _CRG(LiteXModule): #self.rst = Signal() self.cd_sys = ClockDomain() self.cd_usb = ClockDomain() + self.cd_video = ClockDomain() # # # @@ -52,6 +57,7 @@ class _CRG(LiteXModule): pll.create_clkout(self.cd_sys, sys_clk_freq, with_reset=True, name="cd_sys_clkout") pll.create_clkout(self.cd_usb, 60e6, margin=0) pll.create_clkout(None, 800e6, name="dram_clk") # LPDDR4 ctrl + pll.create_clkout(self.cd_video, 25e6, name ="video_clk") # BaseSoC ------------------------------------------------------------------------------------------ @@ -74,9 +80,7 @@ class BaseSoC(SoCCore): # OHCI if with_ohci: - from litex.soc.cores.usb_ohci import USBOHCI - from litex.build.generic_platform import Subsignal, Pins, IOStandard - from litex.soc.integration.soc import SoCRegion + _usb_pmod_ios = [ ("usb_pmod1", 0, Subsignal("dp", Pins("pmod1:0", "pmod1:1", "pmod1:2", "pmod1:3")), @@ -109,6 +113,101 @@ class BaseSoC(SoCCore): self.comb += jtag_pads.tdo.eq(self.cpu.jtag_tdo) platform.add_false_path_constraints(self.crg.cd_sys.clk, jtag_pads.tck) + _hdmi_io = efinix_ti375_c529_dev_kit.hdmi_px("p1") + self.platform.add_extension(_hdmi_io) + self.submodules.videoi2c = I2CMaster(platform.request("hdmi_i2c")) + + self.videoi2c.add_init(addr=0x72>>1, init=[ + # # video input/output mode + (0xD6, 0xC0), + (0x15, 0x01), + (0x16, 0x38), + (0x18, 0xE7), + (0x19, 0x34), + (0x1A, 0x04), + (0x1B, 0xAD), + (0x1C, 0x00), + (0x1D, 0x00), + (0x1E, 0x1C), + (0x1F, 0x1B), + (0x20, 0x1D), + (0x21, 0xDC), + (0x22, 0x04), + (0x23, 0xAD), + (0x24, 0x1F), + (0x25, 0x24), + (0x26, 0x01), + (0x27, 0x35), + (0x28, 0x00), + (0x29, 0x00), + (0x2A, 0x04), + (0x2B, 0xAD), + (0x2C, 0x08), + (0x2D, 0x7C), + (0x2E, 0x1B), + (0x2F, 0x77), + (0x41, 0x10), + (0x48, 0x08), # (right justified + (0x55, 0x00), + (0x56, 0x28), + (0x96, 0xC0), + (0x98, 0x03), + (0x9A, 0xE0), + (0x9C, 0x30), + (0x9D, 0x61), + (0xA2, 0xA4), + (0xA3, 0xA4), + (0xAF, 0x06), + (0xBA, 0x60), + (0xD6, 0xC0), + (0xE0, 0xD0), + (0xDF, 0x01), + (0x9A, 0xE0), + (0xFD, 0xE0), + (0xFE, 0x80), + (0xF9, 0x00), + (0x7F, 0x00), + (0x94, 0x00), + (0xE2, 0x01), + (0x41, 0x10), + ]) + + clk_video = self.crg.cd_video.clk + self.comb += self.cpu.video_clk.eq(self.crg.cd_video.clk) + video_data = platform.request("hdmi_data") + self.specials += DDROutput(i1=Signal(reset=0b0), i2=Signal(reset=0b1), o=video_data.clk, clk=clk_video) + self.specials += DDROutput(i1=self.cpu.video_color_en, i2=self.cpu.video_color_en, o=video_data.de, clk=clk_video) + for i in range(self.cpu.video_color.nbits): + self.specials += DDROutput(i1=self.cpu.video_color[i], i2=self.cpu.video_color[i], o=video_data.d[i], clk=clk_video) + + video_sync = platform.request("hdmi_sync") + self.specials += SDRTristate(io=video_sync.vsync, o=Signal(reset=0b0), oe=self.cpu.video_vsync, i=Signal(), clk=clk_video) + self.specials += SDRTristate(io=video_sync.hsync, o=Signal(reset=0b0), oe=self.cpu.video_hsync, i=Signal(), clk=clk_video) + + _debug_io = [ + ("debug_io", 0, + Subsignal("p0", Pins("pmod2:0")), + Subsignal("p1", Pins("pmod2:1")), + Subsignal("p2", Pins("pmod2:2")), + Subsignal("p3", Pins("pmod2:3")), + Subsignal("p4", Pins("pmod2:4")), + Subsignal("p5", Pins("pmod2:5")), + Subsignal("p6", Pins("pmod2:6")), + Subsignal("p7", Pins("pmod2:7")), + IOStandard("3.3_V_LVCMOS"), + ) + ] + self.platform.add_extension(_debug_io) + debug_io = platform.request("debug_io") + self. comb += debug_io.p0.eq(video_data.clk) + self. comb += debug_io.p1.eq(self.videoi2c._w.fields.scl) + self. comb += debug_io.p2.eq(self.videoi2c._r.fields.sda) + self. comb += debug_io.p3.eq(self.cpu.video_color_en) + self. comb += debug_io.p4.eq(self.cpu.video_vsync) + self. comb += debug_io.p5.eq(self.cpu.video_hsync) + self. comb += debug_io.p6.eq(self.crg.cd_sys.clk) + self.comb += debug_io.p7.eq(self.crg.cd_sys.clk) + # LPDDR4 SDRAM ----------------------------------------------------------------------------- if not self.integrated_main_ram_size: # DRAM / PLL Blocks. From 21e42e5bf653827f2954bb5b9f36acfcaeeb8b24 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Fri, 30 Aug 2024 20:35:38 +0200 Subject: [PATCH 08/10] wip --- .../targets/efinix_ti375_c529_dev_kit.py | 242 ++++++++++-------- 1 file changed, 136 insertions(+), 106 deletions(-) diff --git a/litex_boards/targets/efinix_ti375_c529_dev_kit.py b/litex_boards/targets/efinix_ti375_c529_dev_kit.py index 8441b07..2396f26 100755 --- a/litex_boards/targets/efinix_ti375_c529_dev_kit.py +++ b/litex_boards/targets/efinix_ti375_c529_dev_kit.py @@ -21,6 +21,7 @@ from litex.soc.integration.builder import * from litex.soc.cores.led import LedChaser from litex.soc.interconnect import axi from litex.soc.cores.bitbang import I2CMaster +from litex.soc.cores.pwm import PWM from liteeth.phy.trionrgmii import LiteEthPHYRGMII from litex.build.generic_platform import Subsignal, Pins, Misc, IOStandard @@ -30,16 +31,21 @@ from litex.build.io import DDROutput from litex.build.io import SDRTristate # python3 -m litex_boards.targets.efinix_ti375_c529_dev_kit --cpu-type=vexiiriscv --cpu-variant=debian --update-repo=no --with-jtag-tap --with-sdcard --with-coherent-dma # python3 -m litex.tools.litex_json2dts_linux build/efinix_ti375_c529_dev_kit/csr.json --root-device=mmcblk0p2 > build/efinix_ti375_c529_dev_kit/linux.dts +# timed 5026 gametics in 6544 realtics (26.881113 fps) +# timed 5026 gametics in 3723 realtics (47.249531 fps) + +# TODO efx project ram from 8 words instead of 64, Fanout limit ? # CRG ---------------------------------------------------------------------------------------------- class _CRG(LiteXModule): - def __init__(self, platform, sys_clk_freq): + def __init__(self, platform, sys_clk_freq, cpu_clk_freq): #self.rst = Signal() self.cd_sys = ClockDomain() self.cd_usb = ClockDomain() self.cd_video = ClockDomain() + self.cd_cpu = ClockDomain() # # # @@ -53,11 +59,13 @@ class _CRG(LiteXModule): # You can use CLKOUT0 only for clocks with a maximum frequency of 4x # (integer) of the reference clock. If all your system clocks do not fall within # this range, you should dedicate one unused clock for CLKOUT0. - pll.create_clkout(None, 100e6) - pll.create_clkout(self.cd_sys, sys_clk_freq, with_reset=True, name="cd_sys_clkout") - pll.create_clkout(self.cd_usb, 60e6, margin=0) + pll.create_clkout(self.cd_sys, sys_clk_freq, with_reset=True, name="sys_clk") + pll.create_clkout(self.cd_cpu, cpu_clk_freq, name="cpu_clk") + pll.create_clkout(self.cd_usb, 60e6, margin=0, name="usb_clk") pll.create_clkout(None, 800e6, name="dram_clk") # LPDDR4 ctrl - pll.create_clkout(self.cd_video, 25e6, name ="video_clk") + pll.create_clkout(self.cd_video, 40e6, name ="video_clk") + platform.add_false_path_constraints(self.cd_sys.clk, self.cd_video.clk) + platform.add_false_path_constraints(self.cd_sys.clk, self.cd_usb.clk) # BaseSoC ------------------------------------------------------------------------------------------ @@ -68,16 +76,29 @@ class BaseSoC(SoCCore): }} def __init__(self, sys_clk_freq=100e6, + cpu_clk_freq=100e6, with_ohci=False, **kwargs): platform = efinix_ti375_c529_dev_kit.Platform() # CRG -------------------------------------------------------------------------------------- - self.crg = _CRG(platform, sys_clk_freq) + self.crg = _CRG(platform, sys_clk_freq, cpu_clk_freq) + # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on Efinix Ti375 C529 Dev Kit", **kwargs) + self.fan_pwm = PWM( + pwm=platform.request("fan_speed_control", 0), + with_csr = True, + default_enable = 1, + default_width= 0x800, + default_period = 0xFFF + ) + + if hasattr(self.cpu, "cpu_clk"): + self.comb += self.cpu.cpu_clk.eq(self.crg.cd_cpu.clk) + # OHCI if with_ohci: @@ -113,100 +134,92 @@ class BaseSoC(SoCCore): self.comb += jtag_pads.tdo.eq(self.cpu.jtag_tdo) platform.add_false_path_constraints(self.crg.cd_sys.clk, jtag_pads.tck) - _hdmi_io = efinix_ti375_c529_dev_kit.hdmi_px("p1") - self.platform.add_extension(_hdmi_io) - self.submodules.videoi2c = I2CMaster(platform.request("hdmi_i2c")) + if hasattr(self.cpu, "video_clk"): + _hdmi_io = efinix_ti375_c529_dev_kit.hdmi_px("p1") + self.platform.add_extension(_hdmi_io) + self.submodules.videoi2c = I2CMaster(platform.request("hdmi_i2c")) - self.videoi2c.add_init(addr=0x72>>1, init=[ - # # video input/output mode - (0xD6, 0xC0), - (0x15, 0x01), - (0x16, 0x38), - (0x18, 0xE7), - (0x19, 0x34), - (0x1A, 0x04), - (0x1B, 0xAD), - (0x1C, 0x00), - (0x1D, 0x00), - (0x1E, 0x1C), - (0x1F, 0x1B), - (0x20, 0x1D), - (0x21, 0xDC), - (0x22, 0x04), - (0x23, 0xAD), - (0x24, 0x1F), - (0x25, 0x24), - (0x26, 0x01), - (0x27, 0x35), - (0x28, 0x00), - (0x29, 0x00), - (0x2A, 0x04), - (0x2B, 0xAD), - (0x2C, 0x08), - (0x2D, 0x7C), - (0x2E, 0x1B), - (0x2F, 0x77), - (0x41, 0x10), - (0x48, 0x08), # (right justified - (0x55, 0x00), - (0x56, 0x28), - (0x96, 0xC0), - (0x98, 0x03), - (0x9A, 0xE0), - (0x9C, 0x30), - (0x9D, 0x61), - (0xA2, 0xA4), - (0xA3, 0xA4), - (0xAF, 0x06), - (0xBA, 0x60), - (0xD6, 0xC0), - (0xE0, 0xD0), - (0xDF, 0x01), - (0x9A, 0xE0), - (0xFD, 0xE0), - (0xFE, 0x80), - (0xF9, 0x00), - (0x7F, 0x00), - (0x94, 0x00), - (0xE2, 0x01), - (0x41, 0x10), - ]) + self.videoi2c.add_init(addr=0x72>>1, init=[ + # # video input/output mode + (0xD6, 0xC0), + (0x15, 0x01), + (0x16, 0x38), + (0x18, 0xE7), + (0x19, 0x34), + (0x1A, 0x04), + (0x1B, 0xAD), + (0x1C, 0x00), + (0x1D, 0x00), + (0x1E, 0x1C), + (0x1F, 0x1B), + (0x20, 0x1D), + (0x21, 0xDC), + (0x22, 0x04), + (0x23, 0xAD), + (0x24, 0x1F), + (0x25, 0x24), + (0x26, 0x01), + (0x27, 0x35), + (0x28, 0x00), + (0x29, 0x00), + (0x2A, 0x04), + (0x2B, 0xAD), + (0x2C, 0x08), + (0x2D, 0x7C), + (0x2E, 0x1B), + (0x2F, 0x77), + (0x41, 0x10), + (0x48, 0x08), # (right justified + (0x55, 0x00), + (0x56, 0x28), + (0x96, 0xC0), + (0x98, 0x03), + (0x9A, 0xE0), + (0x9C, 0x30), + (0x9D, 0x61), + (0xA2, 0xA4), + (0xA3, 0xA4), + (0xAF, 0x06), + (0xBA, 0x60), + (0xD6, 0xC0), + (0xE0, 0xD0), + (0xDF, 0x01), + (0x9A, 0xE0), + (0xFD, 0xE0), + (0xFE, 0x80), + (0xF9, 0x00), + (0x7F, 0x00), + (0x94, 0x00), + (0xE2, 0x01), + (0x41, 0x10), + ]) - clk_video = self.crg.cd_video.clk - self.comb += self.cpu.video_clk.eq(self.crg.cd_video.clk) - video_data = platform.request("hdmi_data") - self.specials += DDROutput(i1=Signal(reset=0b0), i2=Signal(reset=0b1), o=video_data.clk, clk=clk_video) - self.specials += DDROutput(i1=self.cpu.video_color_en, i2=self.cpu.video_color_en, o=video_data.de, clk=clk_video) - for i in range(self.cpu.video_color.nbits): - self.specials += DDROutput(i1=self.cpu.video_color[i], i2=self.cpu.video_color[i], o=video_data.d[i], clk=clk_video) + clk_video = self.crg.cd_video.clk + self.comb += self.cpu.video_clk.eq(self.crg.cd_video.clk) + video_data = platform.request("hdmi_data") + self.specials += DDROutput(i1=Signal(reset=0b0), i2=Signal(reset=0b1), o=video_data.clk, clk=clk_video) + self.specials += DDROutput(i1=self.cpu.video_color_en, i2=self.cpu.video_color_en, o=video_data.de, clk=clk_video) + for i in range(self.cpu.video_color.nbits): + self.specials += DDROutput(i1=self.cpu.video_color[i], i2=self.cpu.video_color[i], o=video_data.d[i], clk=clk_video) - video_sync = platform.request("hdmi_sync") - self.specials += SDRTristate(io=video_sync.vsync, o=Signal(reset=0b0), oe=self.cpu.video_vsync, i=Signal(), clk=clk_video) - self.specials += SDRTristate(io=video_sync.hsync, o=Signal(reset=0b0), oe=self.cpu.video_hsync, i=Signal(), clk=clk_video) + video_sync = platform.request("hdmi_sync") + self.specials += SDRTristate(io=video_sync.vsync, o=Signal(reset=0b0), oe=self.cpu.video_vsync, i=Signal(), clk=clk_video) + self.specials += SDRTristate(io=video_sync.hsync, o=Signal(reset=0b0), oe=self.cpu.video_hsync, i=Signal(), clk=clk_video) + + # _debug_io = [ + # ("debug_io", 0, + # Subsignal("p0", Pins("pmod2:0")), + # Subsignal("p1", Pins("pmod2:1")), + # Subsignal("p2", Pins("pmod2:2")), + # Subsignal("p3", Pins("pmod2:3")), + # Subsignal("p4", Pins("pmod2:4")), + # Subsignal("p5", Pins("pmod2:5")), + # Subsignal("p6", Pins("pmod2:6")), + # Subsignal("p7", Pins("pmod2:7")), + # IOStandard("3.3_V_LVCMOS"), + # ) + # ] - _debug_io = [ - ("debug_io", 0, - Subsignal("p0", Pins("pmod2:0")), - Subsignal("p1", Pins("pmod2:1")), - Subsignal("p2", Pins("pmod2:2")), - Subsignal("p3", Pins("pmod2:3")), - Subsignal("p4", Pins("pmod2:4")), - Subsignal("p5", Pins("pmod2:5")), - Subsignal("p6", Pins("pmod2:6")), - Subsignal("p7", Pins("pmod2:7")), - IOStandard("3.3_V_LVCMOS"), - ) - ] - self.platform.add_extension(_debug_io) - debug_io = platform.request("debug_io") - self. comb += debug_io.p0.eq(video_data.clk) - self. comb += debug_io.p1.eq(self.videoi2c._w.fields.scl) - self. comb += debug_io.p2.eq(self.videoi2c._r.fields.sda) - self. comb += debug_io.p3.eq(self.cpu.video_color_en) - self. comb += debug_io.p4.eq(self.cpu.video_vsync) - self. comb += debug_io.p5.eq(self.cpu.video_hsync) - self. comb += debug_io.p6.eq(self.crg.cd_sys.clk) - self.comb += debug_io.p7.eq(self.crg.cd_sys.clk) # LPDDR4 SDRAM ----------------------------------------------------------------------------- if not self.integrated_main_ram_size: @@ -221,6 +234,19 @@ class BaseSoC(SoCCore): data_width = 512 axi_bus = axi.AXIInterface(data_width=data_width, address_width=30, id_width=8) # 256MB. + + # self.platform.add_extension(_debug_io) + # debug_io = platform.request("debug_io") + # self.sync += debug_io.p0.eq(axi_bus.ar.valid) + # self.sync += debug_io.p1.eq(axi_bus.r.valid) + # self.sync += debug_io.p2.eq(axi_bus.ar.ready) + # self.sync += debug_io.p3.eq(axi_bus.r.ready) + # self.sync += debug_io.p4.eq(axi_bus.aw.valid) + # self.sync += debug_io.p5.eq(axi_bus.b.valid) + # self.sync += debug_io.p6.eq(axi_bus.aw.ready) + # self.sync += debug_io.p7.eq(axi_bus.b.ready) + + axi_clk = self.crg.cd_cpu.clk.name_override class DRAMXMLBlock(InterfaceWriterXMLBlock): @staticmethod def generate(root, namespaces): @@ -248,7 +274,7 @@ class BaseSoC(SoCCore): axi_target0 = et.SubElement(ddr, "efxpt:axi_target0",is_axi_width_256="false", is_axi_enable="true") gen_pin_target0 = et.SubElement(axi_target0, "efxpt:gen_pin_axi") - et.SubElement(gen_pin_target0, "efxpt:pin", name="cd_sys_clkout", type_name=f"ACLK_0", is_bus="false", is_clk="true", is_clk_invert="false") + et.SubElement(gen_pin_target0, "efxpt:pin", name=axi_clk, type_name=f"ACLK_0", is_bus="false", is_clk="true", is_clk_invert="false") et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_ar_apcmd", type_name="ARAPCMD_0", is_bus="false") et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_ar_ready", type_name="ARREADY_0", is_bus="false") et.SubElement(gen_pin_target0, "efxpt:pin", name="ddr0_ar_valid", type_name="ARVALID_0", is_bus="false") @@ -291,7 +317,7 @@ class BaseSoC(SoCCore): axi_target1 = et.SubElement(ddr, "efxpt:axi_target1",is_axi_width_256="false", is_axi_enable="false") gen_pin_target1 = et.SubElement(axi_target1, "efxpt:gen_pin_axi") - et.SubElement(gen_pin_target1, "efxpt:pin", name="cd_sys_clkout", type_name=f"ACLK_1", is_bus="false", is_clk="true", is_clk_invert="false") + et.SubElement(gen_pin_target1, "efxpt:pin", name=axi_clk, type_name=f"ACLK_1", is_bus="false", is_clk="true", is_clk_invert="false") et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_ar_apcmd", type_name="ARAPCMD_1", is_bus="false") et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_ar_ready", type_name="ARREADY_1", is_bus="false") et.SubElement(gen_pin_target1, "efxpt:pin", name="ddr1_ar_valid", type_name="ARVALID_1", is_bus="false") @@ -530,6 +556,13 @@ class BaseSoC(SoCCore): Subsignal("resetn", Pins(1)), )] + if hasattr(self.cpu, "add_memory_buses"): + self.cpu.add_memory_buses(address_width = 32, data_width = data_width) + + assert len(self.cpu.memory_buses) == 1 + mbus = self.cpu.memory_buses[0] + self.comb +=mbus.connect(axi_bus) + io = platform.add_iface_ios(ios) self.comb += [ io.ar_valid.eq(axi_bus.ar.valid), @@ -552,7 +585,7 @@ class BaseSoC(SoCCore): io.aw_lock.eq(axi_bus.aw.lock), io.aw_cache.eq(axi_bus.aw.cache), io.aw_qos.eq(axi_bus.aw.qos), - io.aw_allstrb.eq(0), + io.aw_allstrb.eq(0 if not hasattr(self.cpu, "mBus_awallStrb") else self.cpu.mBus_awallStrb), io.aw_apcmd.eq(0), io.awcobuf.eq(0), io.w_valid.eq(axi_bus.w.valid), @@ -572,13 +605,6 @@ class BaseSoC(SoCCore): axi_bus.r.last.eq(io.r_last), io.resetn.eq(~self.crg.cd_sys.rst), ] - - if hasattr(self.cpu, "add_memory_buses"): - self.cpu.add_memory_buses(address_width = 32, data_width = data_width) - - assert len(self.cpu.memory_buses) == 1 - mbus = self.cpu.memory_buses[0] - self.comb +=mbus.connect(axi_bus) cfgs = [(f"cfg", 0, Subsignal("start", Pins(1)), @@ -612,6 +638,8 @@ class BaseSoC(SoCCore): def main(): from litex.build.parser import LiteXArgumentParser parser = LiteXArgumentParser(platform=efinix_ti375_c529_dev_kit.Platform, description="LiteX SoC on Efinix Ti375 C529 Dev Kit.") + parser.add_target_argument("--sys-clk-freq", default=100e6, type=float, help="System clock frequency.") + parser.add_target_argument("--cpu-clk-freq", default=100e6, type=float, help="System clock frequency.") parser.add_target_argument("--with-ohci", action="store_true", help="Enable USB OHCI.") sdopts = parser.target_group.add_mutually_exclusive_group() sdopts.add_argument("--with-spi-sdcard", action="store_true", help="Enable SPI-mode SDCard support.") @@ -619,6 +647,8 @@ def main(): args = parser.parse_args() soc = BaseSoC( + sys_clk_freq = args.sys_clk_freq, + cpu_clk_freq = args.cpu_clk_freq, with_ohci = args.with_ohci, **parser.soc_argdict) if args.with_spi_sdcard: From b893374cdf86f3a6e92493ee296a3feb18deb7ad Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Thu, 5 Sep 2024 15:28:07 +0200 Subject: [PATCH 09/10] Fix ti60 dev kit spi-sdcard voltage --- litex_boards/platforms/efinix_titanium_ti60_f225_dev_kit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/litex_boards/platforms/efinix_titanium_ti60_f225_dev_kit.py b/litex_boards/platforms/efinix_titanium_ti60_f225_dev_kit.py index e5a403f..a1620e9 100644 --- a/litex_boards/platforms/efinix_titanium_ti60_f225_dev_kit.py +++ b/litex_boards/platforms/efinix_titanium_ti60_f225_dev_kit.py @@ -23,7 +23,7 @@ _io = [ Subsignal("mosi", Pins("C12"), Misc("WEAK_PULLUP")), Subsignal("cs_n", Pins("A12"), Misc("WEAK_PULLUP")), Subsignal("miso", Pins("B14"), Misc("WEAK_PULLUP")), - IOStandard("1.8_V_LVCMOS"), + IOStandard("3.3_V_LVCMOS"), ), ("sdcard", 0, Subsignal("data", Pins("B14 A14 D12 A12"), Misc("WEAK_PULLUP")), From d209f64a450d2ffbf7a44afab68143ed93a5373a Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Thu, 5 Sep 2024 15:30:55 +0200 Subject: [PATCH 10/10] Add efinix_ti375_c529_dev_kit support --- .../platforms/efinix_ti375_c529_dev_kit.py | 24 +++- .../targets/efinix_ti375_c529_dev_kit.py | 123 ++++++++---------- 2 files changed, 70 insertions(+), 77 deletions(-) diff --git a/litex_boards/platforms/efinix_ti375_c529_dev_kit.py b/litex_boards/platforms/efinix_ti375_c529_dev_kit.py index 40f33a7..8dccf5f 100644 --- a/litex_boards/platforms/efinix_ti375_c529_dev_kit.py +++ b/litex_boards/platforms/efinix_ti375_c529_dev_kit.py @@ -32,17 +32,27 @@ _io = [ # SD-Card ("spisdcard", 0, Subsignal("clk", Pins("C9")), - Subsignal("mosi", Pins("C10"), Misc("WEAK_PULLUP")), - Subsignal("cs_n", Pins("A9"), Misc("WEAK_PULLUP")), - Subsignal("miso", Pins("B9"), Misc("WEAK_PULLUP")), + Subsignal("mosi", Pins("C10")), + Subsignal("cs_n", Pins("A9")), + Subsignal("miso", Pins("B9")), IOStandard("3.3_V_LVCMOS"), ), ("sdcard", 0, - Subsignal("data", Pins("B9 B10 A8 A9"), Misc("WEAK_PULLUP")), - Subsignal("cmd", Pins("C10"), Misc("WEAK_PULLUP")), - Subsignal("clk", Pins("C9")), - IOStandard("3.3_V_LVCMOS"), + Subsignal("data", Pins("B9 B10 A8 A9")), + Subsignal("cmd", Pins("C10")), + Subsignal("clk", Pins("C9")) , #, Misc("SLEWRATE=1"), Misc("DRIVE_STRENGTH=16") + IOStandard("3.3_V_LVTTL"), ), + + # SD-Card through PMOD2 + # ("sdcard", 0, + # Subsignal("data", Pins("F13 F14 E11 E14"), Misc("WEAK_PULLUP")), + # Subsignal("cmd", Pins("E16"), Misc("WEAK_PULLUP")), + # Subsignal("clk", Pins("E15")), + # IOStandard("3.3_V_LVCMOS"), + # ), + + ("fan_speed_control", 0, Pins("T19"), IOStandard("3.3_V_LVCMOS")), ] diff --git a/litex_boards/targets/efinix_ti375_c529_dev_kit.py b/litex_boards/targets/efinix_ti375_c529_dev_kit.py index 2396f26..028693e 100755 --- a/litex_boards/targets/efinix_ti375_c529_dev_kit.py +++ b/litex_boards/targets/efinix_ti375_c529_dev_kit.py @@ -28,14 +28,12 @@ from litex.build.generic_platform import Subsignal, Pins, Misc, IOStandard from litex.soc.cores.usb_ohci import USBOHCI from litex.soc.integration.soc import SoCRegion from litex.build.io import DDROutput +from litex.build.io import SDROutput from litex.build.io import SDRTristate -# python3 -m litex_boards.targets.efinix_ti375_c529_dev_kit --cpu-type=vexiiriscv --cpu-variant=debian --update-repo=no --with-jtag-tap --with-sdcard --with-coherent-dma -# python3 -m litex.tools.litex_json2dts_linux build/efinix_ti375_c529_dev_kit/csr.json --root-device=mmcblk0p2 > build/efinix_ti375_c529_dev_kit/linux.dts -# timed 5026 gametics in 6544 realtics (26.881113 fps) -# timed 5026 gametics in 3723 realtics (47.249531 fps) - -# TODO efx project ram from 8 words instead of 64, Fanout limit ? - +# Full stream debian demo : +# --cpu-type=vexiiriscv --cpu-variant=debian --update-repo=no --with-jtag-tap --with-sdcard --with-coherent-dma --with-ohci --vexii-video "name=video" +# --vexii-args="--fetch-l1-hardware-prefetch=nl --fetch-l1-refill-count=2 --fetch-l1-mem-data-width-min=128 --lsu-l1-mem-data-width-min=128 --lsu-software-prefetch --lsu-hardware-prefetch rpt --performance-counters 9 --lsu-l1-store-buffer-ops=32 --lsu-l1-refill-count 4 --lsu-l1-writeback-count 4 --lsu-l1-store-buffer-slots=4 --relaxed-div" +# --l2-bytes=524288 --sys-clk-freq 100000000 --cpu-clk-freq 200000000 --with-cpu-clk --bus-standard axi-lite --cpu-count=4 --build # CRG ---------------------------------------------------------------------------------------------- @@ -59,12 +57,14 @@ class _CRG(LiteXModule): # You can use CLKOUT0 only for clocks with a maximum frequency of 4x # (integer) of the reference clock. If all your system clocks do not fall within # this range, you should dedicate one unused clock for CLKOUT0. - pll.create_clkout(self.cd_sys, sys_clk_freq, with_reset=True, name="sys_clk") - pll.create_clkout(self.cd_cpu, cpu_clk_freq, name="cpu_clk") - pll.create_clkout(self.cd_usb, 60e6, margin=0, name="usb_clk") - pll.create_clkout(None, 800e6, name="dram_clk") # LPDDR4 ctrl - pll.create_clkout(self.cd_video, 40e6, name ="video_clk") - platform.add_false_path_constraints(self.cd_sys.clk, self.cd_video.clk) + pll.create_clkout(self.cd_sys, sys_clk_freq, with_reset=True) + pll.create_clkout(self.cd_cpu, cpu_clk_freq) + pll.create_clkout(self.cd_usb, 60e6, margin=0) + pll.create_clkout(None, 800e6) # LPDDR4 ctrl + pll.create_clkout(self.cd_video, 40e6) + platform.add_false_path_constraints(self.cd_cpu.clk, self.cd_usb.clk) + platform.add_false_path_constraints(self.cd_cpu.clk, self.cd_sys.clk) + platform.add_false_path_constraints(self.cd_cpu.clk, self.cd_video.clk) platform.add_false_path_constraints(self.cd_sys.clk, self.cd_usb.clk) @@ -106,7 +106,7 @@ class BaseSoC(SoCCore): ("usb_pmod1", 0, Subsignal("dp", Pins("pmod1:0", "pmod1:1", "pmod1:2", "pmod1:3")), Subsignal("dm", Pins("pmod1:4", "pmod1:5", "pmod1:6", "pmod1:7")), - IOStandard("3.3_V_LVCMOS"), + IOStandard("3.3_V_LVCMOS"), Misc("DRIVE_STRENGTH=8"), ) ] platform.add_extension(_usb_pmod_ios) @@ -225,10 +225,6 @@ class BaseSoC(SoCCore): if not self.integrated_main_ram_size: # DRAM / PLL Blocks. # ------------------ - dram_pll_refclk = platform.request("dram_pll_refclk") - platform.toolchain.excluded_ios.append(dram_pll_refclk) - self.platform.toolchain.additional_sdc_commands.append(f"create_clock -period {1e9/100e6} dram_pll_refclk") - from litex.build.efinix import InterfaceWriterBlock, InterfaceWriterXMLBlock import xml.etree.ElementTree as et @@ -261,15 +257,6 @@ class BaseSoC(SoCCore): physical_rank="1", mem_type="LPDDR4x", mem_density="8G" - # cs_preset_id = "173", - # cs_mem_type = "LPDDR3", - # cs_ctrl_width = "x32", - # cs_dram_width = "x32", - # cs_dram_density = "8G", - # cs_speedbin = "800", - # target0_enable = "true", - # target1_enable = "true", - # ctrl_type = "none" ) axi_target0 = et.SubElement(ddr, "efxpt:axi_target0",is_axi_width_256="false", is_axi_enable="true") @@ -515,44 +502,44 @@ class BaseSoC(SoCCore): # DRAM AXI-Ports. # -------------- ios = [(f"ddr0", 0, - Subsignal("ar_valid", Pins(1)), # - Subsignal("ar_ready", Pins(1)), # - Subsignal("ar_addr", Pins(33)), #32:0] - Subsignal("ar_id", Pins(6)), #5:0] - Subsignal("ar_len", Pins(8)), #7:0] - Subsignal("ar_size", Pins(3)), #2:0] - Subsignal("ar_burst", Pins(2)), #1:0] - Subsignal("ar_lock", Pins(1)), # - Subsignal("ar_apcmd", Pins(1)), # - Subsignal("ar_qos", Pins(1)), # - Subsignal("aw_valid", Pins(1)), # - Subsignal("aw_ready", Pins(1)), # - Subsignal("aw_addr", Pins(33)), #32:0] - Subsignal("aw_id", Pins(6)), #5:0] - Subsignal("aw_len", Pins(8)), #7:0] - Subsignal("aw_size", Pins(3)), #2:0] - Subsignal("aw_burst", Pins(2)), #1:0] - Subsignal("aw_lock", Pins(1)), # - Subsignal("aw_cache", Pins(4)), #3:0] - Subsignal("aw_qos", Pins(1)), # - Subsignal("aw_allstrb", Pins(1)), # - Subsignal("aw_apcmd", Pins(1)), # - Subsignal("awcobuf", Pins(1)), # - Subsignal("w_valid", Pins(1)), # - Subsignal("w_ready", Pins(1)), # - Subsignal("w_data", Pins(data_width)), #512-1:0] - Subsignal("w_strb", Pins(data_width//8)), #64-1:0] - Subsignal("w_last", Pins(1)), # - Subsignal("b_valid", Pins(1)), # - Subsignal("b_ready", Pins(1)), # - Subsignal("b_resp", Pins(1)), #1:0] - Subsignal("b_id", Pins(6)), #5:0] - Subsignal("r_valid", Pins(1)), # - Subsignal("r_ready", Pins(1)), # - Subsignal("r_data", Pins(data_width)), #512-1:0] - Subsignal("r_id", Pins(6)), #5:0] - Subsignal("r_resp", Pins(2)), #1:0] - Subsignal("r_last", Pins(1)), # + Subsignal("ar_valid", Pins(1)), + Subsignal("ar_ready", Pins(1)), + Subsignal("ar_addr", Pins(33)), + Subsignal("ar_id", Pins(6)), + Subsignal("ar_len", Pins(8)), + Subsignal("ar_size", Pins(3)), + Subsignal("ar_burst", Pins(2)), + Subsignal("ar_lock", Pins(1)), + Subsignal("ar_apcmd", Pins(1)), + Subsignal("ar_qos", Pins(1)), + Subsignal("aw_valid", Pins(1)), + Subsignal("aw_ready", Pins(1)), + Subsignal("aw_addr", Pins(33)), + Subsignal("aw_id", Pins(6)), + Subsignal("aw_len", Pins(8)), + Subsignal("aw_size", Pins(3)), + Subsignal("aw_burst", Pins(2)), + Subsignal("aw_lock", Pins(1)), + Subsignal("aw_cache", Pins(4)), + Subsignal("aw_qos", Pins(1)), + Subsignal("aw_allstrb", Pins(1)), + Subsignal("aw_apcmd", Pins(1)), + Subsignal("awcobuf", Pins(1)), + Subsignal("w_valid", Pins(1)), + Subsignal("w_ready", Pins(1)), + Subsignal("w_data", Pins(data_width)), + Subsignal("w_strb", Pins(data_width//8)), + Subsignal("w_last", Pins(1)), + Subsignal("b_valid", Pins(1)), + Subsignal("b_ready", Pins(1)), + Subsignal("b_resp", Pins(1)), + Subsignal("b_id", Pins(6)), + Subsignal("r_valid", Pins(1)), + Subsignal("r_ready", Pins(1)), + Subsignal("r_data", Pins(data_width)), + Subsignal("r_id", Pins(6)), + Subsignal("r_resp", Pins(2)), + Subsignal("r_last", Pins(1)), Subsignal("resetn", Pins(1)), )] @@ -655,6 +642,7 @@ def main(): soc.add_spi_sdcard() if args.with_sdcard: soc.add_sdcard() + builder = Builder(soc, **parser.builder_argdict) if args.build: builder.build(**parser.toolchain_argdict) @@ -663,10 +651,5 @@ def main(): prog = soc.platform.create_programmer() prog.load_bitstream(builder.get_bitstream_filename(mode="sram")) - # if args.flash: - # from litex.build.openfpgaloader import OpenFPGALoader - # prog = OpenFPGALoader("titanium_ti375_c529") - # prog.flash(0, builder.get_bitstream_filename(mode="flash", ext=".hex")) # FIXME - if __name__ == "__main__": main()