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 168

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
//
48
 
49
`include "timescale.v"
50
`include "defines.v"
51
 
52
module ifetch(
53
        // Clock and reset
54
        clk, rst,
55
 
56
        // External i/f to IC
57
        ic_insn, ic_pcaddr, ic_stall, tp_insn, tp_wr_insn,
58
 
59
        // Internal i/f
60
        pipeline_freeze, if_insn, if_pc, branch_op, except_type,
61
        branch_addrofs, lr_restor, flag, taken, binsn_addr, except_start,
62
        epcr
63
);
64
 
65
//
66
// I/O
67
//
68
 
69
//
70
// Clock and reset
71
//
72
input                           clk;
73
input                           rst;
74
 
75
//
76
// External i/f to IC
77
//
78
input   [31:0]                   ic_insn;
79
output  [31:0]                   ic_pcaddr;
80
input                           ic_stall;
81
input   [31:0]                   tp_insn;
82
input                           tp_wr_insn;
83
 
84
//
85
// Internal i/f
86
//
87
input                           pipeline_freeze;
88
output  [31:0]                   if_insn;
89
output  [31:0]                   if_pc;
90
input   [`BRANCHOP_WIDTH-1:0]    branch_op;
91
input   [`EXCEPT_WIDTH-1:0]      except_type;
92
input   [31:2]                  branch_addrofs;
93
input   [31:0]                   lr_restor;
94
input                           flag;
95
input   [31:2]                  binsn_addr;
96
output                          taken;
97
input                           except_start;
98
input   [31:0]                   epcr;
99
 
100
//
101
// Internal wires and regs
102
//
103
reg     [31:2]                  pcreg;
104
reg     [32:0]                   if_saved;
105
reg     [31:0]                   ic_pcaddr;
106
reg                             taken;  /* Set to in case of jump or taken branch */
107
 
108
// Selection between insn from IC or Trace port
109
wire [31:0] ic_tp_insn = (tp_wr_insn) ? tp_insn : ic_insn;
110
 
111
//
112
// Current registered PC (corresponds to fetched instruction)
113
//
114
assign if_pc = {pcreg[31:2], 2'b0};
115
 
116
//
117
// Just fetched instruction
118
//
119
assign if_insn = (if_saved[32]) ? if_saved[31:0] : ((taken || ic_stall) ? 32'h1500FFFF : ic_tp_insn);
120
 
121
//
122
// Async calculation of new PC value. This value is used for addressing the IC.
123
//
124
always @(pcreg or branch_addrofs or binsn_addr or flag or branch_op or except_type
125
        or except_start or lr_restor or epcr) begin
126
        casex ({except_start, branch_op})       // synopsys parallel_case
127
                {1'b0, `BRANCHOP_NOP}: begin
128
                        ic_pcaddr <= #1 {pcreg + 'd1, 2'b0};
129
                        taken <= #1 1'b0;
130
                end
131
                {1'b0, `BRANCHOP_J}: begin
132
                        $display("%t: BRANCHOP_J: ic_pcaddr <= branch_addrofs %h", $time, branch_addrofs);
133
                        ic_pcaddr <= #1 {branch_addrofs, 2'b0};
134
                        taken <= #1 1'b1;
135
                end
136
                {1'b0, `BRANCHOP_JR}: begin
137
                        $display("%t: BRANCHOP_JR: ic_pcaddr <= lr_restor %h", $time, lr_restor);
138
                        ic_pcaddr <= #1 lr_restor;
139
                        taken <= #1 1'b1;
140
                end
141
                {1'b0, `BRANCHOP_BAL}: begin
142
                        $display("%t: BRANCHOP_BAL: ic_pcaddr %h = binsn_addr %h + branch_addrofs %h", $time, binsn_addr + branch_addrofs, binsn_addr, branch_addrofs);
143
                        ic_pcaddr <= #1 {binsn_addr + branch_addrofs, 2'b0};
144
                        taken <= #1 1'b1;
145
                end
146
                {1'b0, `BRANCHOP_BF}:
147
                        if (flag) begin
148
                                $display("%t: BRANCHOP_BF: ic_pcaddr %h = binsn_addr %h + branch_addrofs %h", $time, binsn_addr + branch_addrofs, binsn_addr, branch_addrofs);
149
                                ic_pcaddr <= #1 {binsn_addr + branch_addrofs, 2'b0};
150
                                taken <= #1 1'b1;
151
                        end
152
                        else begin
153
                                $display("%t: BRANCHOP_BF: not taken", $time);
154
                                ic_pcaddr <= #1 {pcreg + 'd1, 2'b0};
155
                                taken <= #1 1'b0;
156
                        end
157
                {1'b0, `BRANCHOP_BNF}:
158
                        if (flag) begin
159
                                ic_pcaddr <= #1 {pcreg + 'd1, 2'b0};
160
                                $display("%t: BRANCHOP_BNF: not taken", $time);
161
                                taken <= #1 1'b0;
162
                        end
163
                        else begin
164
                                $display("%t: BRANCHOP_BNF: ic_pcaddr %h = binsn_addr %h + branch_addrofs %h", $time, binsn_addr + branch_addrofs, binsn_addr, branch_addrofs);
165
                                ic_pcaddr <= #1 {binsn_addr + branch_addrofs, 2'b0};
166
                                taken <= #1 1'b1;
167
                        end
168
                {1'b0, `BRANCHOP_RFE}: begin
169
                        $display("%t: BRANCHOP_RFE: ic_pcaddr <= epcr %h", $time, epcr);
170
                        ic_pcaddr <= #1 epcr;
171
                        taken <= #1 1'b1;
172
                end
173
                default: begin
174
// synopsys translate_off
175
                        $display("Starting exception: %h.", except_type);
176
// synopsys translate_on
177
                        ic_pcaddr <= #1 { 21'h0, except_type, 8'h00};
178
                        taken <= #1 1'b1;
179
                end
180
        endcase
181
end
182
 
183
//
184
// PC register
185
//
186
always @(posedge clk or posedge rst) begin
187
        if (rst)
188
                pcreg <= #1 30'd64;
189
        else if (!pipeline_freeze && !ic_stall) begin
190
                pcreg <= #1 ic_pcaddr[31:2];
191
                $display("%t: pcreg incremented to %h", $time, {ic_pcaddr[31:2], 2'b0});
192
        end
193
end
194
 
195
//
196
// Stores INSN when pipeline is frozen
197
//
198
always @(posedge clk or posedge rst)
199
        if (rst) begin
200
                if_saved <= #1 33'b0;
201
        end
202
        else if (pipeline_freeze && !if_saved[32] && !ic_stall && !taken) begin
203
                if_saved <= #1 {1'b1, ic_tp_insn};
204
                $display("%t: if_saved <= %h", $time, {1'b1, ic_tp_insn});
205
        end
206
        else if (!pipeline_freeze) begin
207
                if_saved[32] <= #1 1'b0;
208
                if_saved[31:0] <= #1 32'h1500eeee;
209
                $display("%t: if_saved[32] <= 0", $time);
210
        end
211
 
212
endmodule

powered by: WebSVN 2.1.0

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