From: Luke Kenneth Casson Leighton Date: Wed, 28 Nov 2018 03:34:22 +0000 (+0000) Subject: handle_trap returns values that get manually transferred on trap X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ab79459e77cd4e1332af0e5980713e959e79e4e2;p=rv32.git handle_trap returns values that get manually transferred on trap --- diff --git a/cpu.py b/cpu.py index b12f90e..29cbe57 100644 --- a/cpu.py +++ b/cpu.py @@ -235,6 +235,13 @@ class CPU(Module): # 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, @@ -242,17 +249,16 @@ class CPU(Module): 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): @@ -268,8 +274,7 @@ class CPU(Module): 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 @@ -617,7 +622,10 @@ class CPU(Module): 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, @@ -625,9 +633,11 @@ class CPU(Module): 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 diff --git a/cpu_handle_trap.py b/cpu_handle_trap.py index c77be86..ad4510c 100644 --- a/cpu_handle_trap.py +++ b/cpu_handle_trap.py @@ -44,31 +44,31 @@ class CPUHandleTrap(Module): 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)) ) @@ -76,44 +76,45 @@ class CPUHandleTrap(Module): # 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, }))