From 0557134ca17192a2eb48594821ea1c1c37bf5c61 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Mon, 26 Nov 2018 12:33:35 +0000 Subject: [PATCH] move get_fetch_action to separate verilog file --- cpu.py | 84 +++++------------------------ cpu_fetch_action.py | 128 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+), 72 deletions(-) create mode 100644 cpu_fetch_action.py diff --git a/cpu.py b/cpu.py index ff46452..bdf234d 100644 --- a/cpu.py +++ b/cpu.py @@ -190,74 +190,6 @@ class Fetch: 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_act, load_store_misaligned, mi_rw_wait, - mi_rw_address_valid, - 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(branch_taken, - If(misaligned_jump_target, - self.action.eq(FA.error_trap) - ).Else( - self.action.eq(FA.jump) - ) - ).Else( - self.action.eq(FA.default) - ) - ) - - # 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) - class CSR: def __init__(self, comb, sync, dc, register_rs1): self.comb = comb @@ -830,10 +762,18 @@ class CPU(Module): # CSR decoding csr = CSR(self.comb, self.sync, dc, self.regs.rs1) - self.comb += ft.get_fetch_action(dc.act, load_store_misaligned, - mi.rw_wait, mi.rw_address_valid, - branch_taken, misaligned_jump_target, - csr.op_is_valid) + fi = Instance("CPUFetchAction", name="cpu_fetch_action", + o_fetch_action = ft.action, + i_output_state = ft.output_state, + i_dc_act = dc.act, + i_load_store_misaligned = load_store_misaligned, + i_mi_rw_wait = mi.rw_wait, + i_mi_rw_address_valid = mi.rw_address_valid, + i_branch_taken = branch_taken, + i_misaligned_jump_target = misaligned_jump_target, + i_csr_op_is_valid = csr.op_is_valid) + + self.specials += fi minfo = MInfo(self.comb) diff --git a/cpu_fetch_action.py b/cpu_fetch_action.py new file mode 100644 index 0000000..3b6d7b8 --- /dev/null +++ b/cpu_fetch_action.py @@ -0,0 +1,128 @@ +""" +/* + * 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 CPUFetchAction(Module): + def __init__(self): + Module.__init__(self) + self.action = Signal(fetch_action) + self.output_state = Signal() + self.dc_act = Signal(decode_action) + self.load_store_misaligned = Signal() + self.mi_rw_wait = Signal() + self.mi_rw_address_valid = Signal() + self.branch_taken = Signal() + self.misaligned_jump_target = Signal() + self.csr_op_is_valid = Signal() + + 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((self.dc_act & DA.trap_illegal_instruction) != 0, + self.action.eq(FA.error_trap) + ) + + # ecall / ebreak -> noerror trap + i = i.Elif((self.dc_act & DA.trap_ecall_ebreak) != 0, + self.action.eq(FA.noerror_trap)) + + # load/store: check alignment, check wait + i = i.Elif((self.dc_act & (DA.load | DA.store)) != 0, + If((self.load_store_misaligned | ~self.mi_rw_address_valid), + self.action.eq(FA.error_trap) # misaligned or invalid addr + ).Elif(self.mi_rw_wait, + self.action.eq(FA.wait) # wait + ).Else( + self.action.eq(FA.default) # ok + ) + ) + + # fence + i = i.Elif((self.dc_act & DA.fence) != 0, + self.action.eq(FA.fence)) + + # branch -> misaligned=error, otherwise jump + i = i.Elif((self.dc_act & DA.branch) != 0, + If(self.branch_taken, + If(self.misaligned_jump_target, + self.action.eq(FA.error_trap) + ).Else( + self.action.eq(FA.jump) + ) + ).Else( + self.action.eq(FA.default) + ) + ) + + # jal/jalr -> misaligned=error, otherwise jump + i = i.Elif((self.dc_act & (DA.jal | DA.jalr)) != 0, + If(self.misaligned_jump_target, + self.action.eq(FA.error_trap) + ).Else( + self.action.eq(FA.jump) + ) + ) + + # csr -> opvalid=ok, else error trap + i = i.Elif((self.dc_act & DA.csr) != 0, + If(self.csr_op_is_valid, + self.action.eq(FA.default) + ).Else( + self.action.eq(FA.error_trap) + ) + ) + + c[FOS.valid] = i + + self.comb += Case(self.output_state, c) + + +if __name__ == "__main__": + example = CPUFetchAction() + print(verilog.convert(example, + { + example.action, + example.output_state, + example.dc_act, + example.load_store_misaligned, + example.mi_rw_wait, + example.mi_rw_address_valid, + example.branch_taken, + example.misaligned_jump_target, + example.csr_op_is_valid, + })) -- 2.30.2