51e94e6dc1a74e8b1601b3fa91b46903b249e17b
[soc.git] / src / soc / minerva / core.py
1 from functools import reduce
2 from operator import or_
3 from itertools import tee
4
5 from nmigen import Elaboratable, Module, Record, Mux, Const, Signal, Memory
6 from nmigen.lib.coding import PriorityEncoder
7
8 from soc.minerva.stage import Stage
9 from soc.minerva.csr import CSRFile
10 from soc.minerva.units.adder import Adder
11 from soc.minerva.units.compare import CompareUnit
12 from soc.minerva.units.debug import DebugUnit
13 from soc.minerva.units.decoder import InstructionDecoder
14 from soc.minerva.units.divider import Divider, DummyDivider
15 from soc.minerva.units.exception import ExceptionUnit
16 from soc.minerva.units.fetch import BareFetchUnit, CachedFetchUnit, PCSelector
17 from soc.minerva.units.rvficon import RVFIController, rvfi_layout
18 from soc.minerva.units.loadstore import (BareLoadStoreUnit, CachedLoadStoreUnit,
19 DataSelector)
20 from soc.minerva.units.logic import LogicUnit
21 from soc.minerva.units.multiplier import DummyMultiplier, Multiplier
22 from soc.minerva.units.predict import BranchPredictor
23 from soc.minerva.units.shifter import Shifter
24 from soc.minerva.units.trigger import TriggerUnit
25
26 from soc.minerva.units.debug.jtag import jtag_layout
27 from soc.minerva.wishbone import wishbone_layout
28
29
30 __all__ = ["Minerva"]
31
32
33 _af_layout = [
34 ("pc", (33, True)),
35 ]
36
37
38 _fd_layout = [
39 ("pc", 32),
40 ("instruction", 32),
41 ("fetch_error", 1),
42 ("fetch_badaddr", 30)
43 ]
44
45
46 _dx_layout = [
47 ("pc", 32),
48 ("instruction", 32),
49 ("fetch_error", 1),
50 ("fetch_badaddr", 30),
51 ("illegal", 1),
52 ("rd", 5),
53 ("rs1", 5),
54 ("rd_we", 1),
55 ("rs1_re", 1),
56 ("src1", 32),
57 ("src2", 32),
58 ("immediate", 32),
59 ("bypass_x", 1),
60 ("bypass_m", 1),
61 ("funct3", 3),
62 ("load", 1),
63 ("store", 1),
64 ("adder", 1),
65 ("adder_sub", 1),
66 ("logic", 1),
67 ("multiply", 1),
68 ("divide", 1),
69 ("shift", 1),
70 ("direction", 1),
71 ("sext", 1),
72 ("jump", 1),
73 ("compare", 1),
74 ("branch", 1),
75 ("branch_target", 32),
76 ("branch_predict_taken", 1),
77 ("fence_i", 1),
78 ("csr", 1),
79 ("csr_adr", 12),
80 ("csr_we", 1),
81 ("ecall", 1),
82 ("ebreak", 1),
83 ("mret", 1),
84 ]
85
86
87 _xm_layout = [
88 ("pc", 32),
89 ("instruction", 32),
90 ("fetch_error", 1),
91 ("fetch_badaddr", 30),
92 ("illegal", 1),
93 ("loadstore_misaligned", 1),
94 ("ecall", 1),
95 ("ebreak", 1),
96 ("rd", 5),
97 ("rd_we", 1),
98 ("bypass_m", 1),
99 ("funct3", 3),
100 ("result", 32),
101 ("shift", 1),
102 ("load", 1),
103 ("store", 1),
104 ("store_data", 32),
105 ("compare", 1),
106 ("multiply", 1),
107 ("divide", 1),
108 ("condition_met", 1),
109 ("branch_target", 32),
110 ("branch_taken", 1),
111 ("branch_predict_taken", 1),
112 ("csr", 1),
113 ("csr_adr", 12),
114 ("csr_we", 1),
115 ("csr_result", 32),
116 ("mret", 1),
117 ("exception", 1)
118 ]
119
120
121 _mw_layout = [
122 ("pc", 32),
123 ("rd", 5),
124 ("rd_we", 1),
125 ("funct3", 3),
126 ("result", 32),
127 ("load", 1),
128 ("load_data", 32),
129 ("multiply", 1),
130 ("exception", 1)
131 ]
132
133
134 class Minerva(Elaboratable):
135 def __init__(self, reset_address=0x00000000,
136 with_icache=False,
137 icache_nways=1, icache_nlines=256, icache_nwords=8, icache_base=0, icache_limit=2**31,
138 with_dcache=False,
139 dcache_nways=1, dcache_nlines=256, dcache_nwords=8, dcache_base=0, dcache_limit=2**31,
140 with_muldiv=False,
141 with_debug=False,
142 with_trigger=False, nb_triggers=8,
143 with_rvfi=False):
144 self.external_interrupt = Signal(32)
145 self.timer_interrupt = Signal()
146 self.software_interrupt = Signal()
147 self.ibus = Record(wishbone_layout)
148 self.dbus = Record(wishbone_layout)
149
150 if with_debug:
151 self.jtag = Record(jtag_layout)
152
153 if with_rvfi:
154 self.rvfi = Record(rvfi_layout)
155
156 self.reset_address = reset_address
157 self.with_icache = with_icache
158 self.icache_args = icache_nways, icache_nlines, icache_nwords, icache_base, icache_limit
159 self.with_dcache = with_dcache
160 self.dcache_args = dcache_nways, dcache_nlines, dcache_nwords, dcache_base, dcache_limit
161 self.with_muldiv = with_muldiv
162 self.with_debug = with_debug
163 self.with_trigger = with_trigger
164 self.nb_triggers = nb_triggers
165 self.with_rvfi = with_rvfi
166
167 def elaborate(self, platform):
168 cpu = Module()
169
170 # pipeline stages
171
172 a = cpu.submodules.a = Stage(None, _af_layout)
173 f = cpu.submodules.f = Stage(_af_layout, _fd_layout)
174 d = cpu.submodules.d = Stage(_fd_layout, _dx_layout)
175 x = cpu.submodules.x = Stage(_dx_layout, _xm_layout)
176 m = cpu.submodules.m = Stage(_xm_layout, _mw_layout)
177 w = cpu.submodules.w = Stage(_mw_layout, None)
178 stages = a, f, d, x, m, w
179
180 sources, sinks = tee(stages)
181 next(sinks)
182 for s1, s2 in zip(sources, sinks):
183 cpu.d.comb += s1.source.connect(s2.sink)
184
185 a.source.pc.reset = self.reset_address - 4
186 cpu.d.comb += a.valid.eq(Const(1))
187
188 # units
189
190 pc_sel = cpu.submodules.pc_sel = PCSelector()
191 data_sel = cpu.submodules.data_sel = DataSelector()
192 adder = cpu.submodules.adder = Adder()
193 compare = cpu.submodules.compare = CompareUnit()
194 decoder = cpu.submodules.decoder = InstructionDecoder(self.with_muldiv)
195 exception = cpu.submodules.exception = ExceptionUnit()
196 logic = cpu.submodules.logic = LogicUnit()
197 predict = cpu.submodules.predict = BranchPredictor()
198 shifter = cpu.submodules.shifter = Shifter()
199
200 if self.with_icache:
201 fetch = cpu.submodules.fetch = CachedFetchUnit(*self.icache_args)
202 else:
203 fetch = cpu.submodules.fetch = BareFetchUnit()
204
205 if self.with_dcache:
206 loadstore = cpu.submodules.loadstore = CachedLoadStoreUnit(*self.dcache_args)
207 else:
208 loadstore = cpu.submodules.loadstore = BareLoadStoreUnit()
209
210 if self.with_muldiv:
211 multiplier = Multiplier() if not self.with_rvfi else DummyMultiplier()
212 divider = Divider() if not self.with_rvfi else DummyDivider()
213 cpu.submodules.multiplier = multiplier
214 cpu.submodules.divider = divider
215
216 if self.with_debug:
217 debug = cpu.submodules.debug = DebugUnit()
218
219 if self.with_trigger:
220 trigger = cpu.submodules.trigger = TriggerUnit(self.nb_triggers)
221
222 if self.with_rvfi:
223 rvficon = cpu.submodules.rvficon = RVFIController()
224
225 # register files
226
227 gprf = Memory(width=32, depth=32)
228 gprf_rp1 = gprf.read_port()
229 gprf_rp2 = gprf.read_port()
230 gprf_wp = gprf.write_port()
231 cpu.submodules += gprf_rp1, gprf_rp2, gprf_wp
232
233 csrf = cpu.submodules.csrf = CSRFile()
234 csrf_rp = csrf.read_port()
235 csrf_wp = csrf.write_port()
236
237 csrf.add_csrs(exception.iter_csrs())
238 if self.with_debug:
239 csrf.add_csrs(debug.iter_csrs())
240 if self.with_trigger:
241 csrf.add_csrs(trigger.iter_csrs())
242
243 # pipeline logic
244
245 cpu.d.comb += [
246 pc_sel.f_pc.eq(f.sink.pc),
247 pc_sel.d_pc.eq(d.sink.pc),
248 pc_sel.d_branch_predict_taken.eq(predict.d_branch_taken & ~predict.d_fetch_misaligned),
249 pc_sel.d_branch_target.eq(predict.d_branch_target),
250 pc_sel.d_valid.eq(d.valid),
251 pc_sel.x_pc.eq(x.sink.pc),
252 pc_sel.x_fence_i.eq(x.sink.fence_i),
253 pc_sel.x_valid.eq(x.valid),
254 pc_sel.m_branch_predict_taken.eq(m.sink.branch_predict_taken),
255 pc_sel.m_branch_taken.eq(m.sink.branch_taken),
256 pc_sel.m_branch_target.eq(m.sink.branch_target),
257 pc_sel.m_exception.eq(exception.m_raise),
258 pc_sel.m_mret.eq(m.sink.mret),
259 pc_sel.m_valid.eq(m.valid),
260 pc_sel.mtvec_r_base.eq(exception.mtvec.r.base),
261 pc_sel.mepc_r_base.eq(exception.mepc.r.base)
262 ]
263
264 cpu.d.comb += [
265 fetch.a_pc.eq(pc_sel.a_pc),
266 fetch.a_stall.eq(a.stall),
267 fetch.a_valid.eq(a.valid),
268 fetch.f_stall.eq(f.stall),
269 fetch.f_valid.eq(f.valid),
270 fetch.ibus.connect(self.ibus)
271 ]
272
273 m.stall_on(fetch.a_busy & a.valid)
274 m.stall_on(fetch.f_busy & f.valid)
275
276 if self.with_icache:
277 flush_icache = x.sink.fence_i & x.valid & ~x.stall
278 if self.with_debug:
279 flush_icache |= debug.resumereq
280
281 cpu.d.comb += [
282 fetch.a_flush.eq(flush_icache),
283 fetch.f_pc.eq(f.sink.pc)
284 ]
285
286 cpu.d.comb += [
287 decoder.instruction.eq(d.sink.instruction)
288 ]
289
290 if self.with_debug:
291 with cpu.If(debug.halt & debug.halted):
292 cpu.d.comb += gprf_rp1.addr.eq(debug.gprf_addr)
293 with cpu.Elif(~d.stall):
294 cpu.d.comb += gprf_rp1.addr.eq(fetch.f_instruction[15:20])
295 with cpu.Else():
296 cpu.d.comb += gprf_rp1.addr.eq(decoder.rs1)
297
298 cpu.d.comb += debug.gprf_dat_r.eq(gprf_rp1.data)
299 else:
300 with cpu.If(~d.stall):
301 cpu.d.comb += gprf_rp1.addr.eq(fetch.f_instruction[15:20])
302 with cpu.Else():
303 cpu.d.comb += gprf_rp1.addr.eq(decoder.rs1)
304
305 with cpu.If(~d.stall):
306 cpu.d.comb += gprf_rp2.addr.eq(fetch.f_instruction[20:25])
307 with cpu.Else():
308 cpu.d.comb += gprf_rp2.addr.eq(decoder.rs2)
309
310 with cpu.If(~f.stall):
311 cpu.d.sync += csrf_rp.addr.eq(fetch.f_instruction[20:32])
312 cpu.d.comb += csrf_rp.en.eq(decoder.csr & d.valid)
313
314 # CSR set/clear instructions are translated to logic operations.
315 x_csr_set_clear = x.sink.funct3[1]
316 x_csr_clear = x_csr_set_clear & x.sink.funct3[0]
317 x_csr_fmt_i = x.sink.funct3[2]
318 x_csr_src1 = Mux(x_csr_fmt_i, x.sink.rs1, x.sink.src1)
319 x_csr_src1 = Mux(x_csr_clear, ~x_csr_src1, x_csr_src1)
320 x_csr_logic_op = x.sink.funct3 | 0b100
321
322 cpu.d.comb += [
323 logic.op.eq(Mux(x.sink.csr, x_csr_logic_op, x.sink.funct3)),
324 logic.src1.eq(Mux(x.sink.csr, x_csr_src1, x.sink.src1)),
325 logic.src2.eq(x.sink.src2)
326 ]
327
328 cpu.d.comb += [
329 adder.sub.eq(x.sink.adder & x.sink.adder_sub | x.sink.compare | x.sink.branch),
330 adder.src1.eq(x.sink.src1),
331 adder.src2.eq(Mux(x.sink.store, x.sink.immediate, x.sink.src2))
332 ]
333
334 if self.with_muldiv:
335 cpu.d.comb += [
336 multiplier.x_op.eq(x.sink.funct3),
337 multiplier.x_src1.eq(x.sink.src1),
338 multiplier.x_src2.eq(x.sink.src2),
339 multiplier.x_stall.eq(x.stall),
340 multiplier.m_stall.eq(m.stall)
341 ]
342
343 cpu.d.comb += [
344 divider.x_op.eq(x.sink.funct3),
345 divider.x_src1.eq(x.sink.src1),
346 divider.x_src2.eq(x.sink.src2),
347 divider.x_valid.eq(x.sink.valid),
348 divider.x_stall.eq(x.stall)
349 ]
350
351 m.stall_on(divider.m_busy)
352
353 cpu.d.comb += [
354 shifter.x_direction.eq(x.sink.direction),
355 shifter.x_sext.eq(x.sink.sext),
356 shifter.x_shamt.eq(x.sink.src2),
357 shifter.x_src1.eq(x.sink.src1),
358 shifter.x_stall.eq(x.stall)
359 ]
360
361 cpu.d.comb += [
362 # compare.op is shared by compare and branch instructions.
363 compare.op.eq(Mux(x.sink.compare, x.sink.funct3 << 1, x.sink.funct3)),
364 compare.zero.eq(x.sink.src1 == x.sink.src2),
365 compare.negative.eq(adder.result[-1]),
366 compare.overflow.eq(adder.overflow),
367 compare.carry.eq(adder.carry)
368 ]
369
370 cpu.d.comb += [
371 exception.external_interrupt.eq(self.external_interrupt),
372 exception.timer_interrupt.eq(self.timer_interrupt),
373 exception.software_interrupt.eq(self.software_interrupt),
374 exception.m_fetch_misaligned.eq(m.sink.branch_taken & m.sink.branch_target[:2].bool()),
375 exception.m_fetch_error.eq(m.sink.fetch_error),
376 exception.m_fetch_badaddr.eq(m.sink.fetch_badaddr),
377 exception.m_load_misaligned.eq(m.sink.load & m.sink.loadstore_misaligned),
378 exception.m_load_error.eq(loadstore.m_load_error),
379 exception.m_store_misaligned.eq(m.sink.store & m.sink.loadstore_misaligned),
380 exception.m_store_error.eq(loadstore.m_store_error),
381 exception.m_loadstore_badaddr.eq(loadstore.m_badaddr),
382 exception.m_branch_target.eq(m.sink.branch_target),
383 exception.m_illegal.eq(m.sink.illegal),
384 exception.m_ecall.eq(m.sink.ecall),
385 exception.m_pc.eq(m.sink.pc),
386 exception.m_instruction.eq(m.sink.instruction),
387 exception.m_result.eq(m.sink.result),
388 exception.m_mret.eq(m.sink.mret),
389 exception.m_stall.eq(m.sink.stall),
390 exception.m_valid.eq(m.valid)
391 ]
392
393 m_ebreak = m.sink.ebreak
394 if self.with_debug:
395 # If dcsr.ebreakm is set, EBREAK instructions enter Debug Mode.
396 # We do not want to raise an exception in this case because Debug Mode
397 # should be invisible to software execution.
398 m_ebreak &= ~debug.dcsr_ebreakm
399 if self.with_trigger:
400 m_ebreak |= trigger.trap
401 cpu.d.comb += exception.m_ebreak.eq(m_ebreak)
402
403 m.kill_on(m.source.exception & m.source.valid)
404
405 cpu.d.comb += [
406 data_sel.x_offset.eq(adder.result[:2]),
407 data_sel.x_funct3.eq(x.sink.funct3),
408 data_sel.x_store_operand.eq(x.sink.src2),
409 data_sel.w_offset.eq(w.sink.result[:2]),
410 data_sel.w_funct3.eq(w.sink.funct3),
411 data_sel.w_load_data.eq(w.sink.load_data)
412 ]
413
414 cpu.d.comb += [
415 loadstore.x_addr.eq(adder.result),
416 loadstore.x_mask.eq(data_sel.x_mask),
417 loadstore.x_load.eq(x.sink.load),
418 loadstore.x_store.eq(x.sink.store),
419 loadstore.x_store_data.eq(data_sel.x_store_data),
420 loadstore.x_stall.eq(x.stall),
421 loadstore.x_valid.eq(x.valid),
422 loadstore.m_stall.eq(m.stall),
423 loadstore.m_valid.eq(m.valid)
424 ]
425
426 m.stall_on(loadstore.x_busy & x.valid)
427 m.stall_on(loadstore.m_busy & m.valid)
428
429 if self.with_dcache:
430 if self.with_debug:
431 cpu.d.comb += loadstore.x_flush.eq(debug.resumereq)
432
433 cpu.d.comb += [
434 loadstore.x_fence_i.eq(x.sink.fence_i),
435 loadstore.m_addr.eq(m.sink.result),
436 loadstore.m_load.eq(m.sink.load),
437 loadstore.m_store.eq(m.sink.store),
438 ]
439
440 x.stall_on(loadstore.x_busy & x.valid)
441
442 for s in a, f:
443 s.kill_on(x.sink.fence_i & x.valid)
444
445 if self.with_debug:
446 with cpu.If(debug.halt & debug.halted):
447 cpu.d.comb += debug.dbus.connect(self.dbus)
448 with cpu.Else():
449 cpu.d.comb += loadstore.dbus.connect(self.dbus)
450 else:
451 cpu.d.comb += loadstore.dbus.connect(self.dbus)
452
453 # RAW hazard management
454
455 x_raw_rs1 = Signal()
456 m_raw_rs1 = Signal()
457 w_raw_rs1 = Signal()
458 x_raw_rs2 = Signal()
459 m_raw_rs2 = Signal()
460 w_raw_rs2 = Signal()
461
462 x_raw_csr = Signal()
463 m_raw_csr = Signal()
464
465 x_lock = Signal()
466 m_lock = Signal()
467
468 cpu.d.comb += [
469 x_raw_rs1.eq((x.sink.rd != 0) & (x.sink.rd == decoder.rs1) & x.sink.rd_we),
470 m_raw_rs1.eq((m.sink.rd != 0) & (m.sink.rd == decoder.rs1) & m.sink.rd_we),
471 w_raw_rs1.eq((w.sink.rd != 0) & (w.sink.rd == decoder.rs1) & w.sink.rd_we),
472
473 x_raw_rs2.eq((x.sink.rd != 0) & (x.sink.rd == decoder.rs2) & x.sink.rd_we),
474 m_raw_rs2.eq((m.sink.rd != 0) & (m.sink.rd == decoder.rs2) & m.sink.rd_we),
475 w_raw_rs2.eq((w.sink.rd != 0) & (w.sink.rd == decoder.rs2) & w.sink.rd_we),
476
477 x_raw_csr.eq((x.sink.csr_adr == decoder.immediate) & x.sink.csr_we),
478 m_raw_csr.eq((m.sink.csr_adr == decoder.immediate) & m.sink.csr_we),
479
480 x_lock.eq(~x.sink.bypass_x & (decoder.rs1_re & x_raw_rs1 | decoder.rs2_re & x_raw_rs2) | decoder.csr & x_raw_csr),
481 m_lock.eq(~m.sink.bypass_m & (decoder.rs1_re & m_raw_rs1 | decoder.rs2_re & m_raw_rs2) | decoder.csr & m_raw_csr)
482 ]
483
484 if self.with_debug:
485 d.stall_on((x_lock & x.valid | m_lock & m.valid) & d.valid & ~debug.dcsr_step)
486 else:
487 d.stall_on((x_lock & x.valid | m_lock & m.valid) & d.valid)
488
489 # result selection
490
491 x_result = Signal(32)
492 m_result = Signal(32)
493 w_result = Signal(32)
494 x_csr_result = Signal(32)
495
496 with cpu.If(x.sink.jump):
497 cpu.d.comb += x_result.eq(x.sink.pc + 4)
498 with cpu.Elif(x.sink.logic):
499 cpu.d.comb += x_result.eq(logic.result)
500 with cpu.Elif(x.sink.csr):
501 cpu.d.comb += x_result.eq(x.sink.src2)
502 with cpu.Else():
503 cpu.d.comb += x_result.eq(adder.result)
504
505 with cpu.If(m.sink.compare):
506 cpu.d.comb += m_result.eq(m.sink.condition_met)
507 if self.with_muldiv:
508 with cpu.Elif(m.sink.divide):
509 cpu.d.comb += m_result.eq(divider.m_result)
510 with cpu.Elif(m.sink.shift):
511 cpu.d.comb += m_result.eq(shifter.m_result)
512 with cpu.Else():
513 cpu.d.comb += m_result.eq(m.sink.result)
514
515 with cpu.If(w.sink.load):
516 cpu.d.comb += w_result.eq(data_sel.w_load_result)
517 if self.with_muldiv:
518 with cpu.Elif(w.sink.multiply):
519 cpu.d.comb += w_result.eq(multiplier.w_result)
520 with cpu.Else():
521 cpu.d.comb += w_result.eq(w.sink.result)
522
523 with cpu.If(x_csr_set_clear):
524 cpu.d.comb += x_csr_result.eq(logic.result)
525 with cpu.Else():
526 cpu.d.comb += x_csr_result.eq(x_csr_src1)
527
528 cpu.d.comb += [
529 csrf_wp.en.eq(m.sink.csr & m.sink.csr_we & m.valid & ~exception.m_raise & ~m.stall),
530 csrf_wp.addr.eq(m.sink.csr_adr),
531 csrf_wp.data.eq(m.sink.csr_result)
532 ]
533
534 if self.with_debug:
535 with cpu.If(debug.halt & debug.halted):
536 cpu.d.comb += [
537 gprf_wp.addr.eq(debug.gprf_addr),
538 gprf_wp.en.eq(debug.gprf_we),
539 gprf_wp.data.eq(debug.gprf_dat_w)
540 ]
541 with cpu.Else():
542 cpu.d.comb += [
543 gprf_wp.en.eq((w.sink.rd != 0) & w.sink.rd_we & w.valid & ~w.sink.exception),
544 gprf_wp.addr.eq(w.sink.rd),
545 gprf_wp.data.eq(w_result)
546 ]
547 else:
548 cpu.d.comb += [
549 gprf_wp.en.eq((w.sink.rd != 0) & w.sink.rd_we & w.valid),
550 gprf_wp.addr.eq(w.sink.rd),
551 gprf_wp.data.eq(w_result)
552 ]
553
554 # D stage operand selection
555
556 d_src1 = Signal(32)
557 d_src2 = Signal(32)
558
559 with cpu.If(decoder.lui):
560 cpu.d.comb += d_src1.eq(0)
561 with cpu.Elif(decoder.auipc):
562 cpu.d.comb += d_src1.eq(d.sink.pc)
563 with cpu.Elif(decoder.rs1_re & (decoder.rs1 == 0)):
564 cpu.d.comb += d_src1.eq(0)
565 with cpu.Elif(x_raw_rs1 & x.valid):
566 cpu.d.comb += d_src1.eq(x_result)
567 with cpu.Elif(m_raw_rs1 & m.valid):
568 cpu.d.comb += d_src1.eq(m_result)
569 with cpu.Elif(w_raw_rs1 & w.valid):
570 cpu.d.comb += d_src1.eq(w_result)
571 with cpu.Else():
572 cpu.d.comb += d_src1.eq(gprf_rp1.data)
573
574 with cpu.If(decoder.csr):
575 cpu.d.comb += d_src2.eq(csrf_rp.data)
576 with cpu.Elif(~decoder.rs2_re):
577 cpu.d.comb += d_src2.eq(decoder.immediate)
578 with cpu.Elif(decoder.rs2 == 0):
579 cpu.d.comb += d_src2.eq(0)
580 with cpu.Elif(x_raw_rs2 & x.valid):
581 cpu.d.comb += d_src2.eq(x_result)
582 with cpu.Elif(m_raw_rs2 & m.valid):
583 cpu.d.comb += d_src2.eq(m_result)
584 with cpu.Elif(w_raw_rs2 & w.valid):
585 cpu.d.comb += d_src2.eq(w_result)
586 with cpu.Else():
587 cpu.d.comb += d_src2.eq(gprf_rp2.data)
588
589 # branch prediction
590
591 cpu.d.comb += [
592 predict.d_branch.eq(decoder.branch),
593 predict.d_jump.eq(decoder.jump),
594 predict.d_offset.eq(decoder.immediate),
595 predict.d_pc.eq(d.sink.pc),
596 predict.d_rs1_re.eq(decoder.rs1_re)
597 ]
598
599 a.kill_on(predict.d_branch_taken & ~predict.d_fetch_misaligned & d.valid)
600 for s in a, f:
601 s.kill_on(m.sink.branch_predict_taken & ~m.sink.branch_taken & m.valid)
602 for s in a, f, d:
603 s.kill_on(~m.sink.branch_predict_taken & m.sink.branch_taken & m.valid)
604 s.kill_on((exception.m_raise | m.sink.mret) & m.valid)
605
606 # debug unit
607
608 if self.with_debug:
609 cpu.d.comb += [
610 debug.jtag.connect(self.jtag),
611 debug.x_pc.eq(x.sink.pc),
612 debug.x_ebreak.eq(x.sink.ebreak),
613 debug.x_stall.eq(x.stall),
614 debug.m_branch_taken.eq(m.sink.branch_taken),
615 debug.m_branch_target.eq(m.sink.branch_target),
616 debug.m_mret.eq(m.sink.mret),
617 debug.m_exception.eq(exception.m_raise),
618 debug.m_pc.eq(m.sink.pc),
619 debug.m_valid.eq(m.valid),
620 debug.mepc_r_base.eq(exception.mepc.r.base),
621 debug.mtvec_r_base.eq(exception.mtvec.r.base)
622 ]
623
624 if self.with_trigger:
625 cpu.d.comb += debug.trigger_haltreq.eq(trigger.haltreq)
626 else:
627 cpu.d.comb += debug.trigger_haltreq.eq(Const(0))
628
629 csrf_debug_rp = csrf.read_port()
630 csrf_debug_wp = csrf.write_port()
631 cpu.d.comb += [
632 csrf_debug_rp.addr.eq(debug.csrf_addr),
633 csrf_debug_rp.en.eq(debug.csrf_re),
634 debug.csrf_dat_r.eq(csrf_debug_rp.data),
635 csrf_debug_wp.addr.eq(debug.csrf_addr),
636 csrf_debug_wp.en.eq(debug.csrf_we),
637 csrf_debug_wp.data.eq(debug.csrf_dat_w)
638 ]
639
640 x.stall_on(debug.halt)
641 m.stall_on(debug.dcsr_step & m.valid & ~debug.halt)
642 for s in a, f, d, x:
643 s.kill_on(debug.killall)
644
645 halted = x.stall & ~reduce(or_, (s.valid for s in (m, w)))
646 cpu.d.sync += debug.halted.eq(halted)
647
648 with cpu.If(debug.resumereq):
649 with cpu.If(~debug.dbus_busy):
650 cpu.d.comb += debug.resumeack.eq(1)
651 cpu.d.sync += a.source.pc.eq(debug.dpc_value - 4)
652
653 if self.with_trigger:
654 cpu.d.comb += [
655 trigger.x_pc.eq(x.sink.pc),
656 trigger.x_valid.eq(x.valid),
657 ]
658
659 if self.with_rvfi:
660 cpu.d.comb += [
661 rvficon.d_insn.eq(decoder.instruction),
662 rvficon.d_rs1_addr.eq(Mux(decoder.rs1_re, decoder.rs1, 0)),
663 rvficon.d_rs2_addr.eq(Mux(decoder.rs2_re, decoder.rs2, 0)),
664 rvficon.d_rs1_rdata.eq(Mux(decoder.rs1_re, d_src1, 0)),
665 rvficon.d_rs2_rdata.eq(Mux(decoder.rs2_re, d_src2, 0)),
666 rvficon.d_stall.eq(d.stall),
667 rvficon.x_mem_addr.eq(loadstore.x_addr[2:] << 2),
668 rvficon.x_mem_wmask.eq(Mux(loadstore.x_store, loadstore.x_mask, 0)),
669 rvficon.x_mem_rmask.eq(Mux(loadstore.x_load, loadstore.x_mask, 0)),
670 rvficon.x_mem_wdata.eq(loadstore.x_store_data),
671 rvficon.x_stall.eq(x.stall),
672 rvficon.m_mem_rdata.eq(loadstore.m_load_data),
673 rvficon.m_fetch_misaligned.eq(exception.m_fetch_misaligned),
674 rvficon.m_illegal_insn.eq(m.sink.illegal),
675 rvficon.m_load_misaligned.eq(exception.m_load_misaligned),
676 rvficon.m_store_misaligned.eq(exception.m_store_misaligned),
677 rvficon.m_exception.eq(exception.m_raise),
678 rvficon.m_mret.eq(m.sink.mret),
679 rvficon.m_branch_taken.eq(m.sink.branch_taken),
680 rvficon.m_branch_target.eq(m.sink.branch_target),
681 rvficon.m_pc_rdata.eq(m.sink.pc),
682 rvficon.m_stall.eq(m.stall),
683 rvficon.m_valid.eq(m.valid),
684 rvficon.w_rd_addr.eq(Mux(gprf_wp.en, gprf_wp.addr, 0)),
685 rvficon.w_rd_wdata.eq(Mux(gprf_wp.en, gprf_wp.data, 0)),
686 rvficon.mtvec_r_base.eq(exception.mtvec.r.base),
687 rvficon.mepc_r_value.eq(exception.mepc.r),
688 rvficon.rvfi.connect(self.rvfi)
689 ]
690
691 # pipeline registers
692
693 # A/F
694 with cpu.If(~a.stall):
695 cpu.d.sync += a.source.pc.eq(fetch.a_pc)
696
697 # F/D
698 with cpu.If(~f.stall):
699 cpu.d.sync += [
700 f.source.pc.eq(f.sink.pc),
701 f.source.instruction.eq(fetch.f_instruction),
702 f.source.fetch_error.eq(fetch.f_fetch_error),
703 f.source.fetch_badaddr.eq(fetch.f_badaddr)
704 ]
705
706 # D/X
707 with cpu.If(~d.stall):
708 cpu.d.sync += [
709 d.source.pc.eq(d.sink.pc),
710 d.source.instruction.eq(d.sink.instruction),
711 d.source.fetch_error.eq(d.sink.fetch_error),
712 d.source.fetch_badaddr.eq(d.sink.fetch_badaddr),
713 d.source.illegal.eq(decoder.illegal),
714 d.source.rd.eq(decoder.rd),
715 d.source.rs1.eq(decoder.rs1),
716 d.source.rd_we.eq(decoder.rd_we),
717 d.source.rs1_re.eq(decoder.rs1_re),
718 d.source.immediate.eq(decoder.immediate),
719 d.source.bypass_x.eq(decoder.bypass_x),
720 d.source.bypass_m.eq(decoder.bypass_m),
721 d.source.funct3.eq(decoder.funct3),
722 d.source.load.eq(decoder.load),
723 d.source.store.eq(decoder.store),
724 d.source.adder.eq(decoder.adder),
725 d.source.adder_sub.eq(decoder.adder_sub),
726 d.source.compare.eq(decoder.compare),
727 d.source.logic.eq(decoder.logic),
728 d.source.shift.eq(decoder.shift),
729 d.source.direction.eq(decoder.direction),
730 d.source.sext.eq(decoder.sext),
731 d.source.jump.eq(decoder.jump),
732 d.source.branch.eq(decoder.branch),
733 d.source.fence_i.eq(decoder.fence_i),
734 d.source.csr.eq(decoder.csr),
735 d.source.csr_adr.eq(decoder.immediate),
736 d.source.csr_we.eq(decoder.csr_we),
737 d.source.ecall.eq(decoder.ecall),
738 d.source.ebreak.eq(decoder.ebreak),
739 d.source.mret.eq(decoder.mret),
740 d.source.src1.eq(d_src1),
741 d.source.src2.eq(d_src2),
742 d.source.branch_predict_taken.eq(predict.d_branch_taken & ~predict.d_fetch_misaligned),
743 d.source.branch_target.eq(predict.d_branch_target)
744 ]
745 if self.with_muldiv:
746 cpu.d.sync += [
747 d.source.multiply.eq(decoder.multiply),
748 d.source.divide.eq(decoder.divide)
749 ]
750
751 # X/M
752 with cpu.If(~x.stall):
753 cpu.d.sync += [
754 x.source.pc.eq(x.sink.pc),
755 x.source.instruction.eq(x.sink.instruction),
756 x.source.fetch_error.eq(x.sink.fetch_error),
757 x.source.fetch_badaddr.eq(x.sink.fetch_badaddr),
758 x.source.illegal.eq(x.sink.illegal),
759 x.source.loadstore_misaligned.eq(data_sel.x_misaligned),
760 x.source.ecall.eq(x.sink.ecall),
761 x.source.ebreak.eq(x.sink.ebreak),
762 x.source.rd.eq(x.sink.rd),
763 x.source.rd_we.eq(x.sink.rd_we),
764 x.source.bypass_m.eq(x.sink.bypass_m | x.sink.bypass_x),
765 x.source.funct3.eq(x.sink.funct3),
766 x.source.load.eq(x.sink.load),
767 x.source.store.eq(x.sink.store),
768 x.source.store_data.eq(loadstore.x_store_data),
769 x.source.compare.eq(x.sink.compare),
770 x.source.shift.eq(x.sink.shift),
771 x.source.mret.eq(x.sink.mret),
772 x.source.condition_met.eq(compare.condition_met),
773 x.source.branch_taken.eq(x.sink.jump | x.sink.branch & compare.condition_met),
774 x.source.branch_target.eq(Mux(x.sink.jump & x.sink.rs1_re, adder.result[1:] << 1, x.sink.branch_target)),
775 x.source.branch_predict_taken.eq(x.sink.branch_predict_taken),
776 x.source.csr.eq(x.sink.csr),
777 x.source.csr_adr.eq(x.sink.csr_adr),
778 x.source.csr_we.eq(x.sink.csr_we),
779 x.source.csr_result.eq(x_csr_result),
780 x.source.result.eq(x_result)
781 ]
782 if self.with_muldiv:
783 cpu.d.sync += [
784 x.source.multiply.eq(x.sink.multiply),
785 x.source.divide.eq(x.sink.divide)
786 ]
787
788 # M/W
789 with cpu.If(~m.stall):
790 cpu.d.sync += [
791 m.source.pc.eq(m.sink.pc),
792 m.source.rd.eq(m.sink.rd),
793 m.source.load.eq(m.sink.load),
794 m.source.funct3.eq(m.sink.funct3),
795 m.source.load_data.eq(loadstore.m_load_data),
796 m.source.rd_we.eq(m.sink.rd_we),
797 m.source.result.eq(m_result),
798 m.source.exception.eq(exception.m_raise)
799 ]
800 if self.with_muldiv:
801 cpu.d.sync += [
802 m.source.multiply.eq(m.sink.multiply)
803 ]
804
805 return cpu