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

Subversion Repositories thor

[/] [thor/] [trunk/] [rtl/] [verilog/] [Thor_TLB.v] - Blame information for rev 21

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

Line No. Rev Author Line
1 3 robfinch
`include "Thor_defines.v"
2
//=============================================================================
3
//        __
4
//   \\__/ o\    (C) 2011,2012,2013  Robert Finch
5
//    \  __ /    All rights reserved.
6
//     \/_//     robfinch<remove>@finitron.ca
7
//       ||
8
//  
9
//      Thor_TLB.v
10
//
11
//  
12
// This source file is free software: you can redistribute it and/or modify 
13
// it under the terms of the GNU Lesser General Public License as published 
14
// by the Free Software Foundation, either version 3 of the License, or     
15
// (at your option) any later version.                                      
16
//                                                                          
17
// This source file is distributed in the hope that it will be useful,      
18
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
19
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
20
// GNU General Public License for more details.                             
21
//                                                                          
22
// You should have received a copy of the GNU General Public License        
23
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
24
//                                                                          
25
//
26
// TLB
27
// The TLB contains 64 entries, that are 8 way set associative.
28
// The TLB is dual ported and shared between the instruction and data streams.
29
//
30
//=============================================================================
31
//
32
`define TLBMissPage             {DBW-12{1'b1}}
33
 
34
module Thor_TLB(rst, clk, km, pc, ea, ppc, pea,
35
        iuncached, uncached,
36
        m1IsStore, ASID, state, op, regno, dati, dato,
37
        ITLBMiss, DTLBMiss, HTLBVirtPageo);
38
parameter DBW=64;
39
input rst;
40
input clk;
41
input km;                                       // kernel mode
42
input [DBW-1:0] pc;
43
input [DBW-1:0] ea;
44
output reg [DBW-1:0] ppc;
45
output reg [DBW-1:0] pea;
46
output iuncached;
47
output uncached;
48
input m1IsStore;
49
input [7:0] ASID;
50
input [2:0] state;
51
input [3:0] op;
52
input [3:0] regno;
53
input [DBW-1:0] dati;
54
output [DBW-1:0] dato;
55
reg [DBW-1:0] dato;
56
output ITLBMiss;
57
output DTLBMiss;
58
output [DBW-1:0] HTLBVirtPageo;
59
 
60
integer n;
61
 
62
// Holding registers
63
// These allow the TLB to updated in a single cycle
64
reg [DBW-1:0] HTLBVirtPage;
65
assign HTLBVirtPageo = {HTLBVirtPage,12'b0};
66
reg [DBW-1:0] HTLBPhysPage;
67
reg [7:0] HTLBASID;
68
reg HTLBG;
69
reg HTLBD;
70
reg [2:0] HTLBC;
71
reg HTLBValid;
72
 
73
reg TLBenabled;
74
reg [5:0] i;
75
reg [DBW-1:0] Index;
76
reg [2:0] Random;
77
reg [2:0] Wired;
78
reg [2:0] PageSize;
79
reg [7:0] IMatch,DMatch;
80
 
81
reg [3:0] m;
82
reg [3:0] q;
83
wire doddpage;
84
reg [DBW-1:0] TLBVirtPage [63:0];
85
reg [DBW-1:0] TLBPhysPage [63:0];
86
reg [63:0] TLBG;
87
reg [63:0] TLBD;
88
reg [2:0] TLBC [63:0];
89
reg [7:0] TLBASID [63:0];
90
reg [63:0] TLBValid;
91
reg [DBW-1:0] imiss_addr;
92
reg [DBW-1:0] dmiss_addr;
93
reg [DBW-1:0] PageTblAddr;
94
reg [DBW-1:0] PageTblCtrl;
95
 
96
initial begin
97
        for (n = 0; n < 64; n = n + 1)
98
        begin
99
                TLBVirtPage[n] = 0;
100
                TLBPhysPage[n] = 0;
101
                TLBG[n] = 0;
102
                TLBASID[n] = 0;
103
                TLBD[n] = 0;
104
                TLBC[n] = 0;
105
                TLBValid[n] = 0;
106
        end
107
end
108
 
109
// Assume the instruction doesn't overlap between a mapped and unmapped area.
110
wire unmappedArea = pc[DBW-1:DBW-4]==4'hF || !TLBenabled;
111
wire unmappedDataArea = ea[DBW-1:DBW-4]==4'hF || !TLBenabled;
112
wire m1UnmappedDataArea = pea[DBW-1:DBW-4]==4'hF || !TLBenabled;
113
wire hitIOPage = ea[DBW-1:DBW-12]==12'hFFD;
114
 
115
always @(posedge clk)
116
if (rst) begin
117
        TLBenabled <= 1'b0;
118
        Random <= 3'h7;
119
        Wired <= 3'd0;
120
        PageSize <= 3'd0;
121
        PageTblAddr <= {DBW{1'b0}};
122
        PageTblCtrl <= {DBW{1'b0}};
123
end
124
else begin
125
        if (dmiss_addr == {DBW{1'b0}} && DTLBMiss)
126
                dmiss_addr <= ea;
127
        if (imiss_addr == {DBW{1'b0}} && ITLBMiss)
128
                imiss_addr <= pc;
129
 
130
        if (Random==Wired)
131
                Random <= 3'd7;
132
        else
133
                Random <= Random - 3'd1;
134
 
135
        if (state==3'd1) begin
136
                case(op)
137
                `TLB_RD,`TLB_WI:
138
                        i <= {Index[5:3],(HTLBVirtPage >> {PageSize,1'b0}) & 3'h7};
139
                `TLB_WR:
140
                        i <= {Random,(HTLBVirtPage >> {PageSize,1'b0}) & 3'h7};
141
                `TLB_WRREG:
142
                        begin
143
                        case(regno)
144
                        `TLBWired:              Wired <= dati[2:0];
145
                        `TLBIndex:              Index <= dati[5:0];
146
                        `TLBRandom:             Random <= dati[2:0];
147
                        `TLBPageSize:   PageSize <= dati[2:0];
148
                        `TLBVirtPage:   HTLBVirtPage <= dati;
149
                        `TLBPhysPage:   HTLBPhysPage <= dati;
150
                        `TLBASID:       begin
151
                                                HTLBValid <= dati[0];
152
                                                HTLBD <= dati[1];
153
                                                HTLBC <= dati[4:2];
154
                                                HTLBASID <= dati[23:16];
155
                                                HTLBG <= dati[31];
156
                                                end
157
                        `TLBDMissAdr:   dmiss_addr <= dati;
158
                        `TLBIMissAdr:   imiss_addr <= dati;
159
                        `TLBPageTblAddr:        PageTblAddr <= dati;
160
                        `TLBPageTblCtrl:        PageTblCtrl <= dati;
161 10 robfinch
                        default: ;
162 3 robfinch
                        endcase
163
                        end
164
                `TLB_EN:
165
                        TLBenabled <= 1'b1;
166
                `TLB_DIS:
167
                        TLBenabled <= 1'b0;
168
                `TLB_INVALL:
169
                        TLBValid <= 64'd0;
170 10 robfinch
                default:  ;
171 3 robfinch
                endcase
172
        end
173
        else if (state==3'd2) begin
174
                case(op)
175
                `TLB_P:
176
                        begin
177
                                Index[DBW-1] <= ~|DMatch;
178
                        end
179
                `TLB_RD:
180
                        begin
181
                                HTLBVirtPage <= TLBVirtPage[i];
182
                                HTLBPhysPage <= TLBPhysPage[i];
183
                                HTLBASID <= TLBASID[i];
184
                                HTLBG <= TLBG[i];
185
                                HTLBD <= TLBD[i];
186
                                HTLBC <= TLBC[i];
187
                                HTLBValid <= TLBValid[i];
188
                        end
189
                `TLB_WR,`TLB_WI:
190
                        begin
191
                                TLBVirtPage[i] <= HTLBVirtPage;
192
                                TLBPhysPage[i] <= HTLBPhysPage;
193
                                TLBASID[i] <= HTLBASID;
194
                                TLBG[i] <= HTLBG;
195
                                TLBD[i] <= HTLBD;
196
                                TLBC[i] <= HTLBC;
197
                                TLBValid[i] <= HTLBValid;
198
                        end
199
                default:  ;
200
                endcase
201
        end
202
 
203
        // Set the dirty bit on a store
204
        if (m1IsStore)
205
                if (!m1UnmappedDataArea & !q[3]) begin
206
                        TLBD[{q[2:0],(pea[DBW-1:12]>>{PageSize,1'b0})&3'd7}] <= 1'b1;
207
                end
208
end
209
 
210
always @*
211
        case(regno)
212
        `TLBWired:              dato = Wired;
213
        `TLBIndex:              dato = Index;
214
        `TLBRandom:             dato = Random;
215
        `TLBPhysPage:   dato = HTLBPhysPage;
216
        `TLBVirtPage:   dato = HTLBVirtPage;
217
        `TLBPageSize:   dato = PageSize;
218
        `TLBASID:       begin
219
                                dato = {DBW{1'b0}};
220
                                dato[0] = HTLBValid;
221
                                dato[1] = HTLBD;
222
                                dato[4:2] = HTLBC;
223
                                dato[23:16] = HTLBASID;
224
                                dato[31] = HTLBG;
225
                                end
226
        `TLBDMissAdr:   dato = dmiss_addr;
227
        `TLBIMissAdr:   dato = imiss_addr;
228
        `TLBPageTblAddr:        dato = PageTblAddr;
229
        `TLBPageTblCtrl:        dato = PageTblCtrl;
230
        default:        dato = {DBW{1'b0}};
231
        endcase
232
 
233
wire [DBW-1:0] pcs = pc[DBW-1:12] >> {PageSize,1'b0};
234
always @*
235
for (n = 0; n < 8; n = n + 1)
236
begin
237
        IMatch[n[2:0]] = (pcs[DBW-1:3]==TLBVirtPage[{n[2:0],pcs[2:0]}][DBW-1:3]) &&
238
                                ((TLBASID[{n,pcs[2:0]}]==ASID) || TLBG[{n,pcs[2:0]}]) &&
239
                                TLBValid[{n[2:0],pcs[2:0]}];
240
end
241
 
242
always @(IMatch)
243
if (IMatch[0]) m <= 4'd0;
244
else if (IMatch[1]) m <= 4'd1;
245
else if (IMatch[2]) m <= 4'd2;
246
else if (IMatch[3]) m <= 4'd3;
247
else if (IMatch[4]) m <= 4'd4;
248
else if (IMatch[5]) m <= 4'd5;
249
else if (IMatch[6]) m <= 4'd6;
250
else if (IMatch[7]) m <= 4'd7;
251
else m <= 4'd15;
252
 
253
 
254
wire [DBW-1:0] IPFN = TLBPhysPage[{m[2:0],pcs[2:0]}];
255
assign iuncached = TLBC[{m[2:0],pcs[2:0]}]==3'd1;
256
 
257
assign ITLBMiss = TLBenabled & (!unmappedArea & (m[3] | ~TLBValid[{m[2:0],pcs[2:0]}]));
258
 
259
always @*
260
begin
261
        ppc[11:0] = pc[11:0];
262
        case(PageSize)
263
        3'd0:   ppc[DBW-1:12] = unmappedArea ? pc[DBW-1:12] : ITLBMiss ? `TLBMissPage: IPFN;                            // 4KiB
264
        3'd1:   ppc[DBW-1:12] = {unmappedArea ? pc[DBW-1:14] : ITLBMiss ? `TLBMissPage: IPFN,pc[13:12]};        // 16KiB
265
        3'd2:   ppc[DBW-1:12] = {unmappedArea ? pc[DBW-1:16] : ITLBMiss ? `TLBMissPage: IPFN,pc[15:12]};        // 64KiB
266
        3'd3:   ppc[DBW-1:12] = {unmappedArea ? pc[DBW-1:18] : ITLBMiss ? `TLBMissPage: IPFN,pc[17:12]};        // 256 KiB
267
        3'd4:   ppc[DBW-1:12] = {unmappedArea ? pc[DBW-1:20] : ITLBMiss ? `TLBMissPage: IPFN,pc[19:12]};        // 1 MiB
268
        default:        ppc[DBW-1:12] = pc[DBW-1:12];
269
        endcase
270
end
271
 
272
wire [DBW-1:0] eas = ea[DBW-1:12] >> {PageSize,1'b0};
273 10 robfinch
always @(eas or ASID or q or TLBG or TLBValid)
274 3 robfinch
for (n = 0; n < 8; n = n + 1)
275
        DMatch[n[2:0]] = (eas[DBW-1:3]==TLBVirtPage[{n,eas[2:0]}]) &&
276
                                ((TLBASID[{n,eas[2:0]}]==ASID) || TLBG[{n,eas[2:0]}]) &&
277
                                TLBValid[{q[2:0],eas[2:0]}];
278
always @(DMatch)
279
if (DMatch[0]) q <= 4'd0;
280
else if (DMatch[1]) q <= 4'd1;
281
else if (DMatch[2]) q <= 4'd2;
282
else if (DMatch[3]) q <= 4'd3;
283
else if (DMatch[4]) q <= 4'd4;
284
else if (DMatch[5]) q <= 4'd5;
285
else if (DMatch[6]) q <= 4'd6;
286
else if (DMatch[7]) q <= 4'd7;
287
else q <= 4'd15;
288
 
289
wire [DBW-1:0] DPFN = TLBPhysPage[{q[2:0],eas[2:0]}];
290
assign uncached = TLBC[{q[2:0],eas[2:0]}]==3'd1;// || unmappedDataArea;
291
 
292
assign DTLBMiss = TLBenabled & (!unmappedDataArea & (q[3] | ~TLBValid[{q[2:0],eas[2:0]}]) ||
293
                                        (!km && hitIOPage));
294
 
295
always @*
296
begin
297
        case(PageSize)
298
        3'd0:   pea[DBW-1:12] = unmappedDataArea ? ea[DBW-1:12] : DTLBMiss ? `TLBMissPage: DPFN;
299
        3'd1:   pea[DBW-1:12] = {unmappedDataArea ? ea[DBW-1:14] : DTLBMiss ? `TLBMissPage: DPFN,ea[13:12]};
300
        3'd2:   pea[DBW-1:12] = {unmappedDataArea ? ea[DBW-1:16] : DTLBMiss ? `TLBMissPage: DPFN,ea[15:12]};
301
        3'd3:   pea[DBW-1:12] = {unmappedDataArea ? ea[DBW-1:18] : DTLBMiss ? `TLBMissPage: DPFN,ea[17:12]};
302
        3'd4:   pea[DBW-1:12] = {unmappedDataArea ? ea[DBW-1:20] : DTLBMiss ? `TLBMissPage: DPFN,ea[19:12]};
303
        default:        pea[DBW-1:12] = ea[DBW-1:12];
304
        endcase
305
        pea[11:0] = ea[11:0];
306
end
307
 
308
endmodule
309
 

powered by: WebSVN 2.1.0

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