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 43

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 43 Revanth
output wire [1:0]  o_taken              // 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 43 Revanth
assign o_taken    = o_instruction[28:26] == 3'b101 ? taken_v : SNT;
99 39 Revanth
 
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
always @ (negedge i_clk)
194
begin
195
        if ( i_pc_ff[0] != 1'd0 )
196
        begin
197 43 Revanth
                $display($time, " - %m :: Error: PC LSB isn't zero. This is not legal...");
198 34 Revanth
                $finish;
199
        end
200
end
201
 
202 26 Revanth
// ----------------------------------------------------------------------------
203
 
204
//
205
// Branch State RAM.
206
// Holds the 2-bit state for a range of branches. Whenever a branch is
207
// either detected as correctly taken or incorrectly taken, this RAM is
208
// updated. Each entry in the RAM corresponds to a virtual memory address
209
// whether or not it be a legit branch or not. 
210
//
211
zap_ram_simple
212
#(.DEPTH(BP_ENTRIES), .WIDTH(2)) u_br_ram
213
(
214
        .i_clk(i_clk),
215
 
216
        // The reason that a no-stall condition is included is that
217
        // if the pipeline stalls, this memory should be trigerred multiply
218
        // times.
219
        .i_wr_en(       !i_data_stall             &&
220
                        !i_stall_from_issue       &&
221
                        !i_stall_from_decode      &&
222
                        !i_stall_from_shifter     &&
223
                        (i_clear_from_alu || i_confirm_from_alu)),
224
 
225
        // Lower bits of the PC index into the branch RAM for read and
226
        // write addresses.
227
        .i_wr_addr(i_pc_from_alu[$clog2(BP_ENTRIES):1]),
228
        .i_rd_addr(i_pc_ff[$clog2(BP_ENTRIES):1]),
229
 
230
        // Write the new state.
231
        .i_wr_data(compute(i_taken, i_clear_from_alu)),
232
 
233
        // Read when there is no stall.
234
        .i_rd_en(
235
                        !i_code_stall             &&
236
                        !i_data_stall             &&
237
                        !i_stall_from_issue       &&
238
                        !i_stall_from_decode      &&
239
                        !i_stall_from_shifter
240
        ),
241
 
242
        // Send the read data over to o_taken_ff which is a 2-bit value.
243 39 Revanth
        .o_rd_data(taken_v)
244 26 Revanth
);
245
 
246
// ----------------------------------------------------------------------------
247
 
248
//
249
// Branch Memory writes.
250
// Implements a 4-state predictor. 
251
//
252
function [1:0] compute ( input [1:0] i_taken, input i_clear_from_alu );
253
begin
254
                // Branch was predicted incorrectly. 
255
                if ( i_clear_from_alu )
256
                begin
257
                        case ( i_taken )
258
                        SNT: compute = WNT;
259
                        WNT: compute = WT;
260
                        WT:  compute = WNT;
261
                        ST:  compute = WT;
262
                        endcase
263
                end
264
                else // Confirm from alu that branch was correctly predicted.
265
                begin
266
                        case ( i_taken )
267
                        SNT: compute = SNT;
268
                        WNT: compute = SNT;
269
                        WT:  compute = ST;
270
                        ST:  compute = ST;
271
                        endcase
272
                end
273
end
274
endfunction
275
 
276
// ----------------------------------------------------------------------------
277
 
278
//
279
// This task clears out the unit and refreshes it for a new
280
// service session. Will wake the unit up and clear the outputs.
281
//
282
task clear_unit;
283
begin
284
                // No valid output.
285
                o_valid         <= 1'd0;
286
 
287
                // No aborts since we are clearing out the unit.
288
                o_instr_abort   <= 1'd0;
289
 
290
                // Wake up the unit.
291
                sleep_ff        <= 1'd0;
292
end
293
endtask
294
 
295
assign _unused_ok_ =   i_pc_from_alu[0] &&
296
                       i_pc_from_alu[31:$clog2(BP_ENTRIES) + 1];
297
 
298
// ---------------------------------------------------------------------------------
299
 
300
zap_decompile u_zap_decompile (
301
        .i_instruction  ({4'd0, o_instruction}),
302
        .i_dav          (o_valid),
303
        .o_decompile    ()
304
);
305
 
306
 
307
endmodule // zap_fetch_main.v
308
`default_nettype wire

powered by: WebSVN 2.1.0

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