# return [m.mcause.eq(0),
# ]
+ def handle_trap(self, mcause, mepc, mie, mpie):
+ s = [mcause.eq(self.new_mcause),
+ mepc.eq(self.new_mepc),
+ mpie.eq(self.new_mpie),
+ mie.eq(self.new_mie)]
+ return s
+
def main_block(self, mtvec, mip, minfo, misa, csr, mi, m, mstatus, mie,
ft, dc,
load_store_misaligned,
lui_auipc_result):
c = {}
c[FOS.empty] = []
- c[FOS.trap] = self.handle_trap.eq(1)
+ c[FOS.trap] = self.handle_trap(m.mcause, m.mepc,
+ mstatus.mie, mstatus.mpie)
c[FOS.valid] = self.handle_valid(mtvec, mip, minfo, misa, csr, mi, m,
mstatus, mie, ft, dc,
load_store_misaligned,
loaded_value,
alu_result,
lui_auipc_result)
- return [self.handle_trap.eq(0),
- self.regs.w_en.eq(0),
+ return [self.regs.w_en.eq(0),
Case(ft.output_state, c),
- self.handle_trap.eq(0),
self.regs.w_en.eq(0)]
def write_register(self, rd, val):
lui_auipc_result):
# fetch action ack trap
i = If((ft.action == FA.ack_trap) | (ft.action == FA.noerror_trap),
- [self.handle_trap.eq(1),
- ]
+ self.handle_trap(m.mcause, m.mepc, mstatus.mie, mstatus.mpie)
)
# load
minfo = MInfo(self.comb)
- self.handle_trap = Signal(reset=0)
+ self.new_mcause = Signal(32)
+ self.new_mepc = Signal(32)
+ self.new_mpie = Signal()
+ self.new_mie = Signal()
ht = Instance("CPUHandleTrap", "cpu_handle_trap",
i_ft_action = ft.action,
i_dc_action = dc.act,
i_dc_immediate = dc.immediate,
i_load_store_misaligned = load_store_misaligned,
- o_mcause = m.mcause,
- o_mepc = m.mepc,
- o_mie = mstatus.mie)
+ i_mie = mstatus.mie,
+ o_mcause = self.new_mcause,
+ o_mepc = self.new_mepc,
+ o_mpie = self.new_mpie,
+ o_mie = self.new_mie)
self.specials += ht
self.clk = ClockSignal()
self.reset = ResetSignal()
- self.handle_trap = Signal()
self.ft_action = Signal(fetch_action)
self.dc_action = Signal(decode_action)
self.dc_immediate = Signal(32)
- self.mcause = Signal(32)
- self.mepc = Signal()
- self.mpie = Signal()
self.mie = Signal()
+ self.new_mie = Signal()
+ self.new_mepc = Signal()
+ self.new_mpie = Signal()
+ self.new_mcause = Signal(32)
self.ft_output_pc = Signal(32)
self.load_store_misaligned = Signal()
- s = [self.mpie.eq(self.mie),
- self.mie.eq(0),
- self.mepc.eq(Mux(self.ft_action == FA.noerror_trap,
+ s = [self.new_mpie.eq(self.mie),
+ self.new_mie.eq(0),
+ self.new_mepc.eq(Mux(self.ft_action == FA.noerror_trap,
self.ft_output_pc + 4,
self.ft_output_pc))]
# fetch action ack trap
i = If(self.ft_action == FA.ack_trap,
- self.mcause.eq(cause_instruction_access_fault)
+ self.new_mcause.eq(cause_instruction_access_fault)
)
# ecall/ebreak
i = i.Elif((self.dc_action & DA.trap_ecall_ebreak) != 0,
- self.mcause.eq(Mux(self.dc_immediate[0],
+ self.new_mcause.eq(Mux(self.dc_immediate[0],
cause_machine_environment_call,
cause_breakpoint))
)
# load
i = i.Elif((self.dc_action & DA.load) != 0,
If(self.load_store_misaligned,
- self.mcause.eq(cause_load_address_misaligned)
+ self.new_mcause.eq(cause_load_address_misaligned)
).Else(
- self.mcause.eq(cause_load_access_fault)
+ self.new_mcause.eq(cause_load_access_fault)
)
)
# store
i = i.Elif((self.dc_action & DA.store) != 0,
If(self.load_store_misaligned,
- self.mcause.eq(cause_store_amo_address_misaligned)
+ self.new_mcause.eq(cause_store_amo_address_misaligned)
).Else(
- self.mcause.eq(cause_store_amo_access_fault)
+ self.new_mcause.eq(cause_store_amo_access_fault)
)
)
# jal/jalr -> misaligned=error, otherwise jump
i = i.Elif((self.dc_action & (DA.jal | DA.jalr | DA.branch)) != 0,
- self.mcause.eq(cause_instruction_address_misaligned)
+ self.new_mcause.eq(cause_instruction_address_misaligned)
)
# defaults to illegal instruction
- i = i.Else(self.mcause.eq(cause_illegal_instruction))
+ i = i.Else(self.new_mcause.eq(cause_illegal_instruction))
s.append(i)
- self.sync += If(self.handle_trap, s)
+ self.sync += s
if __name__ == "__main__":
example = CPUHandleTrap()
print(verilog.convert(example,
{
- example.handle_trap,
example.ft_action,
example.dc_immediate,
- example.mcause,
- example.mpie,
example.mie,
+ example.new_mcause,
+ example.new_mepc,
+ example.new_mpie,
+ example.new_mie,
example.ft_output_pc,
example.load_store_misaligned,
}))