9ed783a8adc0a2f9f85a31b575ed1a4f3d1ab95a
[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 def __init__(self, platform, variant):
28 self.platform = platform
29 self.reset = Signal()
30 self.periph_buses = []
31 self.memory_buses = []
32
33 self.axi_gp_masters = []
34 self.axi_gp_slaves = []
35 self.axi_hp_slaves = []
36
37 # # #
38
39 self.clock_domains.cd_ps7 = ClockDomain()
40
41 # PS7 (Minimal) ----------------------------------------------------------------------------
42 ps7_rst_n = Signal()
43 ps7_ddram_pads = platform.request("ps7_ddram")
44 self.cpu_params = dict(
45 # Clk/Rst
46 io_PS_CLK = platform.request("ps7_clk"),
47 io_PS_PORB = platform.request("ps7_porb"),
48 io_PS_SRSTB = platform.request("ps7_srstb"),
49
50 # MIO
51 io_MIO = platform.request("ps7_mio"),
52
53 # DDRAM
54 io_DDR_Addr = ps7_ddram_pads.addr,
55 io_DDR_BankAddr = ps7_ddram_pads.ba,
56 io_DDR_CAS_n = ps7_ddram_pads.cas_n,
57 io_DDR_Clk_n = ps7_ddram_pads.ck_n,
58 io_DDR_Clk = ps7_ddram_pads.ck_p,
59 io_DDR_CKE = ps7_ddram_pads.cke,
60 io_DDR_CS_n = ps7_ddram_pads.cs_n,
61 io_DDR_DM = ps7_ddram_pads.dm,
62 io_DDR_DQ = ps7_ddram_pads.dq,
63 io_DDR_DQS_n = ps7_ddram_pads.dqs_n,
64 io_DDR_DQS = ps7_ddram_pads.dqs_p,
65 io_DDR_ODT = ps7_ddram_pads.odt,
66 io_DDR_RAS_n = ps7_ddram_pads.ras_n,
67 io_DDR_DRSTB = ps7_ddram_pads.reset_n,
68 io_DDR_WEB = ps7_ddram_pads.we_n,
69 io_DDR_VRN = ps7_ddram_pads.vrn,
70 io_DDR_VRP = ps7_ddram_pads.vrp,
71
72 # Ethernet
73 i_ENET0_MDIO_I = 0,
74
75 # SDIO0
76 i_SDIO0_WP = 0,
77
78 # USB0
79 i_USB0_VBUS_PWRFAULT = 0,
80
81 # Fabric Clk/Rst
82 o_FCLK_CLK0 = ClockSignal("ps7"),
83 o_FCLK_RESET0_N = ps7_rst_n
84 )
85 self.specials += AsyncResetSynchronizer(self.cd_ps7, ~ps7_rst_n)
86
87 def set_ps7_xci(self, ps7_xci):
88 self.ps7_xci = ps7_xci
89 self.platform.add_ip(ps7_xci)
90
91 # AXI GP Master --------------------------------------------------------------------------------
92
93 def add_axi_gp_master(self):
94 assert len(self.axi_gp_masters) < 2
95 n = len(self.axi_gp_masters)
96 axi_gpn = axi.AXIInterface(data_width=32, address_width=32, id_width=12)
97 self.axi_gp_masters.append(axi_gpn)
98 self.cpu_params.update({
99 # AXI GP clk
100 f"i_M_AXI_GP{n}_ACLK" : ClockSignal("ps7"),
101
102 # AXI GP aw
103 f"o_M_AXI_GP{n}_AWVALID" : axi_gpn.aw.valid,
104 f"i_M_AXI_GP{n}_AWREADY" : axi_gpn.aw.ready,
105 f"o_M_AXI_GP{n}_AWADDR" : axi_gpn.aw.addr,
106 f"o_M_AXI_GP{n}_AWBURST" : axi_gpn.aw.burst,
107 f"o_M_AXI_GP{n}_AWLEN" : axi_gpn.aw.len,
108 f"o_M_AXI_GP{n}_AWSIZE" : axi_gpn.aw.size,
109 f"o_M_AXI_GP{n}_AWID" : axi_gpn.aw.id,
110 f"o_M_AXI_GP{n}_AWLOCK" : axi_gpn.aw.lock,
111 f"o_M_AXI_GP{n}_AWPROT" : axi_gpn.aw.prot,
112 f"o_M_AXI_GP{n}_AWCACHE" : axi_gpn.aw.cache,
113 f"o_M_AXI_GP{n}_AWQOS" : axi_gpn.aw.qos,
114
115 # AXI GP w
116 f"o_M_AXI_GP{n}_WVALID" : axi_gpn.w.valid,
117 f"o_M_AXI_GP{n}_WLAST" : axi_gpn.w.last,
118 f"i_M_AXI_GP{n}_WREADY" : axi_gpn.w.ready,
119 f"o_M_AXI_GP{n}_WID" : axi_gpn.w.id,
120 f"o_M_AXI_GP{n}_WDATA" : axi_gpn.w.data,
121 f"o_M_AXI_GP{n}_WSTRB" : axi_gpn.w.strb,
122
123 # AXI GP b
124 f"i_M_AXI_GP{n}_BVALID" : axi_gpn.b.valid,
125 f"o_M_AXI_GP{n}_BREADY" : axi_gpn.b.ready,
126 f"i_M_AXI_GP{n}_BID" : axi_gpn.b.id,
127 f"i_M_AXI_GP{n}_BRESP" : axi_gpn.b.resp,
128
129 # AXI GP ar
130 f"o_M_AXI_GP{n}_ARVALID" : axi_gpn.ar.valid,
131 f"i_M_AXI_GP{n}_ARREADY" : axi_gpn.ar.ready,
132 f"o_M_AXI_GP{n}_ARADDR" : axi_gpn.ar.addr,
133 f"o_M_AXI_GP{n}_ARBURST" : axi_gpn.ar.burst,
134 f"o_M_AXI_GP{n}_ARLEN" : axi_gpn.ar.len,
135 f"o_M_AXI_GP{n}_ARID" : axi_gpn.ar.id,
136 f"o_M_AXI_GP{n}_ARLOCK" : axi_gpn.ar.lock,
137 f"o_M_AXI_GP{n}_ARSIZE" : axi_gpn.ar.size,
138 f"o_M_AXI_GP{n}_ARPROT" : axi_gpn.ar.prot,
139 f"o_M_AXI_GP{n}_ARCACHE" : axi_gpn.ar.cache,
140 f"o_M_AXI_GP{n}_ARQOS" : axi_gpn.ar.qos,
141
142 # AXI GP r
143 f"i_M_AXI_GP{n}_RVALID" : axi_gpn.r.valid,
144 f"o_M_AXI_GP{n}_RREADY" : axi_gpn.r.ready,
145 f"i_M_AXI_GP{n}_RLAST" : axi_gpn.r.last,
146 f"i_M_AXI_GP{n}_RID" : axi_gpn.r.id,
147 f"i_M_AXI_GP{n}_RRESP" : axi_gpn.r.resp,
148 f"i_M_AXI_GP{n}_RDATA" : axi_gpn.r.data,
149 })
150 return axi_gpn
151
152 # AXI GP Slave ---------------------------------------------------------------------------------
153
154 def add_axi_gp_slave(self):
155 raise NotImplementedError
156
157 # AXI HP Slave ---------------------------------------------------------------------------------
158
159 def add_axi_hp_slave(self):
160 assert len(self.axi_hp_slaves) < 4
161 n = len(self.axi_hp_slaves)
162 axi_hpn = axi.AXIInterface(data_width=64, address_width=32, id_width=6)
163 self.axi_hp_masters.append(axi_hpn)
164 self.cpu_params.update({
165 # AXI HP0 clk
166 f"i_S_AXI_HP{n}_ACLK" : ClockSignal("ps7"),
167
168 # AXI HP0 aw
169 f"i_S_AXI_HP{n}_AWVALID" : axi_hpn.aw.valid,
170 f"o_S_AXI_HP{n}_AWREADY" : axi_hpn.aw.ready,
171 f"i_S_AXI_HP{n}_AWADDR" : axi_hpn.aw.addr,
172 f"i_S_AXI_HP{n}_AWBURST" : axi_hpn.aw.burst,
173 f"i_S_AXI_HP{n}_AWLEN" : axi_hpn.aw.len,
174 f"i_S_AXI_HP{n}_AWSIZE" : axi_hpn.aw.size,
175 f"i_S_AXI_HP{n}_AWID" : axi_hpn.aw.id,
176 f"i_S_AXI_HP{n}_AWLOCK" : axi_hpn.aw.lock,
177 f"i_S_AXI_HP{n}_AWPROT" : axi_hpn.aw.prot,
178 f"i_S_AXI_HP{n}_AWCACHE" : axi_hpn.aw.cache,
179 f"i_S_AXI_HP{n}_AWQOS" : axi_hpn.aw.qos,
180
181 # AXI HP0 w
182 f"i_S_AXI_HP{n}_WVALID" : axi_hpn.w.valid,
183 f"i_S_AXI_HP{n}_WLAST" : axi_hpn.w.last,
184 f"o_S_AXI_HP{n}_WREADY" : axi_hpn.w.ready,
185 f"i_S_AXI_HP{n}_WID" : axi_hpn.w.id,
186 f"i_S_AXI_HP{n}_WDATA" : axi_hpn.w.data,
187 f"i_S_AXI_HP{n}_WSTRB" : axi_hpn.w.strb,
188
189 # AXI HP0 b
190 f"o_S_AXI_HP{n}_BVALID" : axi_hpn.b.valid,
191 f"i_S_AXI_HP{n}_BREADY" : axi_hpn.b.ready,
192 f"o_S_AXI_HP{n}_BID" : axi_hpn.b.id,
193 f"o_S_AXI_HP{n}_BRESP" : axi_hpn.b.resp,
194
195 # AXI HP0 ar
196 f"i_S_AXI_HP{n}_ARVALID" : axi_hpn.ar.valid,
197 f"o_S_AXI_HP{n}_ARREADY" : axi_hpn.ar.ready,
198 f"i_S_AXI_HP{n}_ARADDR" : axi_hpn.ar.addr,
199 f"i_S_AXI_HP{n}_ARBURST" : axi_hpn.ar.burst,
200 f"i_S_AXI_HP{n}_ARLEN" : axi_hpn.ar.len,
201 f"i_S_AXI_HP{n}_ARID" : axi_hpn.ar.id,
202 f"i_S_AXI_HP{n}_ARLOCK" : axi_hpn.ar.lock,
203 f"i_S_AXI_HP{n}_ARSIZE" : axi_hpn.ar.size,
204 f"i_S_AXI_HP{n}_ARPROT" : axi_hpn.ar.prot,
205 f"i_S_AXI_HP{n}_ARCACHE" : axi_hpn.ar.cache,
206 f"i_S_AXI_HP{n}_ARQOS" : axi_hpn.ar.qos,
207
208 # AXI HP0 r
209 f"o_S_AXI_HP{n}_RVALID" : axi_hpn.r.valid,
210 f"i_S_AXI_HP{n}_RREADY" : axi_hpn.r.ready,
211 f"o_S_AXI_HP{n}_RLAST" : axi_hpn.r.last,
212 f"o_S_AXI_HP{n}_RID" : axi_hpn.r.id,
213 f"o_S_AXI_HP{n}_RRESP" : axi_hpn.r.resp,
214 f"o_S_AXI_HP{n}_RDATA" : axi_hpn.r.data,
215 })
216 return axi_hpn
217
218 @staticmethod
219 def add_sources(platform):
220 platform.add_ip(os.path.join("ip", self.ps7))
221
222 def do_finalize(self):
223 assert hasattr(self, "ps7_xci")
224 ps7_name = os.path.splitext(os.path.basename(self.ps7_xci))[0]
225 self.specials += Instance(ps7_name, **self.cpu_params)