From a22499e48036a8cfb9d05f03da5bf193865b2806 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Tue, 27 Nov 2018 04:08:38 +0000 Subject: [PATCH] split out cpu handle_trap --- cpu_handle_trap.py | 119 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 cpu_handle_trap.py diff --git a/cpu_handle_trap.py b/cpu_handle_trap.py new file mode 100644 index 0000000..c77be86 --- /dev/null +++ b/cpu_handle_trap.py @@ -0,0 +1,119 @@ +""" +/* + * 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.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.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, + 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) + ) + + # ecall/ebreak + i = i.Elif((self.dc_action & DA.trap_ecall_ebreak) != 0, + self.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) + ).Else( + self.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) + ).Else( + self.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) + ) + + # defaults to illegal instruction + i = i.Else(self.mcause.eq(cause_illegal_instruction)) + + s.append(i) + + self.sync += If(self.handle_trap, 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.ft_output_pc, + example.load_store_misaligned, + })) -- 2.30.2