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
,
83 i_USB0_VBUS_PWRFAULT
= 0,
86 o_FCLK_CLK0
= ClockSignal("ps7"),
87 o_FCLK_RESET0_N
= ps7_rst_n
89 self
.specials
+= AsyncResetSynchronizer(self
.cd_ps7
, ~ps7_rst_n
)
91 def set_ps7_xci(self
, ps7_xci
):
92 self
.ps7_xci
= ps7_xci
93 self
.platform
.add_ip(ps7_xci
)
95 # AXI GP Master --------------------------------------------------------------------------------
97 def add_axi_gp_master(self
):
98 assert len(self
.axi_gp_masters
) < 2
99 n
= len(self
.axi_gp_masters
)
100 axi_gpn
= axi
.AXIInterface(data_width
=32, address_width
=32, id_width
=12)
101 self
.axi_gp_masters
.append(axi_gpn
)
102 self
.cpu_params
.update({
104 f
"i_M_AXI_GP{n}_ACLK" : ClockSignal("ps7"),
107 f
"o_M_AXI_GP{n}_AWVALID" : axi_gpn
.aw
.valid
,
108 f
"i_M_AXI_GP{n}_AWREADY" : axi_gpn
.aw
.ready
,
109 f
"o_M_AXI_GP{n}_AWADDR" : axi_gpn
.aw
.addr
,
110 f
"o_M_AXI_GP{n}_AWBURST" : axi_gpn
.aw
.burst
,
111 f
"o_M_AXI_GP{n}_AWLEN" : axi_gpn
.aw
.len,
112 f
"o_M_AXI_GP{n}_AWSIZE" : axi_gpn
.aw
.size
,
113 f
"o_M_AXI_GP{n}_AWID" : axi_gpn
.aw
.id,
114 f
"o_M_AXI_GP{n}_AWLOCK" : axi_gpn
.aw
.lock
,
115 f
"o_M_AXI_GP{n}_AWPROT" : axi_gpn
.aw
.prot
,
116 f
"o_M_AXI_GP{n}_AWCACHE" : axi_gpn
.aw
.cache
,
117 f
"o_M_AXI_GP{n}_AWQOS" : axi_gpn
.aw
.qos
,
120 f
"o_M_AXI_GP{n}_WVALID" : axi_gpn
.w
.valid
,
121 f
"o_M_AXI_GP{n}_WLAST" : axi_gpn
.w
.last
,
122 f
"i_M_AXI_GP{n}_WREADY" : axi_gpn
.w
.ready
,
123 f
"o_M_AXI_GP{n}_WID" : axi_gpn
.w
.id,
124 f
"o_M_AXI_GP{n}_WDATA" : axi_gpn
.w
.data
,
125 f
"o_M_AXI_GP{n}_WSTRB" : axi_gpn
.w
.strb
,
128 f
"i_M_AXI_GP{n}_BVALID" : axi_gpn
.b
.valid
,
129 f
"o_M_AXI_GP{n}_BREADY" : axi_gpn
.b
.ready
,
130 f
"i_M_AXI_GP{n}_BID" : axi_gpn
.b
.id,
131 f
"i_M_AXI_GP{n}_BRESP" : axi_gpn
.b
.resp
,
134 f
"o_M_AXI_GP{n}_ARVALID" : axi_gpn
.ar
.valid
,
135 f
"i_M_AXI_GP{n}_ARREADY" : axi_gpn
.ar
.ready
,
136 f
"o_M_AXI_GP{n}_ARADDR" : axi_gpn
.ar
.addr
,
137 f
"o_M_AXI_GP{n}_ARBURST" : axi_gpn
.ar
.burst
,
138 f
"o_M_AXI_GP{n}_ARLEN" : axi_gpn
.ar
.len,
139 f
"o_M_AXI_GP{n}_ARID" : axi_gpn
.ar
.id,
140 f
"o_M_AXI_GP{n}_ARLOCK" : axi_gpn
.ar
.lock
,
141 f
"o_M_AXI_GP{n}_ARSIZE" : axi_gpn
.ar
.size
,
142 f
"o_M_AXI_GP{n}_ARPROT" : axi_gpn
.ar
.prot
,
143 f
"o_M_AXI_GP{n}_ARCACHE" : axi_gpn
.ar
.cache
,
144 f
"o_M_AXI_GP{n}_ARQOS" : axi_gpn
.ar
.qos
,
147 f
"i_M_AXI_GP{n}_RVALID" : axi_gpn
.r
.valid
,
148 f
"o_M_AXI_GP{n}_RREADY" : axi_gpn
.r
.ready
,
149 f
"i_M_AXI_GP{n}_RLAST" : axi_gpn
.r
.last
,
150 f
"i_M_AXI_GP{n}_RID" : axi_gpn
.r
.id,
151 f
"i_M_AXI_GP{n}_RRESP" : axi_gpn
.r
.resp
,
152 f
"i_M_AXI_GP{n}_RDATA" : axi_gpn
.r
.data
,
156 # AXI GP Slave ---------------------------------------------------------------------------------
158 def add_axi_gp_slave(self
):
159 raise NotImplementedError
161 # AXI HP Slave ---------------------------------------------------------------------------------
163 def add_axi_hp_slave(self
):
164 assert len(self
.axi_hp_slaves
) < 4
165 n
= len(self
.axi_hp_slaves
)
166 axi_hpn
= axi
.AXIInterface(data_width
=64, address_width
=32, id_width
=6)
167 self
.axi_hp_masters
.append(axi_hpn
)
168 self
.cpu_params
.update({
170 f
"i_S_AXI_HP{n}_ACLK" : ClockSignal("ps7"),
173 f
"i_S_AXI_HP{n}_AWVALID" : axi_hpn
.aw
.valid
,
174 f
"o_S_AXI_HP{n}_AWREADY" : axi_hpn
.aw
.ready
,
175 f
"i_S_AXI_HP{n}_AWADDR" : axi_hpn
.aw
.addr
,
176 f
"i_S_AXI_HP{n}_AWBURST" : axi_hpn
.aw
.burst
,
177 f
"i_S_AXI_HP{n}_AWLEN" : axi_hpn
.aw
.len,
178 f
"i_S_AXI_HP{n}_AWSIZE" : axi_hpn
.aw
.size
,
179 f
"i_S_AXI_HP{n}_AWID" : axi_hpn
.aw
.id,
180 f
"i_S_AXI_HP{n}_AWLOCK" : axi_hpn
.aw
.lock
,
181 f
"i_S_AXI_HP{n}_AWPROT" : axi_hpn
.aw
.prot
,
182 f
"i_S_AXI_HP{n}_AWCACHE" : axi_hpn
.aw
.cache
,
183 f
"i_S_AXI_HP{n}_AWQOS" : axi_hpn
.aw
.qos
,
186 f
"i_S_AXI_HP{n}_WVALID" : axi_hpn
.w
.valid
,
187 f
"i_S_AXI_HP{n}_WLAST" : axi_hpn
.w
.last
,
188 f
"o_S_AXI_HP{n}_WREADY" : axi_hpn
.w
.ready
,
189 f
"i_S_AXI_HP{n}_WID" : axi_hpn
.w
.id,
190 f
"i_S_AXI_HP{n}_WDATA" : axi_hpn
.w
.data
,
191 f
"i_S_AXI_HP{n}_WSTRB" : axi_hpn
.w
.strb
,
194 f
"o_S_AXI_HP{n}_BVALID" : axi_hpn
.b
.valid
,
195 f
"i_S_AXI_HP{n}_BREADY" : axi_hpn
.b
.ready
,
196 f
"o_S_AXI_HP{n}_BID" : axi_hpn
.b
.id,
197 f
"o_S_AXI_HP{n}_BRESP" : axi_hpn
.b
.resp
,
200 f
"i_S_AXI_HP{n}_ARVALID" : axi_hpn
.ar
.valid
,
201 f
"o_S_AXI_HP{n}_ARREADY" : axi_hpn
.ar
.ready
,
202 f
"i_S_AXI_HP{n}_ARADDR" : axi_hpn
.ar
.addr
,
203 f
"i_S_AXI_HP{n}_ARBURST" : axi_hpn
.ar
.burst
,
204 f
"i_S_AXI_HP{n}_ARLEN" : axi_hpn
.ar
.len,
205 f
"i_S_AXI_HP{n}_ARID" : axi_hpn
.ar
.id,
206 f
"i_S_AXI_HP{n}_ARLOCK" : axi_hpn
.ar
.lock
,
207 f
"i_S_AXI_HP{n}_ARSIZE" : axi_hpn
.ar
.size
,
208 f
"i_S_AXI_HP{n}_ARPROT" : axi_hpn
.ar
.prot
,
209 f
"i_S_AXI_HP{n}_ARCACHE" : axi_hpn
.ar
.cache
,
210 f
"i_S_AXI_HP{n}_ARQOS" : axi_hpn
.ar
.qos
,
213 f
"o_S_AXI_HP{n}_RVALID" : axi_hpn
.r
.valid
,
214 f
"i_S_AXI_HP{n}_RREADY" : axi_hpn
.r
.ready
,
215 f
"o_S_AXI_HP{n}_RLAST" : axi_hpn
.r
.last
,
216 f
"o_S_AXI_HP{n}_RID" : axi_hpn
.r
.id,
217 f
"o_S_AXI_HP{n}_RRESP" : axi_hpn
.r
.resp
,
218 f
"o_S_AXI_HP{n}_RDATA" : axi_hpn
.r
.data
,
223 def add_sources(platform
):
224 platform
.add_ip(os
.path
.join("ip", self
.ps7
))
226 def do_finalize(self
):
227 assert hasattr(self
, "ps7_xci")
228 ps7_name
= os
.path
.splitext(os
.path
.basename(self
.ps7_xci
))[0]
229 self
.specials
+= Instance(ps7_name
, **self
.cpu_params
)