soc/cores/cpu/zynq7000: add enet0, enet0_mdio, sdio, sdio_cd and sdio_wp only when...
[litex.git] / litex / soc / cores / cpu / zynq7000 / core.py
1 # This file is Copyright (c) 2019-2020 Florent Kermarrec <florent@enjoy-digital.fr>
2 # License: BSD
3
4 import os
5
6 from migen import *
7 from migen.genlib.resetsync import AsyncResetSynchronizer
8
9 from litex.soc.interconnect import wishbone
10 from litex.soc.interconnect import axi
11
12 from litex.soc.cores.cpu import CPU
13
14
15 class Zynq7000(CPU):
16 variants = ["standard"]
17 name = "zynq7000"
18 human_name = "Zynq7000"
19 data_width = 32
20 endianness = "little"
21 reset_address = 0x00000000
22 gcc_triple = "arm-xilinx-eabi"
23 linker_output_format = "elf32-littlearm"
24 nop = "nop"
25 io_regions = {0x00000000: 0x100000000} # origin, length
26
27 @property
28 def mem_map(self):
29 return {"csr": 0x00000000}
30
31 def __init__(self, platform, variant):
32 self.platform = platform
33 self.reset = Signal()
34 self.periph_buses = []
35 self.memory_buses = []
36
37 self.axi_gp_masters = []
38 self.axi_gp_slaves = []
39 self.axi_hp_slaves = []
40
41 # # #
42
43 self.clock_domains.cd_ps7 = ClockDomain()
44
45 # PS7 (Minimal) ----------------------------------------------------------------------------
46 ps7_rst_n = Signal()
47 ps7_ddram_pads = platform.request("ps7_ddram")
48 self.cpu_params = dict(
49 # Clk/Rst
50 io_PS_CLK = platform.request("ps7_clk"),
51 io_PS_PORB = platform.request("ps7_porb"),
52 io_PS_SRSTB = platform.request("ps7_srstb"),
53
54 # MIO
55 io_MIO = platform.request("ps7_mio"),
56
57 # DDRAM
58 io_DDR_Addr = ps7_ddram_pads.addr,
59 io_DDR_BankAddr = ps7_ddram_pads.ba,
60 io_DDR_CAS_n = ps7_ddram_pads.cas_n,
61 io_DDR_Clk_n = ps7_ddram_pads.ck_n,
62 io_DDR_Clk = ps7_ddram_pads.ck_p,
63 io_DDR_CKE = ps7_ddram_pads.cke,
64 io_DDR_CS_n = ps7_ddram_pads.cs_n,
65 io_DDR_DM = ps7_ddram_pads.dm,
66 io_DDR_DQ = ps7_ddram_pads.dq,
67 io_DDR_DQS_n = ps7_ddram_pads.dqs_n,
68 io_DDR_DQS = ps7_ddram_pads.dqs_p,
69 io_DDR_ODT = ps7_ddram_pads.odt,
70 io_DDR_RAS_n = ps7_ddram_pads.ras_n,
71 io_DDR_DRSTB = ps7_ddram_pads.reset_n,
72 io_DDR_WEB = ps7_ddram_pads.we_n,
73 io_DDR_VRN = ps7_ddram_pads.vrn,
74 io_DDR_VRP = ps7_ddram_pads.vrp,
75
76 # USB0
77 i_USB0_VBUS_PWRFAULT = 0,
78
79 # Fabric Clk/Rst
80 o_FCLK_CLK0 = ClockSignal("ps7"),
81 o_FCLK_RESET0_N = ps7_rst_n
82 )
83
84 # Enet0 mdio
85 try:
86 ps7_enet0_mdio_pads = platform.request("ps7_enet0_mdio")
87 self.cpu_params.update(dict(
88 o_ENET0_MDIO_MDC = ps7_enet0_mdio_pads.mdc,
89 i_ENET0_MDIO_I = ps7_enet0_mdio_pads.i,
90 o_ENET0_MDIO_O = ps7_enet0_mdio_pads.o,
91 o_ENET0_MDIO_T = ps7_enet0_mdio_pads.t
92 ))
93 except:
94 pass
95
96 # Enet0
97 try:
98 ps7_enet0_pads = platform.request("ps7_enet0")
99 self.cpu_params.update(dict(
100 o_ENET0_GMII_TX_EN = ps7_enet0_pads.tx_en,
101 o_ENET0_GMII_TX_ER = ps7_enet0_pads.tx_er,
102 o_ENET0_GMII_TXD = ps7_enet0_pads.txd,
103 i_ENET0_GMII_COL = ps7_enet0_pads.col,
104 i_ENET0_GMII_CRS = ps7_enet0_pads.crs,
105 i_ENET0_GMII_RX_CLK = ps7_enet0_pads.rx_clk,
106 i_ENET0_GMII_RX_DV = ps7_enet0_pads.rx_dv,
107 i_ENET0_GMII_RX_ER = ps7_enet0_pads.rx_er,
108 i_ENET0_GMII_TX_CLK = ps7_enet0_pads.tx_clk,
109 i_ENET0_GMII_RXD = ps7_enet0_pads.rxd
110 ))
111 except:
112 pass
113
114 # SDIO0
115 try:
116 ps7_sdio0_pads = platform.request("ps7_sdio0")
117 self.cpu_params.update(dict(
118 o_SDIO0_CLK = ps7_sdio0_pads.clk,
119 i_SDIO0_CLK_FB = ps7_sdio0_pads.clk_fb,
120 o_SDIO0_CMD_O = ps7_sdio0_pads.cmd_o,
121 i_SDIO0_CMD_I = ps7_sdio0_pads.cmd_i,
122 o_SDIO0_CMD_T = ps7_sdio0_pads.cmd_t,
123 o_SDIO0_DATA_O = ps7_sdio0_pads.data_o,
124 i_SDIO0_DATA_I = ps7_sdio0_pads.data_i,
125 o_SDIO0_DATA_T = ps7_sdio0_pads.data_t,
126 o_SDIO0_LED = ps7_sdio0_pads.led,
127 o_SDIO0_BUSPOW = ps7_sdio0_pads.buspow,
128 o_SDIO0_BUSVOLT = ps7_sdio0_pads.busvolt,
129 ))
130 except:
131 pass
132
133 # SDIO0_CD
134 try:
135 ps7_sdio0_cd_pads = platform.request("ps7_sdio0_cd")
136 self.cpu_params.update(dict(
137 i_SDIO0_CDN = ps7_sdio0_cd_pads.cdn
138 ))
139 except:
140 pass
141
142 # SDIO0_WP
143 try:
144 ps7_sdio0_wp_pads = platform.request("ps7_sdio0_wp")
145 self.cpu_params.update(dict(
146 i_SDIO0_WP = ps7_sdio0_wp_pads.wp
147 ))
148 except:
149 pass
150
151 self.specials += AsyncResetSynchronizer(self.cd_ps7, ~ps7_rst_n)
152
153 def set_ps7_xci(self, ps7_xci):
154 self.ps7_xci = ps7_xci
155 self.platform.add_ip(ps7_xci)
156
157 # AXI GP Master --------------------------------------------------------------------------------
158
159 def add_axi_gp_master(self):
160 assert len(self.axi_gp_masters) < 2
161 n = len(self.axi_gp_masters)
162 axi_gpn = axi.AXIInterface(data_width=32, address_width=32, id_width=12)
163 self.axi_gp_masters.append(axi_gpn)
164 self.cpu_params.update({
165 # AXI GP clk
166 f"i_M_AXI_GP{n}_ACLK" : ClockSignal("ps7"),
167
168 # AXI GP aw
169 f"o_M_AXI_GP{n}_AWVALID" : axi_gpn.aw.valid,
170 f"i_M_AXI_GP{n}_AWREADY" : axi_gpn.aw.ready,
171 f"o_M_AXI_GP{n}_AWADDR" : axi_gpn.aw.addr,
172 f"o_M_AXI_GP{n}_AWBURST" : axi_gpn.aw.burst,
173 f"o_M_AXI_GP{n}_AWLEN" : axi_gpn.aw.len,
174 f"o_M_AXI_GP{n}_AWSIZE" : axi_gpn.aw.size,
175 f"o_M_AXI_GP{n}_AWID" : axi_gpn.aw.id,
176 f"o_M_AXI_GP{n}_AWLOCK" : axi_gpn.aw.lock,
177 f"o_M_AXI_GP{n}_AWPROT" : axi_gpn.aw.prot,
178 f"o_M_AXI_GP{n}_AWCACHE" : axi_gpn.aw.cache,
179 f"o_M_AXI_GP{n}_AWQOS" : axi_gpn.aw.qos,
180
181 # AXI GP w
182 f"o_M_AXI_GP{n}_WVALID" : axi_gpn.w.valid,
183 f"o_M_AXI_GP{n}_WLAST" : axi_gpn.w.last,
184 f"i_M_AXI_GP{n}_WREADY" : axi_gpn.w.ready,
185 f"o_M_AXI_GP{n}_WID" : axi_gpn.w.id,
186 f"o_M_AXI_GP{n}_WDATA" : axi_gpn.w.data,
187 f"o_M_AXI_GP{n}_WSTRB" : axi_gpn.w.strb,
188
189 # AXI GP b
190 f"i_M_AXI_GP{n}_BVALID" : axi_gpn.b.valid,
191 f"o_M_AXI_GP{n}_BREADY" : axi_gpn.b.ready,
192 f"i_M_AXI_GP{n}_BID" : axi_gpn.b.id,
193 f"i_M_AXI_GP{n}_BRESP" : axi_gpn.b.resp,
194
195 # AXI GP ar
196 f"o_M_AXI_GP{n}_ARVALID" : axi_gpn.ar.valid,
197 f"i_M_AXI_GP{n}_ARREADY" : axi_gpn.ar.ready,
198 f"o_M_AXI_GP{n}_ARADDR" : axi_gpn.ar.addr,
199 f"o_M_AXI_GP{n}_ARBURST" : axi_gpn.ar.burst,
200 f"o_M_AXI_GP{n}_ARLEN" : axi_gpn.ar.len,
201 f"o_M_AXI_GP{n}_ARID" : axi_gpn.ar.id,
202 f"o_M_AXI_GP{n}_ARLOCK" : axi_gpn.ar.lock,
203 f"o_M_AXI_GP{n}_ARSIZE" : axi_gpn.ar.size,
204 f"o_M_AXI_GP{n}_ARPROT" : axi_gpn.ar.prot,
205 f"o_M_AXI_GP{n}_ARCACHE" : axi_gpn.ar.cache,
206 f"o_M_AXI_GP{n}_ARQOS" : axi_gpn.ar.qos,
207
208 # AXI GP r
209 f"i_M_AXI_GP{n}_RVALID" : axi_gpn.r.valid,
210 f"o_M_AXI_GP{n}_RREADY" : axi_gpn.r.ready,
211 f"i_M_AXI_GP{n}_RLAST" : axi_gpn.r.last,
212 f"i_M_AXI_GP{n}_RID" : axi_gpn.r.id,
213 f"i_M_AXI_GP{n}_RRESP" : axi_gpn.r.resp,
214 f"i_M_AXI_GP{n}_RDATA" : axi_gpn.r.data,
215 })
216 return axi_gpn
217
218 # AXI GP Slave ---------------------------------------------------------------------------------
219
220 def add_axi_gp_slave(self):
221 raise NotImplementedError
222
223 # AXI HP Slave ---------------------------------------------------------------------------------
224
225 def add_axi_hp_slave(self):
226 assert len(self.axi_hp_slaves) < 4
227 n = len(self.axi_hp_slaves)
228 axi_hpn = axi.AXIInterface(data_width=64, address_width=32, id_width=6)
229 self.axi_hp_masters.append(axi_hpn)
230 self.cpu_params.update({
231 # AXI HP0 clk
232 f"i_S_AXI_HP{n}_ACLK" : ClockSignal("ps7"),
233
234 # AXI HP0 aw
235 f"i_S_AXI_HP{n}_AWVALID" : axi_hpn.aw.valid,
236 f"o_S_AXI_HP{n}_AWREADY" : axi_hpn.aw.ready,
237 f"i_S_AXI_HP{n}_AWADDR" : axi_hpn.aw.addr,
238 f"i_S_AXI_HP{n}_AWBURST" : axi_hpn.aw.burst,
239 f"i_S_AXI_HP{n}_AWLEN" : axi_hpn.aw.len,
240 f"i_S_AXI_HP{n}_AWSIZE" : axi_hpn.aw.size,
241 f"i_S_AXI_HP{n}_AWID" : axi_hpn.aw.id,
242 f"i_S_AXI_HP{n}_AWLOCK" : axi_hpn.aw.lock,
243 f"i_S_AXI_HP{n}_AWPROT" : axi_hpn.aw.prot,
244 f"i_S_AXI_HP{n}_AWCACHE" : axi_hpn.aw.cache,
245 f"i_S_AXI_HP{n}_AWQOS" : axi_hpn.aw.qos,
246
247 # AXI HP0 w
248 f"i_S_AXI_HP{n}_WVALID" : axi_hpn.w.valid,
249 f"i_S_AXI_HP{n}_WLAST" : axi_hpn.w.last,
250 f"o_S_AXI_HP{n}_WREADY" : axi_hpn.w.ready,
251 f"i_S_AXI_HP{n}_WID" : axi_hpn.w.id,
252 f"i_S_AXI_HP{n}_WDATA" : axi_hpn.w.data,
253 f"i_S_AXI_HP{n}_WSTRB" : axi_hpn.w.strb,
254
255 # AXI HP0 b
256 f"o_S_AXI_HP{n}_BVALID" : axi_hpn.b.valid,
257 f"i_S_AXI_HP{n}_BREADY" : axi_hpn.b.ready,
258 f"o_S_AXI_HP{n}_BID" : axi_hpn.b.id,
259 f"o_S_AXI_HP{n}_BRESP" : axi_hpn.b.resp,
260
261 # AXI HP0 ar
262 f"i_S_AXI_HP{n}_ARVALID" : axi_hpn.ar.valid,
263 f"o_S_AXI_HP{n}_ARREADY" : axi_hpn.ar.ready,
264 f"i_S_AXI_HP{n}_ARADDR" : axi_hpn.ar.addr,
265 f"i_S_AXI_HP{n}_ARBURST" : axi_hpn.ar.burst,
266 f"i_S_AXI_HP{n}_ARLEN" : axi_hpn.ar.len,
267 f"i_S_AXI_HP{n}_ARID" : axi_hpn.ar.id,
268 f"i_S_AXI_HP{n}_ARLOCK" : axi_hpn.ar.lock,
269 f"i_S_AXI_HP{n}_ARSIZE" : axi_hpn.ar.size,
270 f"i_S_AXI_HP{n}_ARPROT" : axi_hpn.ar.prot,
271 f"i_S_AXI_HP{n}_ARCACHE" : axi_hpn.ar.cache,
272 f"i_S_AXI_HP{n}_ARQOS" : axi_hpn.ar.qos,
273
274 # AXI HP0 r
275 f"o_S_AXI_HP{n}_RVALID" : axi_hpn.r.valid,
276 f"i_S_AXI_HP{n}_RREADY" : axi_hpn.r.ready,
277 f"o_S_AXI_HP{n}_RLAST" : axi_hpn.r.last,
278 f"o_S_AXI_HP{n}_RID" : axi_hpn.r.id,
279 f"o_S_AXI_HP{n}_RRESP" : axi_hpn.r.resp,
280 f"o_S_AXI_HP{n}_RDATA" : axi_hpn.r.data,
281 })
282 return axi_hpn
283
284 @staticmethod
285 def add_sources(platform):
286 platform.add_ip(os.path.join("ip", self.ps7))
287
288 def do_finalize(self):
289 assert hasattr(self, "ps7_xci")
290 ps7_name = os.path.splitext(os.path.basename(self.ps7_xci))[0]
291 self.specials += Instance(ps7_name, **self.cpu_params)