cores/cpu/rocket: add use_memory_bus parameter to easily disable direct memory bus...
[litex.git] / litex / soc / cores / cpu / rocket / core.py
1 # litex/soc/cores/cpu/rocket/core.py
2 # Rocket Chip core support for the LiteX SoC.
3 #
4 # Author: Gabriel L. Somlo <somlo@cmu.edu>
5 # Copyright (c) 2019, Carnegie Mellon University
6 # All rights reserved.
7 #
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions are
10 # met:
11 #
12 # * Redistributions of source code must retain the above copyright
13 # notice, this list of conditions and the following disclaimer.
14 #
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.
19 #
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.
31
32 import os
33
34 from migen import *
35
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
40
41
42 CPU_VARIANTS = {
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",
48 }
49
50 GCC_FLAGS = {
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 ",
56 }
57
58 AXI_DATA_WIDTHS = {
59 # variant : (mem, mmio)
60 "standard": ( 64, 64),
61 "linux": ( 64, 64),
62 "linuxd": (128, 64),
63 "linuxq": (256, 64),
64 "full": ( 64, 64),
65 }
66
67 class RocketRV64(CPU):
68 name = "rocket"
69 human_name = "RocketRV64[imac]"
70 variants = CPU_VARIANTS
71 data_width = 64
72 endianness = "little"
73 gcc_triple = CPU_GCC_TRIPLE_RISCV64
74 linker_output_format = "elf64-littleriscv"
75 nop = "nop"
76 io_regions = {0x10000000: 0x70000000} # origin, length
77
78 @property
79 def mem_map(self):
80 # Rocket reserves the first 256Mbytes for internal use, so we must change default mem_map.
81 return {
82 "rom" : 0x10000000,
83 "sram" : 0x11000000,
84 "csr" : 0x12000000,
85 "ethmac" : 0x30000000,
86 "main_ram" : 0x80000000,
87 }
88
89 @property
90 def gcc_flags(self):
91 flags = "-mno-save-restore "
92 flags += GCC_FLAGS[self.variant]
93 flags += "-D__rocket__ "
94 return flags
95
96 def __init__(self, platform, variant="standard", use_memory_bus=True):
97 self.platform = platform
98 self.variant = variant
99
100 self.reset = Signal()
101 self.interrupt = Signal(4)
102
103 mem_dw, mmio_dw = AXI_DATA_WIDTHS[self.variant]
104
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)
107
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))
110
111 self.periph_buses = [mmio_wb]
112 self.memory_buses = []
113 if use_memory_bus:
114 self.memory_buses.append(self.mem_axi)
115 else:
116 self.periph_buses.append(self.mem_wb)
117
118 # # #
119
120 self.cpu_params = dict(
121 # clock, reset
122 i_clock=ClockSignal(),
123 i_reset=ResetSignal() | self.reset,
124
125 # debug (ignored)
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,
137 #o_debug_ndreset = ,
138 #o_debug_dmactive = ,
139
140
141 # irq
142 i_interrupts=self.interrupt,
143
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,
156
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,
162
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,
167
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,
179
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,
186
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,
199
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,
205
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,
210
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,
222
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,
229 )
230
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
236
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
241
242 # add verilog sources
243 self.add_sources(platform, variant)
244
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!"
249
250 @staticmethod
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",
257 )
258 platform.add_sources(
259 os.path.join(vdir, "vsrc"),
260 "plusarg_reader.v",
261 "AsyncResetReg.v",
262 "EICG_wrapper.v",
263 )
264
265 def do_finalize(self):
266 assert hasattr(self, "reset_address")
267 self.specials += Instance("ExampleRocketSystem", **self.cpu_params)