b65c2f770e84798c36825a205ecfcf7f75e6a660
[litex.git] / litex / soc / integration / soc_zynq.py
1 # This file is Copyright (c) 2019 Florent Kermarrec <florent@enjoy-digital.fr>
2 # License: BSD
3
4 import os
5
6 from migen import *
7
8 from litex.build.generic_platform import tools
9 from litex.soc.integration.soc_core import *
10 from litex.soc.integration.export import get_csr_header
11 from litex.soc.interconnect import wishbone
12 from litex.soc.interconnect import axi
13
14 # Record layouts -----------------------------------------------------------------------------------
15
16 def axi_fifo_ctrl_layout():
17 return [
18 ("racount", 3, DIR_M_TO_S),
19 ("rcount", 8, DIR_M_TO_S),
20 ("rdissuecapen", 1, DIR_S_TO_M),
21 ("wacount", 6, DIR_M_TO_S),
22 ("wcount", 8, DIR_M_TO_S),
23 ("wrissuecapen", 1, DIR_S_TO_M),
24 ]
25
26 # SoC Zynq -----------------------------------------------------------------------------------------
27
28 class SoCZynq(SoCCore):
29 SoCCore.mem_map["csr"] = 0x00000000
30 def __init__(self, platform, clk_freq, ps7_name, **kwargs):
31 self.ps7_name = ps7_name
32 SoCCore.__init__(self, platform, clk_freq, cpu_type=None, **kwargs)
33
34 # PS7 (Minimal) ----------------------------------------------------------------------------
35 fclk_reset0_n = Signal()
36 ps7_ddram_pads = platform.request("ps7_ddram")
37 self.ps7_params = dict(
38 # clk/rst
39 io_PS_CLK = platform.request("ps7_clk"),
40 io_PS_PORB = platform.request("ps7_porb"),
41 io_PS_SRSTB = platform.request("ps7_srstb"),
42
43 # mio
44 io_MIO=platform.request("ps7_mio"),
45
46 # ddram
47 io_DDR_Addr = ps7_ddram_pads.addr,
48 io_DDR_BankAddr = ps7_ddram_pads.ba,
49 io_DDR_CAS_n = ps7_ddram_pads.cas_n,
50 io_DDR_Clk_n = ps7_ddram_pads.ck_n,
51 io_DDR_Clk = ps7_ddram_pads.ck_p,
52 io_DDR_CKE = ps7_ddram_pads.cke,
53 io_DDR_CS_n = ps7_ddram_pads.cs_n,
54 io_DDR_DM = ps7_ddram_pads.dm,
55 io_DDR_DQ = ps7_ddram_pads.dq,
56 io_DDR_DQS_n = ps7_ddram_pads.dqs_n,
57 io_DDR_DQS = ps7_ddram_pads.dqs_p,
58 io_DDR_ODT = ps7_ddram_pads.odt,
59 io_DDR_RAS_n = ps7_ddram_pads.ras_n,
60 io_DDR_DRSTB = ps7_ddram_pads.reset_n,
61 io_DDR_WEB = ps7_ddram_pads.we_n,
62 io_DDR_VRN = ps7_ddram_pads.vrn,
63 io_DDR_VRP = ps7_ddram_pads.vrp,
64
65 # ethernet
66 i_ENET0_MDIO_I=0,
67
68 # sdio0
69 i_SDIO0_WP=0,
70
71 # usb0
72 i_USB0_VBUS_PWRFAULT=0,
73
74 # fabric clk/rst
75 o_FCLK_CLK0 = ClockSignal("sys"),
76 o_FCLK_RESET0_N = fclk_reset0_n
77 )
78 self.comb += ResetSignal("sys").eq(~fclk_reset0_n)
79 platform.add_ip(os.path.join("ip", ps7_name + ".xci"))
80
81 # GP0 ------------------------------------------------------------------------------------------
82
83 def add_gp0(self):
84 self.axi_gp0 = axi_gp0 = axi.AXIInterface(data_width=32, address_width=32, id_width=12)
85 self.ps7_params.update(
86 # axi gp0 clk
87 i_M_AXI_GP0_ACLK=ClockSignal("sys"),
88
89 # axi gp0 aw
90 o_M_AXI_GP0_AWVALID = axi_gp0.aw.valid,
91 i_M_AXI_GP0_AWREADY = axi_gp0.aw.ready,
92 o_M_AXI_GP0_AWADDR = axi_gp0.aw.addr,
93 o_M_AXI_GP0_AWBURST = axi_gp0.aw.burst,
94 o_M_AXI_GP0_AWLEN = axi_gp0.aw.len,
95 o_M_AXI_GP0_AWSIZE = axi_gp0.aw.size,
96 o_M_AXI_GP0_AWID = axi_gp0.aw.id,
97 o_M_AXI_GP0_AWLOCK = axi_gp0.aw.lock,
98 o_M_AXI_GP0_AWPROT = axi_gp0.aw.prot,
99 o_M_AXI_GP0_AWCACHE = axi_gp0.aw.cache,
100 o_M_AXI_GP0_AWQOS = axi_gp0.aw.qos,
101
102 # axi gp0 w
103 o_M_AXI_GP0_WVALID = axi_gp0.w.valid,
104 o_M_AXI_GP0_WLAST = axi_gp0.w.last,
105 i_M_AXI_GP0_WREADY = axi_gp0.w.ready,
106 o_M_AXI_GP0_WID = axi_gp0.w.id,
107 o_M_AXI_GP0_WDATA = axi_gp0.w.data,
108 o_M_AXI_GP0_WSTRB = axi_gp0.w.strb,
109
110 # axi gp0 b
111 i_M_AXI_GP0_BVALID = axi_gp0.b.valid,
112 o_M_AXI_GP0_BREADY = axi_gp0.b.ready,
113 i_M_AXI_GP0_BID = axi_gp0.b.id,
114 i_M_AXI_GP0_BRESP = axi_gp0.b.resp,
115
116 # axi gp0 ar
117 o_M_AXI_GP0_ARVALID = axi_gp0.ar.valid,
118 i_M_AXI_GP0_ARREADY = axi_gp0.ar.ready,
119 o_M_AXI_GP0_ARADDR = axi_gp0.ar.addr,
120 o_M_AXI_GP0_ARBURST = axi_gp0.ar.burst,
121 o_M_AXI_GP0_ARLEN = axi_gp0.ar.len,
122 o_M_AXI_GP0_ARID = axi_gp0.ar.id,
123 o_M_AXI_GP0_ARLOCK = axi_gp0.ar.lock,
124 o_M_AXI_GP0_ARSIZE = axi_gp0.ar.size,
125 o_M_AXI_GP0_ARPROT = axi_gp0.ar.prot,
126 o_M_AXI_GP0_ARCACHE = axi_gp0.ar.cache,
127 o_M_AXI_GP0_ARQOS = axi_gp0.ar.qos,
128
129 # axi gp0 r
130 i_M_AXI_GP0_RVALID = axi_gp0.r.valid,
131 o_M_AXI_GP0_RREADY = axi_gp0.r.ready,
132 i_M_AXI_GP0_RLAST = axi_gp0.r.last,
133 i_M_AXI_GP0_RID = axi_gp0.r.id,
134 i_M_AXI_GP0_RRESP = axi_gp0.r.resp,
135 i_M_AXI_GP0_RDATA = axi_gp0.r.data,
136 )
137
138 # HP0 ------------------------------------------------------------------------------------------
139
140 def add_hp0(self):
141 self.axi_hp0 = axi_hp0 = axi.AXIInterface(data_width=64, address_width=32, id_width=6)
142 self.axi_hp0_fifo_ctrl = axi_hp0_fifo_ctrl = Record(axi_fifo_ctrl_layout())
143 self.ps7_params.update(
144 # axi hp0 clk
145 i_S_AXI_HP0_ACLK=ClockSignal("sys"),
146
147 # axi hp0 aw
148 i_S_AXI_HP0_AWVALID = axi_hp0.aw.valid,
149 o_S_AXI_HP0_AWREADY = axi_hp0.aw.ready,
150 i_S_AXI_HP0_AWADDR = axi_hp0.aw.addr,
151 i_S_AXI_HP0_AWBURST = axi_hp0.aw.burst,
152 i_S_AXI_HP0_AWLEN = axi_hp0.aw.len,
153 i_S_AXI_HP0_AWSIZE = axi_hp0.aw.size,
154 i_S_AXI_HP0_AWID = axi_hp0.aw.id,
155 i_S_AXI_HP0_AWLOCK = axi_hp0.aw.lock,
156 i_S_AXI_HP0_AWPROT = axi_hp0.aw.prot,
157 i_S_AXI_HP0_AWCACHE = axi_hp0.aw.cache,
158 i_S_AXI_HP0_AWQOS = axi_hp0.aw.qos,
159
160 # axi hp0 w
161 i_S_AXI_HP0_WVALID = axi_hp0.w.valid,
162 i_S_AXI_HP0_WLAST = axi_hp0.w.last,
163 o_S_AXI_HP0_WREADY = axi_hp0.w.ready,
164 i_S_AXI_HP0_WID = axi_hp0.w.id,
165 i_S_AXI_HP0_WDATA = axi_hp0.w.data,
166 i_S_AXI_HP0_WSTRB = axi_hp0.w.strb,
167
168 # axi hp0 b
169 o_S_AXI_HP0_BVALID = axi_hp0.b.valid,
170 i_S_AXI_HP0_BREADY = axi_hp0.b.ready,
171 o_S_AXI_HP0_BID = axi_hp0.b.id,
172 o_S_AXI_HP0_BRESP = axi_hp0.b.resp,
173
174 # axi hp0 ar
175 i_S_AXI_HP0_ARVALID = axi_hp0.ar.valid,
176 o_S_AXI_HP0_ARREADY = axi_hp0.ar.ready,
177 i_S_AXI_HP0_ARADDR = axi_hp0.ar.addr,
178 i_S_AXI_HP0_ARBURST = axi_hp0.ar.burst,
179 i_S_AXI_HP0_ARLEN = axi_hp0.ar.len,
180 i_S_AXI_HP0_ARID = axi_hp0.ar.id,
181 i_S_AXI_HP0_ARLOCK = axi_hp0.ar.lock,
182 i_S_AXI_HP0_ARSIZE = axi_hp0.ar.size,
183 i_S_AXI_HP0_ARPROT = axi_hp0.ar.prot,
184 i_S_AXI_HP0_ARCACHE = axi_hp0.ar.cache,
185 i_S_AXI_HP0_ARQOS = axi_hp0.ar.qos,
186
187 # axi hp0 r
188 o_S_AXI_HP0_RVALID = axi_hp0.r.valid,
189 i_S_AXI_HP0_RREADY = axi_hp0.r.ready,
190 o_S_AXI_HP0_RLAST = axi_hp0.r.last,
191 o_S_AXI_HP0_RID = axi_hp0.r.id,
192 o_S_AXI_HP0_RRESP = axi_hp0.r.resp,
193 o_S_AXI_HP0_RDATA = axi_hp0.r.data,
194
195 # axi hp0 fifo ctrl
196 o_S_AXI_HP0_RACOUNT = axi_hp0_fifo_ctrl.racount,
197 o_S_AXI_HP0_RCOUNT = axi_hp0_fifo_ctrl.rcount,
198 i_S_AXI_HP0_RDISSUECAP1_EN = axi_hp0_fifo_ctrl.rdissuecapen,
199 o_S_AXI_HP0_WACOUNT = axi_hp0_fifo_ctrl.wacount,
200 o_S_AXI_HP0_WCOUNT = axi_hp0_fifo_ctrl.wcount,
201 i_S_AXI_HP0_WRISSUECAP1_EN = axi_hp0_fifo_ctrl.wrissuecapen
202 )
203
204 def add_axi_to_wishbone(self, axi_port, base_address=0x43c00000):
205 wb = wishbone.Interface()
206 axi2wishbone = axi.AXI2Wishbone(axi_port, wb, base_address)
207 self.submodules += axi2wishbone
208 self.add_wb_master(wb)
209
210 def do_finalize(self):
211 SoCCore.do_finalize(self)
212 self.specials += Instance(self.ps7_name, **self.ps7_params)
213
214 def generate_software_header(self, filename):
215 csr_header = get_csr_header(self.csr_regions,
216 self.constants,
217 with_access_functions=False)
218 tools.write_to_file(filename, csr_header)