d90787ca362f4aae4583f6c28bd85b5e3199f939
[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"):
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.mmio_wb = mmio_wb = wishbone.Interface(data_width=mmio_dw, adr_width=32-log2_int(mmio_dw//8))
109
110 self.periph_buses = [mmio_wb]
111 self.memory_buses = [mem_axi]
112
113 # # #
114
115 self.cpu_params = dict(
116 # clock, reset
117 i_clock=ClockSignal(),
118 i_reset=ResetSignal() | self.reset,
119
120 # debug (ignored)
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,
132 #o_debug_ndreset = ,
133 #o_debug_dmactive = ,
134
135
136 # irq
137 i_interrupts=self.interrupt,
138
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,
151
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,
157
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,
162
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,
174
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,
181
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,
194
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,
200
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,
205
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,
217
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,
224 )
225
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,
229 base_address=0))
230 self.comb += mmio_a2w.reset.eq(ResetSignal() | self.reset)
231 self.submodules += mmio_a2w
232
233 # add verilog sources
234 self.add_sources(platform, variant)
235
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!"
240
241 @staticmethod
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",
248 )
249 platform.add_sources(
250 os.path.join(vdir, "vsrc"),
251 "plusarg_reader.v",
252 "AsyncResetReg.v",
253 "EICG_wrapper.v",
254 )
255
256 def do_finalize(self):
257 assert hasattr(self, "reset_address")
258 self.specials += Instance("ExampleRocketSystem", **self.cpu_params)