+ self.sync += self.mie.eq(0)
+ self.sync += self.mpie.eq(0)
+
+ def make(self):
+ return Cat(
+ self.uie, self.sie, Constant(0), self.mie,
+ self.upie, self.spie, Constant(0), self.mpie,
+ self.spp, Constant(0, 2), self.mpp,
+ self.fs, self.xs, self.mprv, self._sum,
+ self.mxr, self.tvm, self.tw, self.tsr,
+ Constant(0, 8),
+ (self.xs == Constant(0b11, 2)) | (self.fs == Constant(0b11, 2))
+ )
+
+
+class MIE:
+ def __init__(self, comb, sync):
+ self.comb = comb
+ self.sync = sync
+ self.meie = Signal(name="mie_meie")
+ self.mtie = Signal(name="mie_mtie")
+ self.msie = Signal(name="mie_msie")
+ self.ueie = Signal(name="mie_ueie")
+ self.stie = Signal(name="mie_stie")
+ self.utie = Signal(name="mie_utie")
+ self.ssie = Signal(name="mie_ssie")
+ self.usie = Signal(name="mie_usie")
+
+ for n in dir(self):
+ if n in ['make', 'comb', 'sync'] or n.startswith("_"):
+ continue
+ self.comb += getattr(self, n).eq(0x0)
+
+ self.sync += self.meie.eq(0)
+ self.sync += self.mtie.eq(0)
+ self.sync += self.msie.eq(0)
+
+class MIP:
+ def __init__(self, comb, sync):
+ self.comb = comb
+ self.sync = sync
+ self.meip = Signal(name="mip_meip") # TODO: implement ext interrupts
+ self.seip = Signal(name="mip_seip")
+ self.ueip = Signal(name="mip_uiep")
+ self.mtip = Signal(name="mip_mtip") # TODO: implement timer interrupts
+ self.stip = Signal(name="mip_stip")
+ self.msip = Signal(name="mip_stip")
+ self.utip = Signal(name="mip_utip")
+ self.ssip = Signal(name="mip_ssip")
+ self.usip = Signal(name="mip_usip")
+
+ for n in dir(self):
+ if n in ['comb', 'sync'] or n.startswith("_"):
+ continue
+ self.comb += getattr(self, n).eq(0x0)
+
+
+class M:
+ def __init__(self, comb, sync):
+ self.comb = comb
+ self.sync = sync
+ self.mcause = Signal(32)
+ self.mepc = Signal(32)
+ self.mscratch = Signal(32)
+ self.sync += self.mcause.eq(0)
+ self.sync += self.mepc.eq(0) # 32'hXXXXXXXX;
+ self.sync += self.mscratch.eq(0) # 32'hXXXXXXXX;
+
+class Misa:
+ def __init__(self, comb, sync):
+ self.comb = comb
+ self.sync = sync
+ self.misa = Signal(32)
+ cl = []
+ for l in list(string.ascii_lowercase):
+ value = 1 if l == 'i' else 0
+ cl.append(Constant(value))
+ cl.append(Constant(0, 4))
+ cl.append(Constant(0b01, 2))
+ self.comb += self.misa.eq(Cat(cl))
+
+
+class Fetch:
+ def __init__(self, comb, sync):
+ self.comb = comb
+ self.sync = sync
+ self.action = Signal(fetch_action, name="fetch_action")
+ self.target_pc = Signal(32, name="fetch_target_pc")
+ self.output_pc = Signal(32, name="fetch_output_pc")
+ self.output_instruction = Signal(32, name="fetch_ouutput_instruction")
+ self.output_state = Signal(fetch_output_state,name="fetch_output_state")
+
+ def get_fetch_action(self, dc, load_store_misaligned, mi,
+ branch_taken, misaligned_jump_target,
+ csr_op_is_valid):
+ c = {}
+ c["default"] = self.action.eq(FA.default) # XXX should be 32'XXXXXXXX?
+ c[FOS.empty] = self.action.eq(FA.default)
+ c[FOS.trap] = self.action.eq(FA.ack_trap)
+
+ # illegal instruction -> error trap
+ i= If((dc.act & DA.trap_illegal_instruction) != 0,
+ self.action.eq(FA.error_trap)
+ )
+
+ # ecall / ebreak -> noerror trap
+ i = i.Elif((dc.act & DA.trap_ecall_ebreak) != 0,
+ self.action.eq(FA.noerror_trap))
+
+ # load/store: check alignment, check wait
+ i = i.Elif((dc.act & (DA.load | DA.store)) != 0,
+ If((load_store_misaligned | ~mi.rw_address_valid),
+ self.action.eq(FA.error_trap) # misaligned or invalid addr
+ ).Elif(mi.rw_wait,
+ self.action.eq(FA.wait) # wait
+ ).Else(
+ self.action.eq(FA.default) # ok
+ )
+ )
+
+ # fence
+ i = i.Elif((dc.act & DA.fence) != 0,
+ self.action.eq(FA.fence))
+
+ # branch -> misaligned=error, otherwise jump
+ i = i.Elif((dc.act & DA.branch) != 0,
+ If(misaligned_jump_target,
+ self.action.eq(FA.error_trap)
+ ).Else(
+ self.action.eq(FA.jump)
+ )
+ )
+
+ # jal/jalr -> misaligned=error, otherwise jump
+ i = i.Elif((dc.act & (DA.jal | DA.jalr)) != 0,
+ If(misaligned_jump_target,
+ self.action.eq(FA.error_trap)
+ ).Else(
+ self.action.eq(FA.jump)
+ )
+ )
+
+ # csr -> opvalid=ok, else error trap
+ i = i.Elif((dc.act & DA.csr) != 0,
+ If(csr_op_is_valid,
+ self.action.eq(FA.default)
+ ).Else(
+ self.action.eq(FA.error_trap)
+ )
+ )
+
+ c[FOS.valid] = i
+
+ return Case(self.output_state, c)
+