Newer
Older
#!/usr/bin/env python3
# This file is Copyright (c) 2020 Fei Gao <feig@princeton.edu>
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# License: BSD
import argparse
from migen import *
from litex.boards.platforms import vcu118
from litex.soc.cores.clock import *
from litex.soc.integration.soc_sdram import *
from litex.soc.integration.builder import *
from litedram.modules import EDY4016A
from litedram.phy import uspddrphy
from liteeth.phy.ku_1000basex import KU_1000BASEX
from liteeth.mac import LiteEthMAC
# 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_clk200 = ClockDomain()
self.clock_domains.cd_ic = ClockDomain()
# # #
self.submodules.pll = pll = USMMCM(speedgrade=-2)
self.comb += pll.reset.eq(platform.request("cpu_reset"))
self.clock_domains.cd_pll4x = ClockDomain(reset_less=True)
pll.register_clkin(platform.request("clk125"), 125e6)
pll.create_clkout(self.cd_pll4x, sys_clk_freq*4, buf=None, with_reset=False)
pll.create_clkout(self.cd_clk200, 200e6, 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_clk200, ~pll.locked),
]
ic_reset_counter = Signal(max=64, reset=63)
ic_reset = Signal(reset=1)
self.sync.clk200 += \
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("clk200"), 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(125e6), **kwargs):
platform = vcu118.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 = uspddrphy.USPDDRPHY(platform.request("ddram"),
memtype = "DDR4",
sys_clk_freq = sys_clk_freq)
self.add_csr("ddrphy")
self.add_constant("USPDDRPHY", None)
sdram_module = EDY4016A(sys_clk_freq, "1:4")
self.register_sdram(self.ddrphy,
geom_settings = sdram_module.geom_settings,
timing_settings = sdram_module.timing_settings)
# EthernetSoC --------------------------------------------------------------------------------------
class EthernetSoC(BaseSoC):
mem_map = {
"ethmac": 0xb0000000,
}
mem_map.update(BaseSoC.mem_map)
def __init__(self, **kwargs):
BaseSoC.__init__(self, **kwargs)
# Ethernet ---------------------------------------------------------------------------------
# phy
self.submodules.ethphy = KU_1000BASEX(self.crg.cd_clk200.clk,
data_pads = self.platform.request("sfp", 0),
sys_clk_freq = self.clk_freq)
self.add_csr("ethphy")
self.comb += self.platform.request("sfp_tx_disable_n", 0).eq(1)
self.platform.add_platform_command("set_property SEVERITY {{Warning}} [get_drc_checks REQP-1753]")
# mac
self.submodules.ethmac = LiteEthMAC(
phy = self.ethphy,
dw = 32,
interface = "wishbone",
endianness = self.cpu.endianness)
self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io")
self.add_wb_slave(self.mem_regions["ethmac"].origin, self.ethmac.bus, 0x2000)
self.add_csr("ethmac")
self.add_interrupt("ethmac")
# timing constraints
self.platform.add_period_constraint(self.ethphy.cd_eth_rx.clk, 1e9/125e6)
self.platform.add_period_constraint(self.ethphy.cd_eth_tx.clk, 1e9/125e6)
self.platform.add_false_path_constraints(
self.crg.cd_sys.clk,
self.ethphy.cd_eth_rx.clk,
self.ethphy.cd_eth_tx.clk)
# Build --------------------------------------------------------------------------------------------
def main():
parser = argparse.ArgumentParser(description="LiteX SoC on KCU105")
builder_args(parser)
soc_sdram_args(parser)
parser.add_argument("--with-ethernet", action="store_true",
help="enable Ethernet support")
args = parser.parse_args()
cls = EthernetSoC if args.with_ethernet else BaseSoC
soc = cls(**soc_sdram_argdict(args))
builder = Builder(soc, **builder_argdict(args))
builder.build()
if __name__ == "__main__":
main()