add Makefile for verilog compilation
[rv32.git] / cpu_fetch_stage.v
1 /*
2 * Copyright 2018 Jacob Lifshay
3 *
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:
10 *
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
13 *
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
20 * SOFTWARE.
21 *
22 */
23 `timescale 1ns / 1ps
24 `include "riscv.vh"
25 `include "cpu.vh"
26
27 module cpu_fetch_stage(
28 input clk,
29 input reset,
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
38 );
39
40 parameter reset_vector = 32'hXXXXXXXX;
41 parameter mtvec = 32'hXXXXXXXX;
42
43 reg [31:0] fetch_pc = reset_vector;
44
45 always @(posedge clk or posedge reset) output_pc <= reset ? reset_vector : ((fetch_action == `fetch_action_wait) ? output_pc : fetch_pc);
46
47 assign memory_interface_fetch_address = fetch_pc[31:2];
48
49 initial output_pc <= reset_vector;
50 initial output_state <= `fetch_output_state_empty;
51
52 reg [31:0] delayed_instruction = 0;
53 reg delayed_instruction_valid = 0;
54
55 always @(posedge clk or posedge reset) delayed_instruction <= reset ? 0 : output_instruction;
56
57 assign output_instruction = delayed_instruction_valid ? delayed_instruction : memory_interface_fetch_data;
58
59 always @(posedge clk or posedge reset) begin
60 if(reset)
61 delayed_instruction_valid <= 0;
62 else
63 delayed_instruction_valid <= fetch_action == `fetch_action_wait;
64 end
65
66 always @(posedge clk or posedge reset) begin
67 if(reset) begin
68 fetch_pc <= reset_vector;
69 output_state <= `fetch_output_state_empty;
70 end
71 else begin
72 case(fetch_action)
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;
78 end
79 else begin
80 fetch_pc <= mtvec;
81 output_state <= `fetch_output_state_trap;
82 end
83 end
84 `fetch_action_fence: begin
85 fetch_pc <= output_pc + 4;
86 output_state <= `fetch_output_state_empty;
87 end
88 `fetch_action_jump: begin
89 fetch_pc <= target_pc;
90 output_state <= `fetch_output_state_empty;
91 end
92 `fetch_action_error_trap,
93 `fetch_action_noerror_trap: begin
94 fetch_pc <= mtvec;
95 output_state <= `fetch_output_state_empty;
96 end
97 `fetch_action_wait: begin
98 fetch_pc <= fetch_pc;
99 output_state <= `fetch_output_state_valid;
100 end
101 endcase
102 end
103 end
104 endmodule