aboutsummaryrefslogtreecommitdiff
path: root/hdl/if_stage.v
blob: 02f4cd0dcaaf3ea312346a726fb12a30f99b98df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
`timescale 1ns / 1ps

/*
 Instruction Fetch pipeline stage  
 */

module if_stage( input             clk, rst,
                 input             if_id_write_en,
                 input             pc_write,
                 input      [1:0]  pc_source,
                 
                 input pstop_i,
                
                 output            i_read_en,
                 output     [31:0] i_addr,
 
                 input      [31:0] i_instr_in, 
                 input      [31:0] jump_addr, branch_addr,
                 
                 output reg [31:0] IF_ID_next_i_addr,
                 output reg [31:0] IF_ID_instruction );


     reg  [31:0] pc_reg, pc_next; // Program counter (PC)
     wire [31:0] next_i_addr;
     
     localparam     LW  = 6'b100011, 
                    SW  = 6'b101011;
     
     wire mem_op = (IF_ID_instruction[31:26] == LW) || (IF_ID_instruction[31:26] == SW);
   
     //logic
     assign next_i_addr = pc_reg + 4;
     assign i_read_en   = 1;
     assign i_addr      = pc_reg >> 2;
      
     always @* begin
          pc_next = pc_reg;
        
          case (pc_source)
               2'b00: pc_next = next_i_addr;
               2'b01: pc_next = branch_addr;
               2'b10: pc_next = jump_addr;                   
          endcase
     end
   
     always @(posedge clk) begin
          if (rst)
               pc_reg <= 0;        
          else begin
               if (pc_write && !(pstop_i || mem_op))
                    pc_reg <= pc_next;             
          end        
     end

     //IF/ID Pipeline register
     always @(posedge clk) begin
          if (rst) begin
               IF_ID_next_i_addr <= 0;
               IF_ID_instruction <= 0;           
          end
          else begin
               if ( if_id_write_en) begin
                    IF_ID_next_i_addr <= next_i_addr;
                    IF_ID_instruction <= !(pstop_i || mem_op)? i_instr_in: 0;
               end
          end
     end
  
endmodule