From: Luke Kenneth Casson Leighton Date: Wed, 21 Nov 2018 14:38:42 +0000 (+0000) Subject: converting cpu_fetch_stage to migen X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2d4a23664382c3192bb492218ce01c07353ca118;p=rv32.git converting cpu_fetch_stage to migen --- diff --git a/cpu_fetch_stage.py b/cpu_fetch_stage.py new file mode 100644 index 0000000..a120573 --- /dev/null +++ b/cpu_fetch_stage.py @@ -0,0 +1,110 @@ +""" +/* + * 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 * + +reset_vector = 32'hXXXXXXXX; +mtvec = 32'hXXXXXXXX; + +class CPUFetchStage(Module): + def __init__(self): + self.clk = ClockSignal() + self.reset = ResetSignal() + #output [31:2] memory_interface_fetch_address, + self.memory_interface_fetch_address = Signal(32)[2:] + #input [31:0] memory_interface_fetch_data, + self.memory_interface_fetch_data = Signal(32) + self.memory_interface_fetch_valid = Signal() + input `fetch_action fetch_action, + input [31:0] target_pc, + self.output_pc = Signal(32, reset=reset_vector) + self.output_instruction = Signal(32) + output reg `fetch_output_state output_state + + self.comb += [ + self.cd_sys.clk.eq(self.clk), + self.cd_sys.rst.eq(self.reset) + ] + + fetch_pc = Signal(32, reset=reset_vector) + + self.sync += output_pc.eq((fetch_action == `fetch_action_wait) ? output_pc : fetch_pc); + + memory_interface_fetch_address = fetch_pc[31:2]; + + initial output_pc <= reset_vector; + initial output_state <= `fetch_output_state_empty; + + delayed_instruction = Signal(32, reset=0); + delayed_instruction_valid = Signal(reset=0); + + self.sync += delayed_instruction.eq(output_instruction) + + assign output_instruction = delayed_instruction_valid ? delayed_instruction : memory_interface_fetch_data; + + self.sync += delayed_instruction_valid.eq(fetch_action == `fetch_action_wait) + + always @(posedge clk or posedge reset) begin + if(reset) begin + output_state <= `fetch_output_state_empty; + end + else begin + case(fetch_action) + `fetch_action_default, + `fetch_action_ack_trap: begin + if(memory_interface_fetch_valid) begin + fetch_pc <= fetch_pc + 4; + output_state <= `fetch_output_state_valid; + end + else begin + fetch_pc <= mtvec; + output_state <= `fetch_output_state_trap; + end + end + `fetch_action_fence: begin + fetch_pc <= output_pc + 4; + output_state <= `fetch_output_state_empty; + end + `fetch_action_jump: begin + fetch_pc <= target_pc; + output_state <= `fetch_output_state_empty; + end + `fetch_action_error_trap, + `fetch_action_noerror_trap: begin + fetch_pc <= mtvec; + output_state <= `fetch_output_state_empty; + end + `fetch_action_wait: begin + fetch_pc <= fetch_pc; + output_state <= `fetch_output_state_valid; + end + endcase + end + end + endmodule