2 * Copyright 2018 Jacob Lifshay
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 module cpu_fetch_stage(
30 output [31:2] memory_interface_fetch_address,
31 input [31:0] memory_interface_fetch_data,
32 input memory_interface_fetch_valid,
33 input `fetch_action fetch_action,
34 input [31:0] target_pc,
35 output reg [31:0] output_pc,
36 output [31:0] output_instruction,
37 output reg `fetch_output_state output_state
40 parameter reset_vector = 32'hXXXXXXXX;
41 parameter mtvec = 32'hXXXXXXXX;
43 reg [31:0] fetch_pc = reset_vector;
45 always @(posedge clk or posedge reset) output_pc <= reset ? reset_vector : ((fetch_action == `fetch_action_wait) ? output_pc : fetch_pc);
47 assign memory_interface_fetch_address = fetch_pc[31:2];
49 initial output_pc <= reset_vector;
50 initial output_state <= `fetch_output_state_empty;
52 reg [31:0] delayed_instruction = 0;
53 reg delayed_instruction_valid = 0;
55 always @(posedge clk or posedge reset) delayed_instruction <= reset ? 0 : output_instruction;
57 assign output_instruction = delayed_instruction_valid ? delayed_instruction : memory_interface_fetch_data;
59 always @(posedge clk or posedge reset) begin
61 delayed_instruction_valid <= 0;
63 delayed_instruction_valid <= fetch_action == `fetch_action_wait;
66 always @(posedge clk or posedge reset) begin
68 fetch_pc <= reset_vector;
69 output_state <= `fetch_output_state_empty;
73 `fetch_action_default,
74 `fetch_action_ack_trap: begin
75 if(memory_interface_fetch_valid) begin
76 fetch_pc <= fetch_pc + 4;
77 output_state <= `fetch_output_state_valid;
81 output_state <= `fetch_output_state_trap;
84 `fetch_action_fence: begin
85 fetch_pc <= output_pc + 4;
86 output_state <= `fetch_output_state_empty;
88 `fetch_action_jump: begin
89 fetch_pc <= target_pc;
90 output_state <= `fetch_output_state_empty;
92 `fetch_action_error_trap,
93 `fetch_action_noerror_trap: begin
95 output_state <= `fetch_output_state_empty;
97 `fetch_action_wait: begin
99 output_state <= `fetch_output_state_valid;