-__all__ = ["PCSelector", "FetchUnitInterface", "BareFetchUnit",
- "CachedFetchUnit"]
-
-
-class PCSelector(Elaboratable):
- def __init__(self):
- self.f_pc = Signal(32)
- self.d_pc = Signal(32)
- self.d_branch_predict_taken = Signal()
- self.d_branch_target = Signal(32)
- self.d_valid = Signal()
- self.x_pc = Signal(32)
- self.x_fence_i = Signal()
- self.x_valid = Signal()
- self.m_branch_predict_taken = Signal()
- self.m_branch_taken = Signal()
- self.m_branch_target = Signal(32)
- self.m_exception = Signal()
- self.m_mret = Signal()
- self.m_valid = Signal()
- self.mtvec_r_base = Signal(30)
- self.mepc_r_base = Signal(30)
-
- self.a_pc = Signal(32)
-
- def elaborate(self, platform):
- m = Module()
-
- with m.If(self.m_exception & self.m_valid):
- m.d.comb += self.a_pc.eq(self.mtvec_r_base << 2)
- with m.Elif(self.m_mret & self.m_valid):
- m.d.comb += self.a_pc.eq(self.mepc_r_base << 2)
- with m.Elif(self.m_branch_predict_taken & ~self.m_branch_taken &
- self.m_valid):
- m.d.comb += self.a_pc.eq(self.x_pc)
- with m.Elif(~self.m_branch_predict_taken & self.m_branch_taken &
- self.m_valid):
- m.d.comb += self.a_pc.eq(self.m_branch_target),
- with m.Elif(self.x_fence_i & self.x_valid):
- m.d.comb += self.a_pc.eq(self.d_pc)
- with m.Elif(self.d_branch_predict_taken & self.d_valid):
- m.d.comb += self.a_pc.eq(self.d_branch_target),
- with m.Else():
- m.d.comb += self.a_pc.eq(self.f_pc + 4)
-
- return m