1 # This file is Copyright (c) 2019 Florent Kermarrec <florent@enjoy-digital.fr>
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
14 # Record layouts -----------------------------------------------------------------------------------
16 def axi_fifo_ctrl_layout():
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
),
26 # SoC Zynq -----------------------------------------------------------------------------------------
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
)
34 # PS7 (Minimal) ----------------------------------------------------------------------------
35 fclk_reset0_n
= Signal()
36 ps7_ddram_pads
= platform
.request("ps7_ddram")
37 self
.ps7_params
= dict(
39 io_PS_CLK
= platform
.request("ps7_clk"),
40 io_PS_PORB
= platform
.request("ps7_porb"),
41 io_PS_SRSTB
= platform
.request("ps7_srstb"),
44 io_MIO
=platform
.request("ps7_mio"),
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
,
72 i_USB0_VBUS_PWRFAULT
=0,
75 o_FCLK_CLK0
= ClockSignal("sys"),
76 o_FCLK_RESET0_N
= fclk_reset0_n
78 self
.comb
+= ResetSignal("sys").eq(~fclk_reset0_n
)
79 platform
.add_ip(os
.path
.join("ip", ps7_name
+ ".xci"))
81 # GP0 ------------------------------------------------------------------------------------------
84 self
.axi_gp0
= axi_gp0
= axi
.AXIInterface(data_width
=32, address_width
=32, id_width
=12)
85 self
.ps7_params
.update(
87 i_M_AXI_GP0_ACLK
=ClockSignal("sys"),
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
,
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
,
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
,
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
,
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
,
138 # HP0 ------------------------------------------------------------------------------------------
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(
145 i_S_AXI_HP0_ACLK
=ClockSignal("sys"),
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
,
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
,
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
,
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
,
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
,
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
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
)
210 def do_finalize(self
):
211 SoCCore
.do_finalize(self
)
212 self
.specials
+= Instance(self
.ps7_name
, **self
.ps7_params
)
214 def generate_software_header(self
, filename
):
215 csr_header
= get_csr_header(self
.csr_regions
,
217 with_access_functions
=False)
218 tools
.write_to_file(filename
, csr_header
)