1 # litex/soc/cores/cpu/rocket/core.py
2 # Rocket Chip core support for the LiteX SoC.
4 # Author: Gabriel L. Somlo <somlo@cmu.edu>
5 # Copyright (c) 2019, Carnegie Mellon University
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions are
12 # * Redistributions of source code must retain the above copyright
13 # notice, this list of conditions and the following disclaimer.
15 # * Redistributions in binary form must reproduce the above
16 # copyright notice, this list of conditions and the following
17 # disclaimer in the documentation and/or other materials provided
18 # with the distribution.
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 from litex
import get_data_mod
37 from litex
.soc
.interconnect
import axi
38 from litex
.soc
.interconnect
import wishbone
39 from litex
.soc
.cores
.cpu
import CPU
, CPU_GCC_TRIPLE_RISCV64
43 "standard": "freechips.rocketchip.system.LitexConfig",
44 "linux": "freechips.rocketchip.system.LitexLinuxConfig",
45 "linuxd": "freechips.rocketchip.system.LitexLinuxDConfig",
46 "linuxq": "freechips.rocketchip.system.LitexLinuxQConfig",
47 "full": "freechips.rocketchip.system.LitexFullConfig",
51 "standard": "-march=rv64imac -mabi=lp64 ",
52 "linux": "-march=rv64imac -mabi=lp64 ",
53 "linuxd": "-march=rv64imac -mabi=lp64 ",
54 "linuxq": "-march=rv64imac -mabi=lp64 ",
55 "full": "-march=rv64imafdc -mabi=lp64 ",
59 # variant : (mem, mmio)
60 "standard": ( 64, 64),
67 class RocketRV64(CPU
):
69 human_name
= "RocketRV64[imac]"
70 variants
= CPU_VARIANTS
73 gcc_triple
= CPU_GCC_TRIPLE_RISCV64
74 linker_output_format
= "elf64-littleriscv"
76 io_regions
= {0x10000000: 0x70000000} # origin, length
80 # Rocket reserves the first 256Mbytes for internal use, so we must change default mem_map.
85 "ethmac" : 0x30000000,
86 "main_ram" : 0x80000000,
91 flags
= "-mno-save-restore "
92 flags
+= GCC_FLAGS
[self
.variant
]
93 flags
+= "-D__rocket__ "
96 def __init__(self
, platform
, variant
="standard", use_memory_bus
=True):
97 self
.platform
= platform
98 self
.variant
= variant
100 self
.reset
= Signal()
101 self
.interrupt
= Signal(4)
103 mem_dw
, mmio_dw
= AXI_DATA_WIDTHS
[self
.variant
]
105 self
.mem_axi
= mem_axi
= axi
.AXIInterface(data_width
= mem_dw
, address_width
=32, id_width
=4)
106 self
.mmio_axi
= mmio_axi
= axi
.AXIInterface(data_width
=mmio_dw
, address_width
=32, id_width
=4)
108 self
.mem_wb
= mem_wb
= wishbone
.Interface(data_width
=mem_dw
, adr_width
=32-log2_int(mem_dw
//8))
109 self
.mmio_wb
= mmio_wb
= wishbone
.Interface(data_width
=mmio_dw
, adr_width
=32-log2_int(mmio_dw
//8))
111 self
.periph_buses
= [mmio_wb
]
112 self
.memory_buses
= []
114 self
.memory_buses
.append(self
.mem_axi
)
116 self
.periph_buses
.append(self
.mem_wb
)
120 self
.cpu_params
= dict(
122 i_clock
=ClockSignal(),
123 i_reset
=ResetSignal() | self
.reset
,
126 #o_debug_clockeddmi_dmi_req_ready = ,
127 i_debug_clockeddmi_dmi_req_valid
= 0,
128 i_debug_clockeddmi_dmi_req_bits_addr
= 0,
129 i_debug_clockeddmi_dmi_req_bits_data
= 0,
130 i_debug_clockeddmi_dmi_req_bits_op
= 0,
131 i_debug_clockeddmi_dmi_resp_ready
= 0,
132 #o_debug_clockeddmi_dmi_resp_valid = ,
133 #o_debug_clockeddmi_dmi_resp_bits_data = ,
134 #o_debug_clockeddmi_dmi_resp_bits_resp = ,
135 i_debug_clockeddmi_dmiClock
= 0,
136 i_debug_clockeddmi_dmiReset
= 0,
138 #o_debug_dmactive = ,
142 i_interrupts
=self
.interrupt
,
144 # axi memory (L1-cached)
145 i_mem_axi4_0_aw_ready
= mem_axi
.aw
.ready
,
146 o_mem_axi4_0_aw_valid
= mem_axi
.aw
.valid
,
147 o_mem_axi4_0_aw_bits_id
= mem_axi
.aw
.id,
148 o_mem_axi4_0_aw_bits_addr
= mem_axi
.aw
.addr
,
149 o_mem_axi4_0_aw_bits_len
= mem_axi
.aw
.len,
150 o_mem_axi4_0_aw_bits_size
= mem_axi
.aw
.size
,
151 o_mem_axi4_0_aw_bits_burst
= mem_axi
.aw
.burst
,
152 o_mem_axi4_0_aw_bits_lock
= mem_axi
.aw
.lock
,
153 o_mem_axi4_0_aw_bits_cache
= mem_axi
.aw
.cache
,
154 o_mem_axi4_0_aw_bits_prot
= mem_axi
.aw
.prot
,
155 o_mem_axi4_0_aw_bits_qos
= mem_axi
.aw
.qos
,
157 i_mem_axi4_0_w_ready
= mem_axi
.w
.ready
,
158 o_mem_axi4_0_w_valid
= mem_axi
.w
.valid
,
159 o_mem_axi4_0_w_bits_data
= mem_axi
.w
.data
,
160 o_mem_axi4_0_w_bits_strb
= mem_axi
.w
.strb
,
161 o_mem_axi4_0_w_bits_last
= mem_axi
.w
.last
,
163 o_mem_axi4_0_b_ready
= mem_axi
.b
.ready
,
164 i_mem_axi4_0_b_valid
= mem_axi
.b
.valid
,
165 i_mem_axi4_0_b_bits_id
= mem_axi
.b
.id,
166 i_mem_axi4_0_b_bits_resp
= mem_axi
.b
.resp
,
168 i_mem_axi4_0_ar_ready
= mem_axi
.ar
.ready
,
169 o_mem_axi4_0_ar_valid
= mem_axi
.ar
.valid
,
170 o_mem_axi4_0_ar_bits_id
= mem_axi
.ar
.id,
171 o_mem_axi4_0_ar_bits_addr
= mem_axi
.ar
.addr
,
172 o_mem_axi4_0_ar_bits_len
= mem_axi
.ar
.len,
173 o_mem_axi4_0_ar_bits_size
= mem_axi
.ar
.size
,
174 o_mem_axi4_0_ar_bits_burst
= mem_axi
.ar
.burst
,
175 o_mem_axi4_0_ar_bits_lock
= mem_axi
.ar
.lock
,
176 o_mem_axi4_0_ar_bits_cache
= mem_axi
.ar
.cache
,
177 o_mem_axi4_0_ar_bits_prot
= mem_axi
.ar
.prot
,
178 o_mem_axi4_0_ar_bits_qos
= mem_axi
.ar
.qos
,
180 o_mem_axi4_0_r_ready
= mem_axi
.r
.ready
,
181 i_mem_axi4_0_r_valid
= mem_axi
.r
.valid
,
182 i_mem_axi4_0_r_bits_id
= mem_axi
.r
.id,
183 i_mem_axi4_0_r_bits_data
= mem_axi
.r
.data
,
184 i_mem_axi4_0_r_bits_resp
= mem_axi
.r
.resp
,
185 i_mem_axi4_0_r_bits_last
= mem_axi
.r
.last
,
187 # axi mmio (not cached)
188 i_mmio_axi4_0_aw_ready
= mmio_axi
.aw
.ready
,
189 o_mmio_axi4_0_aw_valid
= mmio_axi
.aw
.valid
,
190 o_mmio_axi4_0_aw_bits_id
= mmio_axi
.aw
.id,
191 o_mmio_axi4_0_aw_bits_addr
= mmio_axi
.aw
.addr
,
192 o_mmio_axi4_0_aw_bits_len
= mmio_axi
.aw
.len,
193 o_mmio_axi4_0_aw_bits_size
= mmio_axi
.aw
.size
,
194 o_mmio_axi4_0_aw_bits_burst
= mmio_axi
.aw
.burst
,
195 o_mmio_axi4_0_aw_bits_lock
= mmio_axi
.aw
.lock
,
196 o_mmio_axi4_0_aw_bits_cache
= mmio_axi
.aw
.cache
,
197 o_mmio_axi4_0_aw_bits_prot
= mmio_axi
.aw
.prot
,
198 o_mmio_axi4_0_aw_bits_qos
= mmio_axi
.aw
.qos
,
200 i_mmio_axi4_0_w_ready
= mmio_axi
.w
.ready
,
201 o_mmio_axi4_0_w_valid
= mmio_axi
.w
.valid
,
202 o_mmio_axi4_0_w_bits_data
= mmio_axi
.w
.data
,
203 o_mmio_axi4_0_w_bits_strb
= mmio_axi
.w
.strb
,
204 o_mmio_axi4_0_w_bits_last
= mmio_axi
.w
.last
,
206 o_mmio_axi4_0_b_ready
= mmio_axi
.b
.ready
,
207 i_mmio_axi4_0_b_valid
= mmio_axi
.b
.valid
,
208 i_mmio_axi4_0_b_bits_id
= mmio_axi
.b
.id,
209 i_mmio_axi4_0_b_bits_resp
= mmio_axi
.b
.resp
,
211 i_mmio_axi4_0_ar_ready
= mmio_axi
.ar
.ready
,
212 o_mmio_axi4_0_ar_valid
= mmio_axi
.ar
.valid
,
213 o_mmio_axi4_0_ar_bits_id
= mmio_axi
.ar
.id,
214 o_mmio_axi4_0_ar_bits_addr
= mmio_axi
.ar
.addr
,
215 o_mmio_axi4_0_ar_bits_len
= mmio_axi
.ar
.len,
216 o_mmio_axi4_0_ar_bits_size
= mmio_axi
.ar
.size
,
217 o_mmio_axi4_0_ar_bits_burst
= mmio_axi
.ar
.burst
,
218 o_mmio_axi4_0_ar_bits_lock
= mmio_axi
.ar
.lock
,
219 o_mmio_axi4_0_ar_bits_cache
= mmio_axi
.ar
.cache
,
220 o_mmio_axi4_0_ar_bits_prot
= mmio_axi
.ar
.prot
,
221 o_mmio_axi4_0_ar_bits_qos
= mmio_axi
.ar
.qos
,
223 o_mmio_axi4_0_r_ready
= mmio_axi
.r
.ready
,
224 i_mmio_axi4_0_r_valid
= mmio_axi
.r
.valid
,
225 i_mmio_axi4_0_r_bits_id
= mmio_axi
.r
.id,
226 i_mmio_axi4_0_r_bits_data
= mmio_axi
.r
.data
,
227 i_mmio_axi4_0_r_bits_resp
= mmio_axi
.r
.resp
,
228 i_mmio_axi4_0_r_bits_last
= mmio_axi
.r
.last
,
231 # adapt axi interfaces to wishbone
232 # NOTE: AXI2Wishbone FSMs must be reset with the CPU!
233 mmio_a2w
= ResetInserter()(axi
.AXI2Wishbone(mmio_axi
, mmio_wb
, base_address
=0))
234 self
.comb
+= mmio_a2w
.reset
.eq(ResetSignal() | self
.reset
)
235 self
.submodules
+= mmio_a2w
237 if not use_memory_bus
:
238 mem_a2w
= ResetInserter()(axi
.AXI2Wishbone(mem_axi
, mem_wb
, base_address
=0))
239 self
.comb
+= mem_a2w
.reset
.eq(ResetSignal() | self
.reset
)
240 self
.submodules
+= mem_a2w
242 # add verilog sources
243 self
.add_sources(platform
, variant
)
245 def set_reset_address(self
, reset_address
):
246 assert not hasattr(self
, "reset_address")
247 self
.reset_address
= reset_address
248 assert reset_address
== 0x10000000, "cpu_reset_addr hardcoded in during elaboration!"
251 def add_sources(platform
, variant
="standard"):
252 vdir
= get_data_mod("cpu", "rocket").data_location
253 platform
.add_sources(
254 os
.path
.join(vdir
, "generated-src"),
255 CPU_VARIANTS
[variant
] + ".v",
256 CPU_VARIANTS
[variant
] + ".behav_srams.v",
258 platform
.add_sources(
259 os
.path
.join(vdir
, "vsrc"),
265 def do_finalize(self
):
266 assert hasattr(self
, "reset_address")
267 self
.specials
+= Instance("ExampleRocketSystem", **self
.cpu_params
)