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

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v7/] [rtl/] [common/] [FT64_ICController.v] - Blame information for rev 66

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 66 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2017-2019  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@finitron.ca
6
//       ||
7
//
8
//      FT64_ICController.v
9
//
10
// This source file is free software: you can redistribute it and/or modify 
11
// it under the terms of the GNU Lesser General Public License as published 
12
// by the Free Software Foundation, either version 3 of the License, or     
13
// (at your option) any later version.                                      
14
//                                                                          
15
// This source file is distributed in the hope that it will be useful,      
16
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
17
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
18
// GNU General Public License for more details.                             
19
//                                                                          
20
// You should have received a copy of the GNU General Public License        
21
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
22
//
23
// ============================================================================
24
//
25
`include ".\FT64_config.vh"
26
`define HIGH    1'b1
27
`define LOW             1'b0;
28
 
29
module FT64_ICController(clk_i, asid, pc0, pc1, pc2, hit0, hit1, hit2, bstate, state,
30
        invline, invlineAddr,
31
        thread_en, ihitL2, selL2, L2_ld, L2_cnt, L2_adr, L2_dato, L2_nxt,
32
        L1_selpc, L1_adr, L1_dat, L1_wr0, L1_wr1, L1_wr2, L1_en, L1_invline, icnxt, icwhich,
33
        icl_o, cti_o, bte_o, bok_i, cyc_o, stb_o, ack_i, err_i, tlbmiss_i, exv_i, sel_o, adr_o, dat_i);
34
parameter ABW = 64;
35
parameter AMSB = ABW-1;
36
parameter RSTPC = 64'hFFFFFFFFFFFC0100;
37
input clk_i;
38
input [7:0] asid;
39
input [AMSB:0] pc0;
40
input [AMSB:0] pc1;
41
input [AMSB:0] pc2;
42
input hit0;
43
input hit1;
44
input hit2;
45
input [4:0] bstate;
46
(* mark_debug="true" *)
47
output reg [3:0] state = IDLE;
48
input invline;
49
input [71:0] invlineAddr;
50
input thread_en;
51
input ihitL2;
52
output reg selL2 = 1'b0;
53
output reg L2_ld;
54
output [2:0] L2_cnt;
55
output reg [71:0] L2_adr = RSTPC;
56
input [305:0] L2_dato;
57
output reg L2_nxt;
58
output L1_selpc;
59
output reg [71:0] L1_adr = RSTPC;
60
output reg [305:0] L1_dat = {2'b0,{38{8'h3D}}};  // NOP
61
output reg L1_wr0;
62
output reg L1_wr1;
63
output reg L1_wr2;
64
output reg [9:0] L1_en;
65
output reg L1_invline;
66
output reg icnxt;
67
output reg [1:0] icwhich;
68
output reg icl_o;
69
output reg [2:0] cti_o = 3'b000;
70
output reg [1:0] bte_o = 2'b00;
71
input bok_i;
72
output reg cyc_o = 1'b0;
73
output reg stb_o;
74
input ack_i;
75
input err_i;
76
input tlbmiss_i;
77
input exv_i;
78
output reg [7:0] sel_o;
79
output reg [71:0] adr_o;
80
input [63:0] dat_i;
81
 
82
parameter TRUE = 1'b1;
83
parameter FALSE = 1'b0;
84
 
85
reg [3:0] picstate;
86
`include ".\FT64_busStates.vh"
87
reg invline_r = 1'b0;
88
reg [71:0] invlineAddr_r = 72'd0;
89
 
90
wire [AMSB:0] pc0plus6 = pc0 + 8'd7;
91
wire [AMSB:0] pc0plus12 = pc0 + 8'd14;
92
 
93
//assign L2_ld = (state==IC_Ack) && (ack_i|err_i|tlbmiss_i|exv_i);
94
assign L1_selpc = (state==IDLE||state==IC_Next) && !invline_r;
95
 
96
wire clk = clk_i;
97
reg [2:0] iccnt;
98
assign L2_cnt = iccnt;
99
 
100
//BUFH uclkb (.I(clk_i), .O(clk));
101
 
102
always @(posedge clk)
103
begin
104
L1_wr0 <= FALSE;
105
L1_wr1 <= FALSE;
106
L1_wr2 <= FALSE;
107
L1_en <= 10'h000;
108
L1_invline <= FALSE;
109
icnxt <= FALSE;
110
L2_nxt <= FALSE;
111
if (invline) begin
112
        invline_r <= 1'b1;
113
        invlineAddr_r <= invlineAddr;
114
end
115
 
116
// Instruction cache state machine.
117
// On a miss first see if the instruction is in the L2 cache. No need to go to
118
// the BIU on an L1 miss.
119
// If not the machine will wait until the BIU loads the L2 cache.
120
 
121
// Capture the previous ic state, used to determine how long to wait in
122
// icstate #4.
123
picstate <= state;
124
case(state)
125
IDLE:
126
        begin
127
                iccnt <= 3'd0;
128
                if (invline_r) begin
129
                        L1_adr <= {invlineAddr_r[71:5],5'b0};
130
                        L1_invline <= TRUE;
131
                        invline_r <= 1'b0;
132
                end
133
                // If the bus unit is busy doing an update involving L1_adr or L2_adr
134
                // we have to wait.
135
                else begin
136
                        if (!hit0) begin
137
                                L1_adr <= {asid,pc0[AMSB:5],5'h0};
138
                                L1_invline <= TRUE;
139
                                icwhich <= 2'b00;
140
                                state <= IC2;
141
                        end
142
                        else if (!hit1 && `WAYS > 1) begin
143
                                if (thread_en) begin
144
                                        L1_adr <= {asid,pc1[AMSB:5],5'h0};
145
                                end
146
                                else begin
147
                                        L1_adr <= {asid,pc0plus6[AMSB:5],5'h0};
148
                                end
149
                                L1_invline <= TRUE;
150
                                icwhich <= 2'b01;
151
                                state <= IC2;
152
                        end
153
                        else if (!hit2 && `WAYS > 2) begin
154
                                if (thread_en) begin
155
                                        L1_adr <= {asid,pc2[AMSB:5],5'h0};
156
                                end
157
                                else begin
158
                                        L1_adr <= {asid,pc0plus12[AMSB:5],5'h0};
159
                                end
160
                                L1_invline <= TRUE;
161
                                icwhich <= 2'b10;
162
                                state <= IC2;
163
                        end
164
                end
165
        end
166
 
167
IC2:     state <= IC3;
168
IC3:     state <= IC3a;
169
IC3a:     state <= IC_WaitL2;
170
// If data was in the L2 cache already there's no need to wait on the
171
// BIU to retrieve data. It can be determined if the hit signal was
172
// already active when this state was entered in which case waiting
173
// will do no good.
174
// The IC machine will stall in this state until the BIU has loaded the
175
// L2 cache. 
176
IC_WaitL2:
177
        if (ihitL2 && picstate==IC3a) begin
178
                L1_en <= 10'h3FF;
179
                L1_wr0 <= TRUE;
180
                L1_wr1 <= TRUE && `WAYS > 1;
181
                L1_wr2 <= TRUE && `WAYS > 2;
182
//              L1_adr <= L2_adr;
183
                // L1_dati is loaded dring an L2 icache load operation
184
//              if (picstate==IC3a)
185
                L1_dat <= L2_dato;
186
                state <= IC5;
187
        end
188
        else begin
189
                if (bstate == B_WaitIC)
190
                        state <= IC_Access;
191
        end
192
/*
193
        else if (state!=IC_Nack)
194
                ;
195
        else begin
196
                L1_en <= 10'h3FF;
197
                L1_wr0 <= TRUE;
198
                L1_wr1 <= TRUE && `WAYS > 1;
199
                L1_wr2 <= TRUE && `WAYS > 2;
200
//              L1_adr <= L2_adr;
201
                // L1_dati set below while loading cache line
202
                //L1_dati <= L2_dato;
203
                state <= IC5;
204
        end
205
*/
206
IC5:    state <= IC6;
207
IC6:  state <= IC7;
208
IC7:    state <= IC_Next;
209
IC_Next:
210
  begin
211
   state <= IDLE;
212
   icnxt <= TRUE;
213
        end
214
IC_Access:
215
        begin
216
                iccnt <= 3'd0;
217
                icl_o <= `HIGH;
218
                cti_o <= 3'b001;
219
                bte_o <= 2'b00;
220
                cyc_o <= `HIGH;
221
                stb_o <= `HIGH;
222
                sel_o <= 8'hFF;
223
                adr_o <= {L1_adr[AMSB:5],5'b0};
224
                L2_adr <= L1_adr;
225
                L2_adr[4:0] <= 5'd0;
226
                selL2 <= TRUE;
227
                L2_ld <= TRUE;
228
                state <= IC_Ack;
229
        end
230
IC_Ack:
231
  if (ack_i|err_i|tlbmiss_i|exv_i) begin
232
        L2_ld <= TRUE;
233
        if (!bok_i) begin
234
                stb_o <= `LOW;
235
                        adr_o[AMSB:3] <= adr_o[AMSB:3] + 2'd1;
236
                state <= IC_Nack2;
237
        end
238
                if (tlbmiss_i) begin
239
                        L1_dat[305:304] <= 2'd1;
240
                        L1_dat[303:0] <= {38{8'h3D}};    // NOP
241
                        nack();
242
          end
243
                else if (exv_i) begin
244
                        L1_dat[305:304] <= 2'd2;
245
                        L1_dat[303:0] <= {38{8'h3D}};    // NOP
246
                        nack();
247
                end
248
          else if (err_i) begin
249
                        L1_dat[305:304] <= 2'd3;
250
                        L1_dat[303:0] <= {38{8'h3D}};    // NOP
251
                        nack();
252
          end
253
          else
254
                case(iccnt)
255
                3'd0:   L1_dat[63:0] <= dat_i;
256
                3'd1:   L1_dat[127:64] <= dat_i;
257
                3'd2:   L1_dat[191:128] <= dat_i;
258
                3'd3:   L1_dat[255:192] <= dat_i;
259
                3'd4:   L1_dat[305:256] <= {2'b00,dat_i[47:0]};
260
                default:        L1_dat <= L1_dat;
261
                endcase
262
    iccnt <= iccnt + 3'd1;
263
    if (iccnt==3'd3)
264
      cti_o <= 3'b111;
265
    if (iccnt>=3'd4)
266
        nack();
267
  end
268
IC_Nack2:
269
        if (~ack_i) begin
270
                stb_o <= `HIGH;
271
                state <= IC_Ack;
272
        end
273
IC_Nack:
274
        begin
275
    iccnt <= iccnt + 3'd1;
276
                L2_ld <= FALSE;
277
                selL2 <= FALSE;
278
                if (~ack_i) begin
279
                        //icl_ctr <= icl_ctr + 40'd1;
280
                        state <= IDLE;
281
                        L2_nxt <= TRUE;
282
                end
283
        end
284
default:
285
        begin
286
        state <= IDLE;
287
  end
288
endcase
289
end
290
 
291
task nack;
292
begin
293
        icl_o <= `LOW;
294
        cti_o <= 3'b000;
295
        cyc_o <= `LOW;
296
        stb_o <= `LOW;
297
        L1_en <= 10'h3FF;
298
        L1_wr0 <= TRUE;
299
        L1_wr1 <= TRUE && `WAYS > 1;
300
        L1_wr2 <= TRUE && `WAYS > 2;
301
        state <= IC_Nack;
302
end
303
endtask
304
 
305
endmodule

powered by: WebSVN 2.1.0

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