riscv-formal-nmigen/rvfi/cores/minerva/units/predict.py

39 lines
1.2 KiB
Python

from nmigen import *
__all__ = ["BranchPredictor"]
class BranchPredictor(Elaboratable):
def __init__(self):
self.d_branch = Signal()
self.d_jump = Signal()
self.d_offset = Signal((32, True))
self.d_pc = Signal(32)
self.d_rs1_re = Signal()
self.d_branch_taken = Signal()
self.d_branch_target = Signal(32)
def elaborate(self, platform):
m = Module()
d_fetch_misaligned = Signal()
m.d.comb += [
d_fetch_misaligned.eq(self.d_pc[:2].bool() | self.d_offset[:2].bool()),
self.d_branch_target.eq(self.d_pc + self.d_offset),
]
with m.If(d_fetch_misaligned):
m.d.comb += self.d_branch_taken.eq(0)
with m.Elif(self.d_branch):
# Backward conditional branches are predicted as taken.
# Forward conditional branches are predicted as not taken.
m.d.comb += self.d_branch_taken.eq(self.d_offset[-1])
with m.Else():
# Direct jumps are predicted as taken.
# Other branch types (ie. indirect jumps, exceptions) are not predicted.
m.d.comb += self.d_branch_taken.eq(self.d_jump & ~self.d_rs1_re)
return m