51e94e6dc1a74e8b1601b3fa91b46903b249e17b
1 from functools
import reduce
2 from operator
import or_
3 from itertools
import tee
5 from nmigen
import Elaboratable
, Module
, Record
, Mux
, Const
, Signal
, Memory
6 from nmigen
.lib
.coding
import PriorityEncoder
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
,
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
26 from soc
.minerva
.units
.debug
.jtag
import jtag_layout
27 from soc
.minerva
.wishbone
import wishbone_layout
50 ("fetch_badaddr", 30),
75 ("branch_target", 32),
76 ("branch_predict_taken", 1),
91 ("fetch_badaddr", 30),
93 ("loadstore_misaligned", 1),
108 ("condition_met", 1),
109 ("branch_target", 32),
111 ("branch_predict_taken", 1),
134 class Minerva(Elaboratable
):
135 def __init__(self
, reset_address
=0x00000000,
137 icache_nways
=1, icache_nlines
=256, icache_nwords
=8, icache_base
=0, icache_limit
=2**31,
139 dcache_nways
=1, dcache_nlines
=256, dcache_nwords
=8, dcache_base
=0, dcache_limit
=2**31,
142 with_trigger
=False, nb_triggers
=8,
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
)
151 self
.jtag
= Record(jtag_layout
)
154 self
.rvfi
= Record(rvfi_layout
)
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
167 def elaborate(self
, platform
):
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
180 sources
, sinks
= tee(stages
)
182 for s1
, s2
in zip(sources
, sinks
):
183 cpu
.d
.comb
+= s1
.source
.connect(s2
.sink
)
185 a
.source
.pc
.reset
= self
.reset_address
- 4
186 cpu
.d
.comb
+= a
.valid
.eq(Const(1))
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()
201 fetch
= cpu
.submodules
.fetch
= CachedFetchUnit(*self
.icache_args
)
203 fetch
= cpu
.submodules
.fetch
= BareFetchUnit()
206 loadstore
= cpu
.submodules
.loadstore
= CachedLoadStoreUnit(*self
.dcache_args
)
208 loadstore
= cpu
.submodules
.loadstore
= BareLoadStoreUnit()
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
217 debug
= cpu
.submodules
.debug
= DebugUnit()
219 if self
.with_trigger
:
220 trigger
= cpu
.submodules
.trigger
= TriggerUnit(self
.nb_triggers
)
223 rvficon
= cpu
.submodules
.rvficon
= RVFIController()
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
233 csrf
= cpu
.submodules
.csrf
= CSRFile()
234 csrf_rp
= csrf
.read_port()
235 csrf_wp
= csrf
.write_port()
237 csrf
.add_csrs(exception
.iter_csrs())
239 csrf
.add_csrs(debug
.iter_csrs())
240 if self
.with_trigger
:
241 csrf
.add_csrs(trigger
.iter_csrs())
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
)
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
)
273 m
.stall_on(fetch
.a_busy
& a
.valid
)
274 m
.stall_on(fetch
.f_busy
& f
.valid
)
277 flush_icache
= x
.sink
.fence_i
& x
.valid
& ~x
.stall
279 flush_icache |
= debug
.resumereq
282 fetch
.a_flush
.eq(flush_icache
),
283 fetch
.f_pc
.eq(f
.sink
.pc
)
287 decoder
.instruction
.eq(d
.sink
.instruction
)
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])
296 cpu
.d
.comb
+= gprf_rp1
.addr
.eq(decoder
.rs1
)
298 cpu
.d
.comb
+= debug
.gprf_dat_r
.eq(gprf_rp1
.data
)
300 with cpu
.If(~d
.stall
):
301 cpu
.d
.comb
+= gprf_rp1
.addr
.eq(fetch
.f_instruction
[15:20])
303 cpu
.d
.comb
+= gprf_rp1
.addr
.eq(decoder
.rs1
)
305 with cpu
.If(~d
.stall
):
306 cpu
.d
.comb
+= gprf_rp2
.addr
.eq(fetch
.f_instruction
[20:25])
308 cpu
.d
.comb
+= gprf_rp2
.addr
.eq(decoder
.rs2
)
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
)
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
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
)
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
))
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
)
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
)
351 m
.stall_on(divider
.m_busy
)
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
)
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
)
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
)
393 m_ebreak
= m
.sink
.ebreak
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
)
403 m
.kill_on(m
.source
.exception
& m
.source
.valid
)
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
)
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
)
426 m
.stall_on(loadstore
.x_busy
& x
.valid
)
427 m
.stall_on(loadstore
.m_busy
& m
.valid
)
431 cpu
.d
.comb
+= loadstore
.x_flush
.eq(debug
.resumereq
)
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
),
440 x
.stall_on(loadstore
.x_busy
& x
.valid
)
443 s
.kill_on(x
.sink
.fence_i
& x
.valid
)
446 with cpu
.If(debug
.halt
& debug
.halted
):
447 cpu
.d
.comb
+= debug
.dbus
.connect(self
.dbus
)
449 cpu
.d
.comb
+= loadstore
.dbus
.connect(self
.dbus
)
451 cpu
.d
.comb
+= loadstore
.dbus
.connect(self
.dbus
)
453 # RAW hazard management
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
),
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
),
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
),
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
)
485 d
.stall_on((x_lock
& x
.valid | m_lock
& m
.valid
) & d
.valid
& ~debug
.dcsr_step
)
487 d
.stall_on((x_lock
& x
.valid | m_lock
& m
.valid
) & d
.valid
)
491 x_result
= Signal(32)
492 m_result
= Signal(32)
493 w_result
= Signal(32)
494 x_csr_result
= Signal(32)
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
)
503 cpu
.d
.comb
+= x_result
.eq(adder
.result
)
505 with cpu
.If(m
.sink
.compare
):
506 cpu
.d
.comb
+= m_result
.eq(m
.sink
.condition_met
)
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
)
513 cpu
.d
.comb
+= m_result
.eq(m
.sink
.result
)
515 with cpu
.If(w
.sink
.load
):
516 cpu
.d
.comb
+= w_result
.eq(data_sel
.w_load_result
)
518 with cpu
.Elif(w
.sink
.multiply
):
519 cpu
.d
.comb
+= w_result
.eq(multiplier
.w_result
)
521 cpu
.d
.comb
+= w_result
.eq(w
.sink
.result
)
523 with cpu
.If(x_csr_set_clear
):
524 cpu
.d
.comb
+= x_csr_result
.eq(logic
.result
)
526 cpu
.d
.comb
+= x_csr_result
.eq(x_csr_src1
)
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
)
535 with cpu
.If(debug
.halt
& debug
.halted
):
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
)
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
)
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
)
554 # D stage operand selection
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
)
572 cpu
.d
.comb
+= d_src1
.eq(gprf_rp1
.data
)
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
)
587 cpu
.d
.comb
+= d_src2
.eq(gprf_rp2
.data
)
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
)
599 a
.kill_on(predict
.d_branch_taken
& ~predict
.d_fetch_misaligned
& d
.valid
)
601 s
.kill_on(m
.sink
.branch_predict_taken
& ~m
.sink
.branch_taken
& m
.valid
)
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
)
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
)
624 if self
.with_trigger
:
625 cpu
.d
.comb
+= debug
.trigger_haltreq
.eq(trigger
.haltreq
)
627 cpu
.d
.comb
+= debug
.trigger_haltreq
.eq(Const(0))
629 csrf_debug_rp
= csrf
.read_port()
630 csrf_debug_wp
= csrf
.write_port()
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
)
640 x
.stall_on(debug
.halt
)
641 m
.stall_on(debug
.dcsr_step
& m
.valid
& ~debug
.halt
)
643 s
.kill_on(debug
.killall
)
645 halted
= x
.stall
& ~
reduce(or_
, (s
.valid
for s
in (m
, w
)))
646 cpu
.d
.sync
+= debug
.halted
.eq(halted
)
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)
653 if self
.with_trigger
:
655 trigger
.x_pc
.eq(x
.sink
.pc
),
656 trigger
.x_valid
.eq(x
.valid
),
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
)
694 with cpu
.If(~a
.stall
):
695 cpu
.d
.sync
+= a
.source
.pc
.eq(fetch
.a_pc
)
698 with cpu
.If(~f
.stall
):
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
)
707 with cpu
.If(~d
.stall
):
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
)
747 d
.source
.multiply
.eq(decoder
.multiply
),
748 d
.source
.divide
.eq(decoder
.divide
)
752 with cpu
.If(~x
.stall
):
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
)
784 x
.source
.multiply
.eq(x
.sink
.multiply
),
785 x
.source
.divide
.eq(x
.sink
.divide
)
789 with cpu
.If(~m
.stall
):
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
)
802 m
.source
.multiply
.eq(m
.sink
.multiply
)