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

Subversion Repositories zap

[/] [zap/] [trunk/] [src/] [rtl/] [cpu/] [zap_fetch_main.v] - Blame information for rev 39

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

Line No. Rev Author Line
1 26 Revanth
// -----------------------------------------------------------------------------
2
// --                                                                         --
3
// --                   (C) 2016-2018 Revanth Kamaraj.                        --
4
// --                                                                         -- 
5
// -- --------------------------------------------------------------------------
6
// --                                                                         --
7
// -- This program is free software; you can redistribute it and/or           --
8
// -- modify it under the terms of the GNU General Public License             --
9
// -- as published by the Free Software Foundation; either version 2          --
10
// -- of the License, or (at your option) any later version.                  --
11
// --                                                                         --
12
// -- This program is distributed in the hope that it will be useful,         --
13
// -- but WITHOUT ANY WARRANTY; without even the implied warranty of          --
14
// -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           --
15
// -- GNU General Public License for more details.                            --
16
// --                                                                         --
17
// -- You should have received a copy of the GNU General Public License       --
18
// -- along with this program; if not, write to the Free Software             --
19
// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA           --
20
// -- 02110-1301, USA.                                                        --
21
// --                                                                         --
22
// -----------------------------------------------------------------------------
23
// --                                                                         --   
24
// --  This is the simple I-cache frontend to the processor. This stage       --
25
// --  serves as a buffer for instructions. Data aborts are handled by adding --
26
// --  an extra signal down the pipeline. Data aborts piggyback off           --
27
// --  AND R0, R0, R0.                                                        --
28
// --                                                                         --
29
// -----------------------------------------------------------------------------
30
 
31
`default_nettype none
32
 
33
module zap_fetch_main #(
34
        // Branch predictor entries.
35
        parameter BP_ENTRIES = 1024
36
)
37
(
38
// Clock and reset.
39
input wire i_clk,          // ZAP clock.        
40
input wire i_reset,        // Active high synchronous reset.
41
 
42
// 
43
// From other parts of the pipeline. These
44
// signals either tell the unit to invalidate
45
// its outputs or freeze in place.
46
//
47
input wire i_code_stall,           // |      
48
input wire i_clear_from_writeback, // | High Priority.
49
input wire i_data_stall,           // |
50
input wire i_clear_from_alu,       // |
51
input wire i_stall_from_shifter,   // |
52
input wire i_stall_from_issue,     // |
53
input wire i_stall_from_decode,    // | Low Priority.
54
input wire i_clear_from_decode,    // V
55
 
56
// Comes from WB unit.
57
input wire [31:0] i_pc_ff,         // Program counter.
58
 
59
// Comes from CPSR
60
input wire        i_cpsr_ff_t,     // CPSR T bit.
61
 
62
// From I-cache.
63
input wire [31:0] i_instruction,   // A 32-bit ZAP instruction.
64
 
65
input wire        i_valid,         // Instruction valid indicator.
66
input wire        i_instr_abort,   // Instruction abort fault.
67
 
68
 
69
// To decode.
70
output reg [31:0]  o_instruction,  // The 32-bit instruction.
71
output reg         o_valid,        // Instruction valid.
72
output reg         o_instr_abort,  // Indication of an abort.       
73
output reg [31:0]  o_pc_plus_8_ff, // PC +8 ouput.
74
output reg [31:0]  o_pc_ff,        // PC output.
75
 
76
// For BP.
77
input wire         i_confirm_from_alu,  // Confirm branch prediction from ALU.
78
input wire [31:0]  i_pc_from_alu,       // Address of branch. 
79
input wire [1:0]   i_taken,             // Predicted status.
80 39 Revanth
output wire [1:0]  o_taken_ff           // Prediction. Not a flip-flop...
81 26 Revanth
 
82
);
83
 
84
`include "zap_defines.vh"
85
`include "zap_localparams.vh"
86
`include "zap_functions.vh"
87
 
88
// Unused signals are assigned to this.
89
wire _unused_ok_;
90
 
91
// If an instruction abort occurs, this unit sleeps until it is woken up.
92
reg sleep_ff;
93
 
94 39 Revanth
// Taken_v
95
wire [1:0] taken_v;
96
 
97
// Predict non branches as not taken...
98
assign o_taken_ff = i_instruction[28:26] == 3'b101 ? taken_v : SNT;
99
 
100 26 Revanth
// ----------------------------------------------------------------------------
101
 
102
//
103
// This is the instruction payload on an abort
104
// because no instruction is actually available on
105
// an abort. This is AND R0, R0, R0 which is a NOP.
106
//
107
localparam ABORT_PAYLOAD = 32'd0;
108
 
109
// Branch states.
110
localparam  [1:0]    SNT     =       2'b00; // Strongly Not Taken.
111
localparam  [1:0]    WNT     =       2'b01; // Weakly Not Taken.
112
localparam  [1:0]    WT      =       2'b10; // Weakly Taken.
113
localparam  [1:0]    ST      =       2'b11; // Strongly Taken.
114
 
115
//
116
// NOTE: If an instruction is invalid, only then can it be tagged with any
117
// kind of interrupt. Thus, the MMU must make instruction valid as 1 before
118
// attaching an abort interrupt to it even though the instruction generated
119
// might be invalid. Such an instruction is not actually executed.
120
//
121
 
122
//
123
// This stage simply forwards data from the
124
// I-cache downwards.
125
//
126
always @ (posedge i_clk)
127
begin
128
        if (  i_reset )
129
        begin
130
                // Unit has no valid output.
131
                o_valid         <= 1'd0;
132
 
133
                // Do not signal any abort.
134
                o_instr_abort   <= 1'd0;
135
 
136
                // Wake unit up.
137
                sleep_ff        <= 1'd0;
138
        end
139
        else if ( i_clear_from_writeback )       clear_unit;
140
        else if ( i_data_stall)                  begin end // Save state.
141
        else if ( i_clear_from_alu )             clear_unit;
142
        else if ( i_stall_from_shifter )         begin end // Save state.
143
        else if ( i_stall_from_issue )           begin end // Save state.
144
        else if ( i_stall_from_decode)           begin end // Save state.
145
        else if ( i_clear_from_decode )          clear_unit;
146
        else if ( i_code_stall )                 begin end
147
 
148
        // If unit is sleeping.
149
        else if ( sleep_ff )
150
        begin
151
                // Nothing valid to be sent.
152
                o_valid         <= 1'd0;
153
 
154
                // No aborts.
155
                o_instr_abort   <= 1'd0;
156
 
157
                // Keep sleeping.
158
                sleep_ff        <= 1'd1;
159
        end
160
 
161
        // Data from memory is valid. This could also be used to signal
162
        // an instruction access abort.
163
        else if ( i_valid )
164
        begin
165
                // Instruction aborts occur with i_valid as 1. See NOTE.
166
                o_valid         <= 1'd1;
167
                o_instr_abort   <= i_instr_abort;
168
 
169
                // Put unit to sleep on an abort.
170
                sleep_ff        <= i_instr_abort;
171
 
172
                //
173
                // Pump PC + 8 or 4 down the pipeline. The number depends on
174
                // ARM/Compressed mode.
175
                //
176
                o_pc_plus_8_ff <= i_cpsr_ff_t ? ( i_pc_ff + 32'd4 ) :
177
                                                ( i_pc_ff + 32'd8 );
178
 
179
                // PC is pumped down the pipeline.
180
                o_pc_ff <= i_pc_ff;
181
 
182 34 Revanth
                // Instruction. If 16-bit aligned address, move data from
183
                // cache by 16-bit to focus on the instruction.
184
                o_instruction <= i_pc_ff[1] ? i_instruction >> 16 : i_instruction;
185 26 Revanth
        end
186
        else
187
        begin
188
                // Invalidate the output.
189
                o_valid        <= 1'd0;
190
        end
191
end
192
 
193 34 Revanth
`ifndef SYNTHESIS
194
 
195
always @ (negedge i_clk)
196
begin
197
        if ( i_pc_ff[0] != 1'd0 )
198
        begin
199
                $display($time, ": Error: PC LSB isn't zero. This is not legal! (Module_Src = %m)");
200
                $finish;
201
        end
202
end
203
 
204
`endif
205
 
206 26 Revanth
// ----------------------------------------------------------------------------
207
 
208
//
209
// Branch State RAM.
210
// Holds the 2-bit state for a range of branches. Whenever a branch is
211
// either detected as correctly taken or incorrectly taken, this RAM is
212
// updated. Each entry in the RAM corresponds to a virtual memory address
213
// whether or not it be a legit branch or not. 
214
//
215
zap_ram_simple
216
#(.DEPTH(BP_ENTRIES), .WIDTH(2)) u_br_ram
217
(
218
        .i_clk(i_clk),
219
 
220
        // The reason that a no-stall condition is included is that
221
        // if the pipeline stalls, this memory should be trigerred multiply
222
        // times.
223
        .i_wr_en(       !i_data_stall             &&
224
                        !i_stall_from_issue       &&
225
                        !i_stall_from_decode      &&
226
                        !i_stall_from_shifter     &&
227
                        (i_clear_from_alu || i_confirm_from_alu)),
228
 
229
        // Lower bits of the PC index into the branch RAM for read and
230
        // write addresses.
231
        .i_wr_addr(i_pc_from_alu[$clog2(BP_ENTRIES):1]),
232
        .i_rd_addr(i_pc_ff[$clog2(BP_ENTRIES):1]),
233
 
234
        // Write the new state.
235
        .i_wr_data(compute(i_taken, i_clear_from_alu)),
236
 
237
        // Read when there is no stall.
238
        .i_rd_en(
239
                        !i_code_stall             &&
240
                        !i_data_stall             &&
241
                        !i_stall_from_issue       &&
242
                        !i_stall_from_decode      &&
243
                        !i_stall_from_shifter
244
        ),
245
 
246
        // Send the read data over to o_taken_ff which is a 2-bit value.
247 39 Revanth
        .o_rd_data(taken_v)
248 26 Revanth
);
249
 
250
// ----------------------------------------------------------------------------
251
 
252
//
253
// Branch Memory writes.
254
// Implements a 4-state predictor. 
255
//
256
function [1:0] compute ( input [1:0] i_taken, input i_clear_from_alu );
257
begin
258
                // Branch was predicted incorrectly. 
259
                if ( i_clear_from_alu )
260
                begin
261
                        case ( i_taken )
262
                        SNT: compute = WNT;
263
                        WNT: compute = WT;
264
                        WT:  compute = WNT;
265
                        ST:  compute = WT;
266
                        endcase
267
                end
268
                else // Confirm from alu that branch was correctly predicted.
269
                begin
270
                        case ( i_taken )
271
                        SNT: compute = SNT;
272
                        WNT: compute = SNT;
273
                        WT:  compute = ST;
274
                        ST:  compute = ST;
275
                        endcase
276
                end
277
end
278
endfunction
279
 
280
// ----------------------------------------------------------------------------
281
 
282
//
283
// This task clears out the unit and refreshes it for a new
284
// service session. Will wake the unit up and clear the outputs.
285
//
286
task clear_unit;
287
begin
288
                // No valid output.
289
                o_valid         <= 1'd0;
290
 
291
                // No aborts since we are clearing out the unit.
292
                o_instr_abort   <= 1'd0;
293
 
294
                // Wake up the unit.
295
                sleep_ff        <= 1'd0;
296
end
297
endtask
298
 
299
assign _unused_ok_ =   i_pc_from_alu[0] &&
300
                       i_pc_from_alu[31:$clog2(BP_ENTRIES) + 1];
301
 
302
// ---------------------------------------------------------------------------------
303
 
304
`ifndef SYNTHESIS
305
 
306
zap_decompile u_zap_decompile (
307
        .i_instruction  ({4'd0, o_instruction}),
308
        .i_dav          (o_valid),
309
        .o_decompile    ()
310
);
311
 
312
`endif
313
 
314
endmodule // zap_fetch_main.v
315
`default_nettype wire

powered by: WebSVN 2.1.0

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