""" /* * 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. * */ """ from migen import * from migen.fhdl import verilog #from riscvdefs import * from cpudefs import * class CPUFetchStage(Module): def __init__(self): self.clk = ClockSignal() self.reset = ResetSignal() self.reset_vector = Signal(32) #32'hXXXXXXXX; - parameter self.mtvec = Signal(32) # 32'hXXXXXXXX; - parameter #output [31:2] memory_interface_fetch_address, self.memory_interface_fetch_address = Signal(32) #input [31:0] memory_interface_fetch_data, self.memory_interface_fetch_data = Signal(32) self.memory_interface_fetch_valid = Signal() self.fetch_action = Signal(fetch_action) self.target_pc = Signal(32) self.output_pc = Signal(32, reset=self.reset_vector) self.output_instruction = Signal(32) self.output_state = Signal(fetch_output_state, reset=FOS.empty) #self.comb += [ # self.cd_sys.clk.eq(self.clk), # self.cd_sys.rst.eq(self.reset) #] fetch_pc = Signal(32, reset=self.reset_vector) self.sync += If(self.fetch_action != FA.wait, self.output_pc.eq(fetch_pc)) self.comb += self.memory_interface_fetch_address.eq(fetch_pc[2:]) #initial output_pc <= self.reset_vector; #initial output_state <= `FOS.empty; delayed_instruction = Signal(32, reset=0) delayed_instruction_valid = Signal(reset=0) self.sync += delayed_instruction.eq(self.output_instruction) self.comb += If(delayed_instruction_valid, self.output_instruction.eq(delayed_instruction) ).Else( self.output_instruction.eq(self.memory_interface_fetch_data) ) self.sync += delayed_instruction_valid.eq(self.fetch_action == FA.wait) fc = { FA.ack_trap: If(self.memory_interface_fetch_valid, [fetch_pc.eq(fetch_pc + 4), self.output_state.eq(FOS.valid)] ).Else( [fetch_pc.eq(self.mtvec), self.output_state.eq(FOS.trap)] ), FA.fence: [ fetch_pc.eq(self.output_pc + 4), self.output_state.eq(FOS.empty) ], FA.jump: [ fetch_pc.eq(self.target_pc), self.output_state.eq(FOS.empty) ], FA.error_trap: [fetch_pc.eq(self.mtvec), self.output_state.eq(FOS.empty) ], FA.wait: [fetch_pc.eq(fetch_pc), self.output_state.eq(FOS.valid) ] } fc[FA.default] = fc[FA.ack_trap] fc[FA.noerror_trap] = fc[FA.error_trap] self.sync += Case(self.fetch_action, fc).makedefault(FA.default) if __name__ == "__main__": example = CPUFetchStage() #memory_interface_fetch_address = Signal(32) print(verilog.convert(example, { #example.clk, #example.reset, example.memory_interface_fetch_address, example.memory_interface_fetch_data, example.memory_interface_fetch_valid, example.fetch_action, example.target_pc, example.output_pc, example.output_instruction, example.output_state, example.reset_vector, example.mtvec }))