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"):
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
.mmio_wb
= mmio_wb
= wishbone
.Interface(data_width
=mmio_dw
, adr_width
=32-log2_int(mmio_dw
//8))
110 self
.periph_buses
= [mmio_wb
]
111 self
.memory_buses
= [mem_axi
]
115 self
.cpu_params
= dict(
117 i_clock
=ClockSignal(),
118 i_reset
=ResetSignal() | self
.reset
,
121 #o_debug_clockeddmi_dmi_req_ready = ,
122 i_debug_clockeddmi_dmi_req_valid
= 0,
123 i_debug_clockeddmi_dmi_req_bits_addr
= 0,
124 i_debug_clockeddmi_dmi_req_bits_data
= 0,
125 i_debug_clockeddmi_dmi_req_bits_op
= 0,
126 i_debug_clockeddmi_dmi_resp_ready
= 0,
127 #o_debug_clockeddmi_dmi_resp_valid = ,
128 #o_debug_clockeddmi_dmi_resp_bits_data = ,
129 #o_debug_clockeddmi_dmi_resp_bits_resp = ,
130 i_debug_clockeddmi_dmiClock
= 0,
131 i_debug_clockeddmi_dmiReset
= 0,
133 #o_debug_dmactive = ,
137 i_interrupts
=self
.interrupt
,
139 # axi memory (L1-cached)
140 i_mem_axi4_0_aw_ready
= mem_axi
.aw
.ready
,
141 o_mem_axi4_0_aw_valid
= mem_axi
.aw
.valid
,
142 o_mem_axi4_0_aw_bits_id
= mem_axi
.aw
.id,
143 o_mem_axi4_0_aw_bits_addr
= mem_axi
.aw
.addr
,
144 o_mem_axi4_0_aw_bits_len
= mem_axi
.aw
.len,
145 o_mem_axi4_0_aw_bits_size
= mem_axi
.aw
.size
,
146 o_mem_axi4_0_aw_bits_burst
= mem_axi
.aw
.burst
,
147 o_mem_axi4_0_aw_bits_lock
= mem_axi
.aw
.lock
,
148 o_mem_axi4_0_aw_bits_cache
= mem_axi
.aw
.cache
,
149 o_mem_axi4_0_aw_bits_prot
= mem_axi
.aw
.prot
,
150 o_mem_axi4_0_aw_bits_qos
= mem_axi
.aw
.qos
,
152 i_mem_axi4_0_w_ready
= mem_axi
.w
.ready
,
153 o_mem_axi4_0_w_valid
= mem_axi
.w
.valid
,
154 o_mem_axi4_0_w_bits_data
= mem_axi
.w
.data
,
155 o_mem_axi4_0_w_bits_strb
= mem_axi
.w
.strb
,
156 o_mem_axi4_0_w_bits_last
= mem_axi
.w
.last
,
158 o_mem_axi4_0_b_ready
= mem_axi
.b
.ready
,
159 i_mem_axi4_0_b_valid
= mem_axi
.b
.valid
,
160 i_mem_axi4_0_b_bits_id
= mem_axi
.b
.id,
161 i_mem_axi4_0_b_bits_resp
= mem_axi
.b
.resp
,
163 i_mem_axi4_0_ar_ready
= mem_axi
.ar
.ready
,
164 o_mem_axi4_0_ar_valid
= mem_axi
.ar
.valid
,
165 o_mem_axi4_0_ar_bits_id
= mem_axi
.ar
.id,
166 o_mem_axi4_0_ar_bits_addr
= mem_axi
.ar
.addr
,
167 o_mem_axi4_0_ar_bits_len
= mem_axi
.ar
.len,
168 o_mem_axi4_0_ar_bits_size
= mem_axi
.ar
.size
,
169 o_mem_axi4_0_ar_bits_burst
= mem_axi
.ar
.burst
,
170 o_mem_axi4_0_ar_bits_lock
= mem_axi
.ar
.lock
,
171 o_mem_axi4_0_ar_bits_cache
= mem_axi
.ar
.cache
,
172 o_mem_axi4_0_ar_bits_prot
= mem_axi
.ar
.prot
,
173 o_mem_axi4_0_ar_bits_qos
= mem_axi
.ar
.qos
,
175 o_mem_axi4_0_r_ready
= mem_axi
.r
.ready
,
176 i_mem_axi4_0_r_valid
= mem_axi
.r
.valid
,
177 i_mem_axi4_0_r_bits_id
= mem_axi
.r
.id,
178 i_mem_axi4_0_r_bits_data
= mem_axi
.r
.data
,
179 i_mem_axi4_0_r_bits_resp
= mem_axi
.r
.resp
,
180 i_mem_axi4_0_r_bits_last
= mem_axi
.r
.last
,
182 # axi mmio (not cached)
183 i_mmio_axi4_0_aw_ready
= mmio_axi
.aw
.ready
,
184 o_mmio_axi4_0_aw_valid
= mmio_axi
.aw
.valid
,
185 o_mmio_axi4_0_aw_bits_id
= mmio_axi
.aw
.id,
186 o_mmio_axi4_0_aw_bits_addr
= mmio_axi
.aw
.addr
,
187 o_mmio_axi4_0_aw_bits_len
= mmio_axi
.aw
.len,
188 o_mmio_axi4_0_aw_bits_size
= mmio_axi
.aw
.size
,
189 o_mmio_axi4_0_aw_bits_burst
= mmio_axi
.aw
.burst
,
190 o_mmio_axi4_0_aw_bits_lock
= mmio_axi
.aw
.lock
,
191 o_mmio_axi4_0_aw_bits_cache
= mmio_axi
.aw
.cache
,
192 o_mmio_axi4_0_aw_bits_prot
= mmio_axi
.aw
.prot
,
193 o_mmio_axi4_0_aw_bits_qos
= mmio_axi
.aw
.qos
,
195 i_mmio_axi4_0_w_ready
= mmio_axi
.w
.ready
,
196 o_mmio_axi4_0_w_valid
= mmio_axi
.w
.valid
,
197 o_mmio_axi4_0_w_bits_data
= mmio_axi
.w
.data
,
198 o_mmio_axi4_0_w_bits_strb
= mmio_axi
.w
.strb
,
199 o_mmio_axi4_0_w_bits_last
= mmio_axi
.w
.last
,
201 o_mmio_axi4_0_b_ready
= mmio_axi
.b
.ready
,
202 i_mmio_axi4_0_b_valid
= mmio_axi
.b
.valid
,
203 i_mmio_axi4_0_b_bits_id
= mmio_axi
.b
.id,
204 i_mmio_axi4_0_b_bits_resp
= mmio_axi
.b
.resp
,
206 i_mmio_axi4_0_ar_ready
= mmio_axi
.ar
.ready
,
207 o_mmio_axi4_0_ar_valid
= mmio_axi
.ar
.valid
,
208 o_mmio_axi4_0_ar_bits_id
= mmio_axi
.ar
.id,
209 o_mmio_axi4_0_ar_bits_addr
= mmio_axi
.ar
.addr
,
210 o_mmio_axi4_0_ar_bits_len
= mmio_axi
.ar
.len,
211 o_mmio_axi4_0_ar_bits_size
= mmio_axi
.ar
.size
,
212 o_mmio_axi4_0_ar_bits_burst
= mmio_axi
.ar
.burst
,
213 o_mmio_axi4_0_ar_bits_lock
= mmio_axi
.ar
.lock
,
214 o_mmio_axi4_0_ar_bits_cache
= mmio_axi
.ar
.cache
,
215 o_mmio_axi4_0_ar_bits_prot
= mmio_axi
.ar
.prot
,
216 o_mmio_axi4_0_ar_bits_qos
= mmio_axi
.ar
.qos
,
218 o_mmio_axi4_0_r_ready
= mmio_axi
.r
.ready
,
219 i_mmio_axi4_0_r_valid
= mmio_axi
.r
.valid
,
220 i_mmio_axi4_0_r_bits_id
= mmio_axi
.r
.id,
221 i_mmio_axi4_0_r_bits_data
= mmio_axi
.r
.data
,
222 i_mmio_axi4_0_r_bits_resp
= mmio_axi
.r
.resp
,
223 i_mmio_axi4_0_r_bits_last
= mmio_axi
.r
.last
,
226 # adapt axi interfaces to wishbone
227 # NOTE: AXI2Wishbone FSMs must be reset with the CPU!
228 mmio_a2w
= ResetInserter()(axi
.AXI2Wishbone(mmio_axi
, mmio_wb
,
230 self
.comb
+= mmio_a2w
.reset
.eq(ResetSignal() | self
.reset
)
231 self
.submodules
+= mmio_a2w
233 # add verilog sources
234 self
.add_sources(platform
, variant
)
236 def set_reset_address(self
, reset_address
):
237 assert not hasattr(self
, "reset_address")
238 self
.reset_address
= reset_address
239 assert reset_address
== 0x10000000, "cpu_reset_addr hardcoded in during elaboration!"
242 def add_sources(platform
, variant
="standard"):
243 vdir
= get_data_mod("cpu", "rocket").data_location
244 platform
.add_sources(
245 os
.path
.join(vdir
, "generated-src"),
246 CPU_VARIANTS
[variant
] + ".v",
247 CPU_VARIANTS
[variant
] + ".behav_srams.v",
249 platform
.add_sources(
250 os
.path
.join(vdir
, "vsrc"),
256 def do_finalize(self
):
257 assert hasattr(self
, "reset_address")
258 self
.specials
+= Instance("ExampleRocketSystem", **self
.cpu_params
)