1 # This file is Copyright (c) 2019-2020 Florent Kermarrec <florent@enjoy-digital.fr>
7 from migen
.genlib
.resetsync
import AsyncResetSynchronizer
9 from litex
.soc
.interconnect
import wishbone
10 from litex
.soc
.interconnect
import axi
12 from litex
.soc
.cores
.cpu
import CPU
16 variants
= ["standard"]
18 human_name
= "Zynq7000"
21 reset_address
= 0x00000000
22 gcc_triple
= "arm-xilinx-eabi"
23 linker_output_format
= "elf32-littlearm"
25 io_regions
= {0x00000000: 0x100000000} # origin, length
29 return {"csr": 0x00000000}
31 def __init__(self
, platform
, variant
):
32 self
.platform
= platform
34 self
.periph_buses
= []
35 self
.memory_buses
= []
37 self
.axi_gp_masters
= []
38 self
.axi_gp_slaves
= []
39 self
.axi_hp_slaves
= []
43 self
.clock_domains
.cd_ps7
= ClockDomain()
45 # PS7 (Minimal) ----------------------------------------------------------------------------
47 ps7_ddram_pads
= platform
.request("ps7_ddram")
48 self
.cpu_params
= dict(
50 io_PS_CLK
= platform
.request("ps7_clk"),
51 io_PS_PORB
= platform
.request("ps7_porb"),
52 io_PS_SRSTB
= platform
.request("ps7_srstb"),
55 io_MIO
= platform
.request("ps7_mio"),
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
,
77 i_USB0_VBUS_PWRFAULT
= 0,
80 o_FCLK_CLK0
= ClockSignal("ps7"),
81 o_FCLK_RESET0_N
= ps7_rst_n
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
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
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
,
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
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
151 self
.specials
+= AsyncResetSynchronizer(self
.cd_ps7
, ~ps7_rst_n
)
153 def set_ps7_xci(self
, ps7_xci
):
154 self
.ps7_xci
= ps7_xci
155 self
.platform
.add_ip(ps7_xci
)
157 # AXI GP Master --------------------------------------------------------------------------------
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({
166 f
"i_M_AXI_GP{n}_ACLK" : ClockSignal("ps7"),
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
,
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
,
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
,
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
,
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
,
218 # AXI GP Slave ---------------------------------------------------------------------------------
220 def add_axi_gp_slave(self
):
221 raise NotImplementedError
223 # AXI HP Slave ---------------------------------------------------------------------------------
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({
232 f
"i_S_AXI_HP{n}_ACLK" : ClockSignal("ps7"),
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
,
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
,
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
,
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
,
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
,
285 def add_sources(platform
):
286 platform
.add_ip(os
.path
.join("ip", self
.ps7
))
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
)