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

Subversion Repositories or1k

[/] [or1k/] [branches/] [mp3_stable/] [or1200/] [rtl/] [verilog/] [ifetch.v] - Blame information for rev 210

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

Line No. Rev Author Line
1 168 lampret
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  OR1200's instruction fetch                                  ////
4
////                                                              ////
5
////  This file is part of the OpenRISC 1200 project              ////
6
////  http://www.opencores.org/cores/or1k/                        ////
7
////                                                              ////
8
////  Description                                                 ////
9
////  PC, instruction fetch, interface to IC.                     ////
10
////                                                              ////
11
////  To Do:                                                      ////
12
////   - make it smaller and faster                               ////
13
////                                                              ////
14
////  Author(s):                                                  ////
15
////      - Damjan Lampret, lampret@opencores.org                 ////
16
////                                                              ////
17
//////////////////////////////////////////////////////////////////////
18
////                                                              ////
19
//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
20
////                                                              ////
21
//// This source file may be used and distributed without         ////
22
//// restriction provided that this copyright statement is not    ////
23
//// removed from the file and that any derivative work contains  ////
24
//// the original copyright notice and the associated disclaimer. ////
25
////                                                              ////
26
//// This source file is free software; you can redistribute it   ////
27
//// and/or modify it under the terms of the GNU Lesser General   ////
28
//// Public License as published by the Free Software Foundation; ////
29
//// either version 2.1 of the License, or (at your option) any   ////
30
//// later version.                                               ////
31
////                                                              ////
32
//// This source is distributed in the hope that it will be       ////
33
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
34
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
35
//// PURPOSE.  See the GNU Lesser General Public License for more ////
36
//// details.                                                     ////
37
////                                                              ////
38
//// You should have received a copy of the GNU Lesser General    ////
39
//// Public License along with this source; if not, download it   ////
40
//// from http://www.opencores.org/lgpl.shtml                     ////
41
////                                                              ////
42
//////////////////////////////////////////////////////////////////////
43
//
44
// CVS Revision History
45
//
46
// $Log: not supported by cvs2svn $
47 203 lampret
// Revision 1.1  2001/08/09 13:39:33  lampret
48
// Major clean-up.
49 168 lampret
//
50 203 lampret
//
51 168 lampret
 
52 203 lampret
// synopsys translate_off
53 168 lampret
`include "timescale.v"
54 203 lampret
// synopsys translate_on
55 168 lampret
`include "defines.v"
56
 
57
module ifetch(
58
        // Clock and reset
59
        clk, rst,
60
 
61
        // External i/f to IC
62 209 lampret
        ic_insn, ic_addr, ic_stall, ic_fetchop,
63 168 lampret
 
64
        // Internal i/f
65 205 lampret
        if_freeze, if_insn, if_pc, branch_op, except_type,
66 168 lampret
        branch_addrofs, lr_restor, flag, taken, binsn_addr, except_start,
67 203 lampret
        epcr, force_dslot_fetch, if_stall, branch_stall
68 168 lampret
);
69
 
70
//
71
// I/O
72
//
73
 
74
//
75
// Clock and reset
76
//
77
input                           clk;
78
input                           rst;
79
 
80
//
81
// External i/f to IC
82
//
83
input   [31:0]                   ic_insn;
84 203 lampret
output  [31:0]                   ic_addr;
85
output  [`FETCHOP_WIDTH-1:0]     ic_fetchop;
86 168 lampret
input                           ic_stall;
87
 
88
//
89
// Internal i/f
90
//
91 205 lampret
input                           if_freeze;
92 168 lampret
output  [31:0]                   if_insn;
93
output  [31:0]                   if_pc;
94
input   [`BRANCHOP_WIDTH-1:0]    branch_op;
95
input   [`EXCEPT_WIDTH-1:0]      except_type;
96
input   [31:2]                  branch_addrofs;
97
input   [31:0]                   lr_restor;
98
input                           flag;
99
input   [31:2]                  binsn_addr;
100
output                          taken;
101
input                           except_start;
102
input   [31:0]                   epcr;
103 203 lampret
input                           force_dslot_fetch;
104
output                          if_stall;
105
output                          branch_stall;
106 168 lampret
 
107
//
108
// Internal wires and regs
109
//
110
reg     [31:2]                  pcreg;
111 203 lampret
reg     [32:2]                  dslot_pc;
112 168 lampret
reg     [32:0]                   if_saved;
113 203 lampret
reg     [31:0]                   pcaddr;
114
reg     [31:0]                   pc_saved;
115 168 lampret
reg                             taken;  /* Set to in case of jump or taken branch */
116
 
117
//
118
// Current registered PC (corresponds to fetched instruction)
119
//
120 203 lampret
//assign if_pc = {pcreg[31:2], 2'b00};
121
assign if_pc = (if_saved[32]) ? pc_saved : ic_addr;
122
assign ic_addr = dslot_pc[32] ? {dslot_pc[31:2], 2'b00} : pcaddr;
123
assign branch_stall = dslot_pc[32] & taken;
124
//assign if_stall = ic_stall | (~branch_stall & taken);
125
assign if_stall = ic_stall;
126 168 lampret
 
127
//
128 203 lampret
// Control access to IC subsystem
129
//
130
assign ic_fetchop = (if_saved[32] & !if_stall) ? `FETCHOP_NOP : `FETCHOP_LW;
131
 
132
//
133 168 lampret
// Just fetched instruction
134
//
135 209 lampret
assign if_insn = (if_saved[32]) ? if_saved[31:0] : (ic_stall) ? 32'h1500FFFF : ic_insn;
136 168 lampret
 
137
//
138 203 lampret
// Delay slot PC saved
139
//
140
always @(posedge clk or posedge rst)
141
        if (rst)
142
                dslot_pc <= #1 31'h00000000;
143
//      else if (force_dslot_fetch)
144
//              dslot_pc <= #1 {1'b1, pcaddr[31:2]};
145
        else if (!ic_stall)
146
                dslot_pc <= #1 31'h00000000;
147
 
148
//
149 168 lampret
// Async calculation of new PC value. This value is used for addressing the IC.
150
//
151
always @(pcreg or branch_addrofs or binsn_addr or flag or branch_op or except_type
152
        or except_start or lr_restor or epcr) begin
153
        casex ({except_start, branch_op})       // synopsys parallel_case
154
                {1'b0, `BRANCHOP_NOP}: begin
155 203 lampret
                        pcaddr = {pcreg + 'd1, 2'b0};
156
                        taken = 1'b0;
157 168 lampret
                end
158
                {1'b0, `BRANCHOP_J}: begin
159 203 lampret
`ifdef OR1200_VERBOSE
160
// synopsys translate_off
161
                        $display("%t: BRANCHOP_J: pcaddr <= branch_addrofs %h", $time, branch_addrofs);
162
// synopsys translate_on
163
`endif
164
                        pcaddr = {branch_addrofs, 2'b0};
165
                        taken = 1'b1;
166 168 lampret
                end
167
                {1'b0, `BRANCHOP_JR}: begin
168 203 lampret
`ifdef OR1200_VERBOSE
169
// synopsys translate_off
170
                        $display("%t: BRANCHOP_JR: pcaddr <= lr_restor %h", $time, lr_restor);
171
// synopsys translate_on
172
`endif
173
                        pcaddr = lr_restor;
174
                        taken = 1'b1;
175 168 lampret
                end
176
                {1'b0, `BRANCHOP_BAL}: begin
177 203 lampret
`ifdef OR1200_VERBOSE
178
// synopsys translate_off
179
                        $display("%t: BRANCHOP_BAL: pcaddr %h = binsn_addr %h + branch_addrofs %h", $time, binsn_addr + branch_addrofs, binsn_addr, branch_addrofs);
180
// synopsys translate_on
181
`endif
182
                        pcaddr = {binsn_addr + branch_addrofs, 2'b0};
183
                        taken = 1'b1;
184 168 lampret
                end
185
                {1'b0, `BRANCHOP_BF}:
186
                        if (flag) begin
187 203 lampret
`ifdef OR1200_VERBOSE
188
// synopsys translate_off
189
                                $display("%t: BRANCHOP_BF: pcaddr %h = binsn_addr %h + branch_addrofs %h", $time, binsn_addr + branch_addrofs, binsn_addr, branch_addrofs);
190
// synopsys translate_on
191
`endif
192
                                pcaddr = {binsn_addr + branch_addrofs, 2'b0};
193
                                taken = 1'b1;
194 168 lampret
                        end
195
                        else begin
196 203 lampret
`ifdef OR1200_VERBOSE
197
// synopsys translate_off
198 168 lampret
                                $display("%t: BRANCHOP_BF: not taken", $time);
199 203 lampret
// synopsys translate_on
200
`endif
201
                                pcaddr = {pcreg + 'd1, 2'b0};
202
                                taken = 1'b0;
203 168 lampret
                        end
204
                {1'b0, `BRANCHOP_BNF}:
205
                        if (flag) begin
206 203 lampret
                                pcaddr = {pcreg + 'd1, 2'b0};
207
`ifdef OR1200_VERBOSE
208
// synopsys translate_off
209 168 lampret
                                $display("%t: BRANCHOP_BNF: not taken", $time);
210 203 lampret
// synopsys translate_on
211
`endif
212
                                taken = 1'b0;
213 168 lampret
                        end
214
                        else begin
215 203 lampret
`ifdef OR1200_VERBOSE
216
// synopsys translate_off
217
                                $display("%t: BRANCHOP_BNF: pcaddr %h = binsn_addr %h + branch_addrofs %h", $time, binsn_addr + branch_addrofs, binsn_addr, branch_addrofs);
218
// synopsys translate_on
219
`endif
220
                                pcaddr = {binsn_addr + branch_addrofs, 2'b0};
221
                                taken = 1'b1;
222 168 lampret
                        end
223
                {1'b0, `BRANCHOP_RFE}: begin
224 203 lampret
`ifdef OR1200_VERBOSE
225
// synopsys translate_off
226
                        $display("%t: BRANCHOP_RFE: pcaddr <= epcr %h", $time, epcr);
227
// synopsys translate_on
228
`endif
229
                        pcaddr = epcr;
230
                        taken = 1'b1;
231 168 lampret
                end
232
                default: begin
233 203 lampret
`ifdef OR1200_VERBOSE
234 168 lampret
// synopsys translate_off
235
                        $display("Starting exception: %h.", except_type);
236
// synopsys translate_on
237 203 lampret
`endif
238 209 lampret
                        pcaddr = { 20'h0_0000, except_type, 8'h00};
239 203 lampret
                        taken = 1'b1;
240 168 lampret
                end
241
        endcase
242
end
243
 
244
//
245
// PC register
246
//
247
always @(posedge clk or posedge rst) begin
248
        if (rst)
249
                pcreg <= #1 30'd64;
250 205 lampret
        else if (!if_freeze && !ic_stall) begin
251 203 lampret
                pcreg <= #1 ic_addr[31:2];
252
`ifdef OR1200_VERBOSE
253
// synopsys translate_off
254
                $display("%t: pcreg incremented to %h", $time, {ic_addr[31:2], 2'b0});
255
// synopsys translate_on
256
`endif
257 168 lampret
        end
258
end
259
 
260
//
261
// Stores INSN when pipeline is frozen
262
//
263
always @(posedge clk or posedge rst)
264
        if (rst) begin
265
                if_saved <= #1 33'b0;
266
        end
267 205 lampret
        else if (if_freeze && !if_saved[32] && !ic_stall) begin  // && !taken
268 209 lampret
                if_saved <= #1 {1'b1, ic_insn};
269 203 lampret
`ifdef OR1200_VERBOSE
270
// synopsys translate_off
271 209 lampret
                $display("%t: if_saved <= %h", $time, {1'b1, ic_insn});
272 203 lampret
// synopsys translate_on
273
`endif
274 168 lampret
        end
275 205 lampret
        else if (!if_freeze) begin
276 168 lampret
                if_saved[32] <= #1 1'b0;
277
                if_saved[31:0] <= #1 32'h1500eeee;
278 203 lampret
`ifdef OR1200_VERBOSE
279
// synopsys translate_off
280 168 lampret
                $display("%t: if_saved[32] <= 0", $time);
281 203 lampret
// synopsys translate_on
282
`endif
283 168 lampret
        end
284
 
285 203 lampret
//
286
// Stores PC when pipeline is frozen
287
//
288
always @(posedge clk or posedge rst)
289
        if (rst) begin
290
                pc_saved <= #1 32'b0;
291
        end
292 205 lampret
        else if (if_freeze && !if_saved[32] && !ic_stall) begin  // && !taken
293 203 lampret
                pc_saved <= #1 ic_addr;
294
        end
295 205 lampret
        else if (!if_freeze) begin
296 203 lampret
                pc_saved <= #1 32'h00000000;
297
        end
298
 
299 168 lampret
endmodule

powered by: WebSVN 2.1.0

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