Merge pull request #52 from antmicro/jboc/mercury-xu5
add Enclustra Mercury XU5 board
This commit is contained in:
commit
dc1371108d
|
@ -0,0 +1,143 @@
|
|||
from litex.build.generic_platform import *
|
||||
from litex.build.xilinx import XilinxPlatform, VivadoProgrammer
|
||||
|
||||
# IOs ----------------------------------------------------------------------------------------------
|
||||
|
||||
_io = [
|
||||
('clk100', 0,
|
||||
Subsignal('n', Pins('AD4'), IOStandard('DIFF_SSTL12_DCI')),
|
||||
Subsignal('p', Pins('AD5'), IOStandard('DIFF_SSTL12_DCI')),
|
||||
),
|
||||
|
||||
('clk100_gtr', 0,
|
||||
Subsignal('p', Pins('C21'), IOStandard('DIFF_SSTL12')),
|
||||
Subsignal('n', Pins('C22'), IOStandard('DIFF_SSTL12')),
|
||||
),
|
||||
|
||||
('clk27_gtr', 0,
|
||||
Subsignal('p', Pins('A21'), IOStandard('DIFF_SSTL12')),
|
||||
Subsignal('n', Pins('A22'), IOStandard('DIFF_SSTL12')),
|
||||
),
|
||||
|
||||
('clk33', 0, Pins('AD4'), IOStandard('SSTL12')),
|
||||
|
||||
('cpu_reset', 0, Pins('N19'), IOStandard('LVCMOS33')),
|
||||
|
||||
('user_led', 0, Pins('H2'), IOStandard('LVCMOS18')),
|
||||
('user_led', 1, Pins('P9'), IOStandard('LVCMOS18')),
|
||||
('user_led', 2, Pins('K5'), IOStandard('LVCMOS18')),
|
||||
|
||||
('serial', 0,
|
||||
Subsignal('rx', Pins('AA10')), # Module connector A: A60 (Meccury PE1: "IO B" connector 32)
|
||||
Subsignal('tx', Pins('AA11')), # Module connector A: A58 (Meccury PE1: "IO B" connector 31)
|
||||
IOStandard('LVCMOS33'),
|
||||
),
|
||||
|
||||
('ddram', 0, # TODO: remove Misc with default settings
|
||||
Subsignal('a', Pins(
|
||||
'AC4 AC3 AB4 AB3 AB2 AC2 AB1 AC1',
|
||||
'AB5 AG4 AH4 AG3 AH3 AE3'), IOStandard('SSTL12_DCI'),
|
||||
Misc('OUTPUT_IMPEDANCE=RDRV_40_40'),
|
||||
Misc('DATA_RATE=DDR'),
|
||||
),
|
||||
Subsignal('we_n', Pins('AF3'), IOStandard('SSTL12_DCI'), # A14
|
||||
Misc('OUTPUT_IMPEDANCE=RDRV_40_40'),
|
||||
Misc('DATA_RATE=DDR'),
|
||||
),
|
||||
Subsignal('cas_n', Pins('AE2'), IOStandard('SSTL12_DCI'), # A15
|
||||
Misc('OUTPUT_IMPEDANCE=RDRV_40_40'),
|
||||
Misc('DATA_RATE=DDR'),
|
||||
),
|
||||
Subsignal('ras_n', Pins('AF2'), IOStandard('SSTL12_DCI'), # A16
|
||||
Misc('OUTPUT_IMPEDANCE=RDRV_40_40'),
|
||||
Misc('DATA_RATE=DDR'),
|
||||
),
|
||||
Subsignal('ba', Pins('AH1 AF1'), IOStandard('SSTL12_DCI'),
|
||||
Misc('OUTPUT_IMPEDANCE=RDRV_40_40'),
|
||||
Misc('DATA_RATE=DDR'),
|
||||
),
|
||||
# Subsignal('bg', Pins('AG1 AD9'), IOStandard('SSTL12_DCI'),
|
||||
Subsignal('bg', Pins('AG1'), IOStandard('SSTL12_DCI'),
|
||||
Misc('OUTPUT_IMPEDANCE=RDRV_40_40'),
|
||||
Misc('DATA_RATE=DDR'),
|
||||
),
|
||||
Subsignal('cs_n', Pins('AH9'), IOStandard('SSTL12_DCI'),
|
||||
Misc('OUTPUT_IMPEDANCE=RDRV_40_40'),
|
||||
Misc('DATA_RATE=SDR'),
|
||||
),
|
||||
Subsignal('act_n', Pins('AH2'), IOStandard('SSTL12_DCI'),
|
||||
Misc('OUTPUT_IMPEDANCE=RDRV_40_40'),
|
||||
Misc('DATA_RATE=DDR'),
|
||||
),
|
||||
Subsignal('dm', Pins('AC9 AG9'), IOStandard('POD12_DCI'),
|
||||
Misc('OUTPUT_IMPEDANCE=RDRV_40_40'),
|
||||
# Misc('EQUALIZATION=EQ_LEVEL2'),
|
||||
Misc('DATA_RATE=DDR'),
|
||||
),
|
||||
Subsignal('dq', Pins(
|
||||
'AB6 AC6 AE9 AE8 AB8 AC8 AB7 AC7',
|
||||
'AE5 AF5 AF8 AG8 AH8 AH7 AF7 AF6'), IOStandard('POD12_DCI'),
|
||||
Misc('PRE_EMPHASIS=RDRV_240'),
|
||||
Misc('EQUALIZATION=EQ_LEVEL2'),
|
||||
Misc('OUTPUT_IMPEDANCE=RDRV_40_40'),
|
||||
Misc('DATA_RATE=DDR'),
|
||||
Misc('ODT=RTT_40'),
|
||||
),
|
||||
Subsignal('dqs_p', Pins('AD7 AG6'), IOStandard('DIFF_POD12_DCI'),
|
||||
Misc('PRE_EMPHASIS=RDRV_240'),
|
||||
Misc('EQUALIZATION=EQ_LEVEL2'),
|
||||
Misc('OUTPUT_IMPEDANCE=RDRV_40_40'),
|
||||
Misc('DATA_RATE=DDR'),
|
||||
Misc('ODT=RTT_40'),
|
||||
),
|
||||
Subsignal('dqs_n', Pins('AE7 AG5'), IOStandard('DIFF_POD12_DCI'),
|
||||
Misc('PRE_EMPHASIS=RDRV_240'),
|
||||
Misc('EQUALIZATION=EQ_LEVEL2'),
|
||||
Misc('OUTPUT_IMPEDANCE=RDRV_40_40'),
|
||||
Misc('DATA_RATE=DDR'),
|
||||
Misc('ODT=RTT_40'),
|
||||
),
|
||||
Subsignal('clk_p', Pins('AD2'), IOStandard('DIFF_SSTL12_DCI'),
|
||||
Misc('OUTPUT_IMPEDANCE=RDRV_40_40'),
|
||||
Misc('DATA_RATE=DDR'),
|
||||
),
|
||||
Subsignal('clk_n', Pins('AD1'), IOStandard('DIFF_SSTL12_DCI'),
|
||||
Misc('OUTPUT_IMPEDANCE=RDRV_40_40'),
|
||||
Misc('DATA_RATE=DDR'),
|
||||
),
|
||||
Subsignal('cke', Pins('AH6'), IOStandard('SSTL12_DCI'),
|
||||
Misc('OUTPUT_IMPEDANCE=RDRV_40_40'),
|
||||
Misc('DATA_RATE=DDR'),
|
||||
),
|
||||
Subsignal('odt', Pins('AE4'), IOStandard('SSTL12_DCI'),
|
||||
Misc('OUTPUT_IMPEDANCE=RDRV_40_40'),
|
||||
Misc('DATA_RATE=DDR'),
|
||||
),
|
||||
Subsignal('reset_n', Pins('G4'), IOStandard('LVCMOS18'),
|
||||
Misc('DRIVE=8'),
|
||||
),
|
||||
Misc('SLEW=FAST'),
|
||||
),
|
||||
]
|
||||
|
||||
# Connectors ---------------------------------------------------------------------------------------
|
||||
|
||||
_connectors = []
|
||||
|
||||
# Platform -----------------------------------------------------------------------------------------
|
||||
|
||||
class Platform(XilinxPlatform):
|
||||
default_clk_name = 'clk100'
|
||||
default_clk_period = 1e9/100e6
|
||||
|
||||
def __init__(self):
|
||||
XilinxPlatform.__init__(self, 'xczu2eg-sfvc784-1-i', _io, _connectors, toolchain='vivado')
|
||||
|
||||
def create_programmer(self):
|
||||
return VivadoProgrammer()
|
||||
|
||||
def do_finalize(self, fragment):
|
||||
XilinxPlatform.do_finalize(self, fragment)
|
||||
self.add_platform_command('set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN ENABLE [current_design]')
|
||||
self.add_platform_command('set_property BITSTREAM.CONFIG.UNUSEDPIN PULLNONE [current_design]')
|
||||
self.add_platform_command('set_property INTERNAL_VREF 0.600 [get_iobanks 64]')
|
|
@ -0,0 +1,111 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
|
||||
from migen import *
|
||||
from migen.genlib.io import CRG
|
||||
|
||||
from litex_boards.platforms import mercury_xu5
|
||||
|
||||
from litex.soc.cores.clock import *
|
||||
from litex.soc.integration.soc_sdram import *
|
||||
from litex.soc.integration.builder import *
|
||||
|
||||
from litedram.modules import MT40A256M16
|
||||
from litedram.phy import usddrphy
|
||||
|
||||
# CRG ----------------------------------------------------------------------------------------------
|
||||
|
||||
class _CRG(Module):
|
||||
def __init__(self, platform, sys_clk_freq):
|
||||
self.clock_domains.cd_sys = ClockDomain()
|
||||
self.clock_domains.cd_sys4x = ClockDomain(reset_less=True)
|
||||
self.clock_domains.cd_pll4x = ClockDomain(reset_less=True)
|
||||
self.clock_domains.cd_clk400 = ClockDomain()
|
||||
self.clock_domains.cd_ic = ClockDomain()
|
||||
|
||||
self.submodules.pll = pll = USMMCM(speedgrade=-1)
|
||||
pll.register_clkin(platform.request("clk100"), 100e6)
|
||||
|
||||
pll.create_clkout(self.cd_pll4x, sys_clk_freq*4, buf=None, with_reset=False)
|
||||
pll.create_clkout(self.cd_clk400, 400e6, with_reset=False)
|
||||
|
||||
self.specials += [
|
||||
Instance("BUFGCE_DIV", name="main_bufgce_div",
|
||||
p_BUFGCE_DIVIDE=4,
|
||||
i_CE=1, i_I=self.cd_pll4x.clk, o_O=self.cd_sys.clk),
|
||||
Instance("BUFGCE", name="main_bufgce",
|
||||
i_CE=1, i_I=self.cd_pll4x.clk, o_O=self.cd_sys4x.clk),
|
||||
AsyncResetSynchronizer(self.cd_clk400, ~pll.locked),
|
||||
]
|
||||
|
||||
ic_reset_counter = Signal(max=64, reset=63)
|
||||
ic_reset = Signal(reset=1)
|
||||
self.sync.clk400 += \
|
||||
If(ic_reset_counter != 0,
|
||||
ic_reset_counter.eq(ic_reset_counter - 1)
|
||||
).Else(
|
||||
ic_reset.eq(0)
|
||||
)
|
||||
ic_rdy = Signal()
|
||||
ic_rdy_counter = Signal(max=64, reset=63)
|
||||
self.cd_sys.rst.reset = 1
|
||||
self.comb += self.cd_ic.clk.eq(self.cd_sys.clk)
|
||||
self.sync.ic += [
|
||||
If(ic_rdy,
|
||||
If(ic_rdy_counter != 0,
|
||||
ic_rdy_counter.eq(ic_rdy_counter - 1)
|
||||
).Else(
|
||||
self.cd_sys.rst.eq(0)
|
||||
)
|
||||
)
|
||||
]
|
||||
self.specials += [
|
||||
Instance("IDELAYCTRL", p_SIM_DEVICE="ULTRASCALE",
|
||||
i_REFCLK=ClockSignal("clk400"), i_RST=ic_reset,
|
||||
o_RDY=ic_rdy),
|
||||
AsyncResetSynchronizer(self.cd_ic, ic_reset)
|
||||
]
|
||||
|
||||
# BaseSoC ------------------------------------------------------------------------------------------
|
||||
|
||||
class BaseSoC(SoCSDRAM):
|
||||
def __init__(self, sys_clk_freq=int(100e6), **kwargs):
|
||||
platform = mercury_xu5.Platform()
|
||||
|
||||
# SoCSDRAM ---------------------------------------------------------------------------------
|
||||
SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs)
|
||||
|
||||
# CRG --------------------------------------------------------------------------------------
|
||||
self.submodules.crg = _CRG(platform, sys_clk_freq)
|
||||
|
||||
# DDR4 SDRAM -------------------------------------------------------------------------------
|
||||
if not self.integrated_main_ram_size:
|
||||
self.submodules.ddrphy = usddrphy.USDDRPHY(platform.request("ddram"),
|
||||
memtype = "DDR4",
|
||||
sim_device = "ULTRASCALE_PLUS",
|
||||
iodelay_clk_freq = 400e6,
|
||||
cmd_latency = 1,
|
||||
sys_clk_freq = sys_clk_freq)
|
||||
self.add_csr("ddrphy")
|
||||
self.add_constant("USDDRPHY", None)
|
||||
sdram_module = MT40A256M16(sys_clk_freq, "1:4")
|
||||
self.register_sdram(self.ddrphy,
|
||||
geom_settings = sdram_module.geom_settings,
|
||||
timing_settings = sdram_module.timing_settings)
|
||||
|
||||
# Build --------------------------------------------------------------------------------------------
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="LiteX SoC on Enclustra's Mercury XU5")
|
||||
builder_args(parser)
|
||||
soc_sdram_args(parser)
|
||||
args = parser.parse_args()
|
||||
|
||||
soc = BaseSoC(**soc_sdram_argdict(args))
|
||||
builder = Builder(soc, **builder_argdict(args))
|
||||
builder.build()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in New Issue