OpenCores
URL https://opencores.org/ocsvn/altor32/altor32/trunk

Subversion Repositories altor32

[/] [altor32/] [trunk/] [rtl/] [cpu/] [altor32_fetch.v] - Blame information for rev 36

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 ultra_embe
//-----------------------------------------------------------------
2
//                           AltOR32 
3
//                Alternative Lightweight OpenRisc 
4 36 ultra_embe
//                            V2.1
5 27 ultra_embe
//                     Ultra-Embedded.com
6 36 ultra_embe
//                   Copyright 2011 - 2014
7 27 ultra_embe
//
8
//               Email: admin@ultra-embedded.com
9
//
10
//                       License: LGPL
11
//-----------------------------------------------------------------
12
//
13
// Copyright (C) 2011 - 2013 Ultra-Embedded.com
14
//
15
// This source file may be used and distributed without         
16
// restriction provided that this copyright statement is not    
17
// removed from the file and that any derivative work contains  
18
// the original copyright notice and the associated disclaimer. 
19
//
20
// This source file is free software; you can redistribute it   
21
// and/or modify it under the terms of the GNU Lesser General   
22
// Public License as published by the Free Software Foundation; 
23
// either version 2.1 of the License, or (at your option) any   
24
// later version.
25
//
26
// This source is distributed in the hope that it will be       
27
// useful, but WITHOUT ANY WARRANTY; without even the implied   
28
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      
29
// PURPOSE.  See the GNU Lesser General Public License for more 
30
// details.
31
//
32
// You should have received a copy of the GNU Lesser General    
33
// Public License along with this source; if not, write to the 
34
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
35
// Boston, MA  02111-1307  USA
36
//-----------------------------------------------------------------
37
 
38
//-----------------------------------------------------------------
39
// Includes
40
//-----------------------------------------------------------------
41
`include "altor32_defs.v"
42
 
43
//-----------------------------------------------------------------
44
// Module - Instruction Fetch
45
//-----------------------------------------------------------------
46
module altor32_fetch
47
(
48
    // General
49
    input               clk_i /*verilator public*/,
50
    input               rst_i /*verilator public*/,
51
 
52
    // Instruction Fetch
53
    output              fetch_o /*verilator public*/,
54 36 ultra_embe
    output reg [31:0]   pc_o /*verilator public*/,
55 27 ultra_embe
    input [31:0]        data_i /*verilator public*/,
56
    input               data_valid_i/*verilator public*/,
57
 
58
    // Branch target
59
    input               branch_i /*verilator public*/,
60
    input [31:0]        branch_pc_i /*verilator public*/,
61
    input               stall_i /*verilator public*/,
62
 
63
    // Decoded opcode
64
    output [31:0]       opcode_o /*verilator public*/,
65
    output [31:0]       opcode_pc_o /*verilator public*/,
66
    output              opcode_valid_o /*verilator public*/,
67
 
68
    // Decoded register details
69
    output [4:0]        ra_o /*verilator public*/,
70
    output [4:0]        rb_o /*verilator public*/,
71
    output [4:0]        rd_o /*verilator public*/
72
);
73
 
74
//-----------------------------------------------------------------
75
// Params
76
//-----------------------------------------------------------------
77
parameter           BOOT_VECTOR             = 32'h00000000;
78
parameter           CACHE_LINE_SIZE_WIDTH   = 5; /* 5-bits -> 32 entries */
79 36 ultra_embe
parameter           PIPELINED_FETCH         = "DISABLED";
80 27 ultra_embe
 
81
//-----------------------------------------------------------------
82
// Registers
83
//-----------------------------------------------------------------
84 36 ultra_embe
reg         r_rd;
85 27 ultra_embe
reg [31:0]  r_pc;
86
reg [31:0]  d_pc;
87
 
88
//-------------------------------------------------------------------
89
// Next PC state machine
90
//-------------------------------------------------------------------
91 36 ultra_embe
wire [31:0] next_pc = r_pc + 32'd4;
92 27 ultra_embe
 
93
always @ (posedge clk_i or posedge rst_i)
94
begin
95
   if (rst_i)
96
   begin
97
        r_pc        <= BOOT_VECTOR + `VECTOR_RESET;
98
        d_pc        <= BOOT_VECTOR + `VECTOR_RESET;
99
        r_rd        <= 1'b1;
100
   end
101 36 ultra_embe
   else if (~stall_i)
102 27 ultra_embe
   begin
103
        r_rd        <= 1'b0;
104
        d_pc        <= pc_o;
105
 
106
        // Branch - Next PC = branch target + 4
107
        if (branch_i)
108
        begin
109
            r_pc <= branch_pc_i + 4;
110
        end
111
        // Normal sequential execution (and instruction is ready)
112
        else if (data_valid_i)
113
        begin
114
            // New cache line?
115 36 ultra_embe
            if (next_pc[CACHE_LINE_SIZE_WIDTH-1:0] == {CACHE_LINE_SIZE_WIDTH{1'b0}})
116 27 ultra_embe
            begin
117
                // Start fetch of next line
118
                r_rd  <= 1'b1;
119
            end
120
 
121 36 ultra_embe
            r_pc <= next_pc;
122 27 ultra_embe
        end
123
   end
124
end
125
 
126
//-------------------------------------------------------------------
127 36 ultra_embe
// Assignments
128 27 ultra_embe
//-------------------------------------------------------------------
129 36 ultra_embe
 
130
// Instruction Fetch
131
always @ *
132 27 ultra_embe
begin
133 36 ultra_embe
    // Stall, revert to last requested PC
134
    if (stall_i)
135
        pc_o = d_pc;
136
    else if (branch_i)
137
        pc_o = branch_pc_i;
138
    else if (~data_valid_i)
139
        pc_o = d_pc;
140
    else
141
        pc_o = r_pc;
142 27 ultra_embe
end
143
 
144 36 ultra_embe
assign fetch_o         = branch_i ? 1'b1 : r_rd;
145
 
146 27 ultra_embe
//-------------------------------------------------------------------
147 36 ultra_embe
// Opcode output (retiming)
148 27 ultra_embe
//-------------------------------------------------------------------
149 36 ultra_embe
generate
150
if (PIPELINED_FETCH == "ENABLED")
151
begin: FETCH_FLOPS
152
    reg [31:0] r_opcode;
153
    reg [31:0] r_opcode_pc;
154
    reg        r_opcode_valid;
155
    reg        r_branch;
156 27 ultra_embe
 
157 36 ultra_embe
    always @ (posedge clk_i or posedge rst_i)
158
    begin
159
       if (rst_i)
160
       begin
161
            r_opcode        <= 32'b0;
162
            r_opcode_pc     <= 32'b0;
163
            r_opcode_valid  <= 1'b0;
164
            r_branch        <= 1'b0;
165
       end
166
       else
167
       begin
168
            r_branch        <= branch_i;
169 27 ultra_embe
 
170 36 ultra_embe
            if (~stall_i)
171
            begin
172
                r_opcode_pc     <= d_pc;
173
                r_opcode        <= data_i;
174
                r_opcode_valid  <= (data_valid_i & !branch_i);
175
            end
176
       end
177
    end
178
 
179
    // Opcode output
180
    assign opcode_valid_o  = r_opcode_valid & ~branch_i & ~r_branch;
181
    assign opcode_o        = r_opcode;
182
    assign opcode_pc_o     = r_opcode_pc;
183
end
184
//-------------------------------------------------------------------
185 27 ultra_embe
// Opcode output
186 36 ultra_embe
//-------------------------------------------------------------------
187
else
188
begin : NO_FETCH_FLOPS
189
    // Opcode output
190
    assign opcode_valid_o  = (data_valid_i & !branch_i);
191
    assign opcode_o        = data_i;
192
    assign opcode_pc_o     = d_pc;
193
end
194
endgenerate
195 27 ultra_embe
 
196 36 ultra_embe
//-------------------------------------------------------------------
197
// Opcode output
198
//-------------------------------------------------------------------
199 27 ultra_embe
// If simulation, RA = 03 if NOP instruction
200
`ifdef SIMULATION
201
    wire [7:0] v_fetch_inst = {2'b00, opcode_o[31:26]};
202
    wire       v_is_nop     = (v_fetch_inst == `INST_OR32_NOP);
203
    assign     ra_o         = v_is_nop ? 5'd3 : opcode_o[20:16];
204
`else
205
    assign     ra_o         = opcode_o[20:16];
206
`endif
207
 
208
assign rb_o            = opcode_o[15:11];
209
assign rd_o            = opcode_o[25:21];
210
 
211
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.