X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=cpu_handle_trap.py;fp=cpu_handle_trap.py;h=ad4510c2364be3613eb72c24053cc7ef6a3f6888;hb=25d14007b011dd77a3b88878f124127fef29640e;hp=0000000000000000000000000000000000000000;hpb=0434ba1d907755fe3057f1d2f2f1d487b02279b9;p=rv32.git diff --git a/cpu_handle_trap.py b/cpu_handle_trap.py new file mode 100644 index 0000000..ad4510c --- /dev/null +++ b/cpu_handle_trap.py @@ -0,0 +1,120 @@ +""" +/* + * Copyright 2018 Jacob Lifshay + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ +`timescale 1ns / 1ps +`include "riscv.vh" +`include "cpu.vh" +""" + +import string +from migen import * +from migen.fhdl import verilog +from migen.fhdl.structure import _Operator + +from riscvdefs import * +from cpudefs import * + + +class CPUHandleTrap(Module): + """ + """ + + def __init__(self): + Module.__init__(self) + self.clk = ClockSignal() + self.reset = ResetSignal() + + self.ft_action = Signal(fetch_action) + self.dc_action = Signal(decode_action) + self.dc_immediate = Signal(32) + 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.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.new_mcause.eq(cause_instruction_access_fault) + ) + + # ecall/ebreak + i = i.Elif((self.dc_action & DA.trap_ecall_ebreak) != 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.new_mcause.eq(cause_load_address_misaligned) + ).Else( + self.new_mcause.eq(cause_load_access_fault) + ) + ) + + # store + i = i.Elif((self.dc_action & DA.store) != 0, + If(self.load_store_misaligned, + self.new_mcause.eq(cause_store_amo_address_misaligned) + ).Else( + 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.new_mcause.eq(cause_instruction_address_misaligned) + ) + + # defaults to illegal instruction + i = i.Else(self.new_mcause.eq(cause_illegal_instruction)) + + s.append(i) + + self.sync += s + + +if __name__ == "__main__": + example = CPUHandleTrap() + print(verilog.convert(example, + { + example.ft_action, + example.dc_immediate, + example.mie, + example.new_mcause, + example.new_mepc, + example.new_mpie, + example.new_mie, + example.ft_output_pc, + example.load_store_misaligned, + }))