Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / dmu / rtl / dmu_mmu_tlb.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: dmu_mmu_tlb.v
4// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
5// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
6//
7// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8//
9// This program is free software; you can redistribute it and/or modify
10// it under the terms of the GNU General Public License as published by
11// the Free Software Foundation; version 2 of the License.
12//
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21//
22// For the avoidance of doubt, and except that if any non-GPL license
23// choice is available it will apply instead, Sun elects to use only
24// the General Public License version 2 (GPLv2) at this time for any
25// software where a choice of GPL license versions is made
26// available with the language indicating that GPLv2 or any later version
27// may be used, or where a choice of which version of the GPL is applied is
28// otherwise unspecified.
29//
30// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
31// CA 95054 USA or visit www.sun.com if you need additional information or
32// have any questions.
33//
34// ========== Copyright Header End ============================================
35module dmu_mmu_tlb
36 (
37 clk, // clock
38 rst_l, // synchronous reset
39 csr2tlb_ps, // csr page size
40 csr2tlb_tb, // csr table base address
41 csr2tlb_ts, // csr table size
42 rcb2tlb_dhi, // rcb data high
43 rcb2tlb_dlo, // rcb data low
44 tcb2tlb_dld, // tlb data load
45 tcb2tlb_hld, // tlb hold
46 tcb2tlb_ra, // tlb read address
47 tcb2tlb_ras, // tlb read address select
48 tcb2tlb_sel, // tlb select
49 tcb2tlb_tld, // tlb tag load
50 vab2tlb_addr, // vab address
51 vab2tlb_rqid, // vab requester ID
52 vab2tlb_type, // vab type
53 vab2tlb_iotsbno, // vab iotsb for sun4v mode
54 vab2tlb_tsbbpa, // tablewalk base pa for sun4v mode
55 vab2tlb_sun4v_pgnmb, // sun4v page number for tablewalks
56 vab2tlb_sun4v_pgsz, // sun4v page size to adjust new tag write into vtb
57 vtb2tlb_dbra, // vtb data buffer read address
58 tlb2csr_addr, // csr address
59 tlb2csr_dbra, // csr data buffer read address
60 tlb2csr_rqid, // csr requester ID
61 tlb2csr_type, // csr type
62 tlb2tdb_rqid, // csr requester ID to tdb to compare against current entry
63 tlb2pab_addr, // pab address
64 tlb2pab_sun4v_pgsz, // sun4v page size for pa adr concat
65 tlb2pab_type, // pab type
66 tlb2pab_vld, // pab valid
67 tlb2pab_wrt, // pab write
68 tlb2ptb_addr, // ptb physical tag address
69 tlb2rcb_addr, // rcb address
70 tlb2tcb_hit, // tcb virtual tag hit
71 tlb2tdb_data, // tdb data
72 tlb2vtb_addr, // vtb virtual tag address
73 tlb2vtb_iotsbno, // vtb virtual iotsb for sun4v mode
74 sun4v_mode, // 1=sun4v mode
75 tlb2tmc_kerr, // key mismatch error from single entry tlb
76 tlb2pab_byp_ps2, // sun4v bypass for pab tdb parity check
77 vab2tlb_sun4v_byp_ps1 // sun4v bypass for pab tdb parity check
78 );
79
80// ----------------------------------------------------------------------------
81// Parameters
82// ----------------------------------------------------------------------------
83 parameter PAM = `FIRE_PA_MSB, // physical address MSB
84 VTL = `FIRE_DLC_MMU_VTD_VPN_LSB, // virtual tag LSB
85 VTM = `FIRE_DLC_MMU_VTD_VPN_MSB; // virtual tag MSB
86
87// ----------------------------------------------------------------------------
88// Ports
89// ----------------------------------------------------------------------------
90 input clk;
91 input rst_l;
92
93 input csr2tlb_ps;
94 input [`FIRE_DLC_MMU_CSR_TB_BITS] csr2tlb_tb;
95 input [`FIRE_DLC_MMU_CSR_TS_BITS] csr2tlb_ts;
96 input [`FIRE_DLC_MMU_TDR_DATA_BITS] rcb2tlb_dhi;
97 input [`FIRE_DLC_MMU_TDR_DATA_BITS] rcb2tlb_dlo;
98 input tcb2tlb_dld;
99 input tcb2tlb_hld;
100 input [`FILE_DLC_MMU_TTE_CNT_BITS] tcb2tlb_ra;
101 input tcb2tlb_ras;
102 input tcb2tlb_sel;
103 input tcb2tlb_tld;
104 input [`FIRE_DLC_MMU_VA_ADDR_BITS] vab2tlb_addr;
105 input [`FIRE_DLC_MMU_VA_RQID_BITS] vab2tlb_rqid;
106 input [`FIRE_DLC_MMU_VA_TYPE_BITS] vab2tlb_type;
107 input [`FIRE_DLC_MMU_VAR_IOTSB_BITS] vab2tlb_iotsbno;
108 input [`FIRE_DLC_MMU_IOTSB_BSPA_BITS] vab2tlb_tsbbpa;
109 input [27:0] vab2tlb_sun4v_pgnmb;
110 input [2:0] vab2tlb_sun4v_pgsz;
111 input [`FIRE_DLC_MMU_TDB_PTR_BITS] vtb2tlb_dbra;
112 input sun4v_mode;
113
114 output [`FIRE_DLC_MMU_VA_ADDR_BITS] tlb2csr_addr;
115 output [`FIRE_DLC_MMU_TDB_PTR_BITS] tlb2csr_dbra;
116 output [`FIRE_DLC_MMU_VA_RQID_BITS] tlb2csr_rqid;
117 output [`FIRE_DLC_MMU_VA_TYPE_BITS] tlb2csr_type;
118 output [`FIRE_DLC_MMU_VA_RQID_BITS] tlb2tdb_rqid;
119 output [`FIRE_DLC_MMU_PA_ADDR_BITS] tlb2pab_addr;
120 output [2:0] tlb2pab_sun4v_pgsz;
121 output [`FIRE_DLC_MMU_PA_TYPE_BITS] tlb2pab_type;
122 output tlb2pab_vld;
123 output tlb2pab_wrt;
124 output [`FIRE_DLC_MMU_PTD_TAG_BITS] tlb2ptb_addr;
125 output [`FIRE_DLC_MMU_PTD_TAG_BITS] tlb2rcb_addr;
126 output tlb2tcb_hit;
127 output [`FIRE_DLC_MMU_TDR_MINUS_PAR_BITS] tlb2tdb_data;
128 output [`FIRE_DLC_MMU_VTD_VPN_BITS] tlb2vtb_addr;
129 output [`FIRE_DLC_MMU_VAR_IOTSB_BITS] tlb2vtb_iotsbno;
130 output tlb2tmc_kerr;
131 input vab2tlb_sun4v_byp_ps1;
132 output tlb2pab_byp_ps2;
133
134// ----------------------------------------------------------------------------
135// Variables
136// ----------------------------------------------------------------------------
137 wire [`FIRE_DLC_MMU_VA_ADDR_BITS] tlb2csr_addr, addr_ps1;
138 wire [`FIRE_DLC_MMU_TDB_PTR_BITS] tlb2csr_dbra, dbra_ps1;
139 wire [`FIRE_DLC_MMU_VA_RQID_BITS] tlb2csr_rqid, rqid_ps1;
140 wire [`FIRE_DLC_MMU_VA_TYPE_BITS] tlb2csr_type, type_ps1;
141 reg [`FIRE_DLC_MMU_PA_ADDR_BITS] tlb2pab_addr;
142 reg [25:0] sun4v_tlb_addr;
143 wire [`FIRE_DLC_MMU_PA_TYPE_BITS] tlb2pab_type;
144 wire [`FIRE_DLC_MMU_PTD_TAG_BITS] tlb2ptb_addr;
145 wire [`FIRE_DLC_MMU_PTD_TAG_BITS] tlb2rcb_addr;
146 wire [`FIRE_DLC_MMU_TDR_MINUS_PAR_BITS] tlb2tdb_data;
147 wire [`FIRE_DLC_MMU_VTD_VPN_BITS] tlb2vtb_addr;
148
149 wire [`FIRE_DLC_MMU_VAR_IOTSB_BITS] tlb2vtb_iotsbno;
150
151
152 wire [`FIRE_DLC_MMU_PTD_TAG_BITS] new_ptag;
153 reg [`FIRE_DLC_MMU_VTD_VPN_BITS] new_vtag, vtag_ps1;
154 reg [`FIRE_DLC_MMU_VTD_VPN_BITS] sun4v_new_vtag,sun4v_vtag_ps1;
155 wire [`FIRE_DLC_MMU_VAR_IOTSB_BITS] iotsbno_ps1;
156 wire [`FIRE_DLC_MMU_IOTSB_BSPA_BITS] tsbbpa_ps1;
157 wire [`FIRE_DLC_MMU_TDR_DATA_BITS] data;
158 wire [`FIRE_DLC_MMU_TDD_PPN_BITS] ppn;
159 wire [`FILE_DLC_MMU_TTE_CNT_BITS] ra;
160 wire [1:0] sel;
161
162 reg [`FIRE_DLC_MMU_VA_ADDR_BITS] addr_ps2;
163 reg [`FIRE_DLC_MMU_TDB_PTR_BITS] dbra_ps2;
164 reg [`FIRE_DLC_MMU_VA_RQID_BITS] rqid_ps2;
165 reg [`FIRE_DLC_MMU_VA_TYPE_BITS] type_ps2;
166 reg [`FIRE_DLC_MMU_VAR_IOTSB_BITS] iotsbno_ps2,tlb_iotsbno;
167 reg [`FIRE_DLC_MMU_IOTSB_BSPA_BITS] tsbbpa_ps2;
168
169 reg [`FIRE_DLC_MMU_PTD_TAG_BITS] tlb_ptag;
170 reg [`FIRE_DLC_MMU_VTD_VPN_BITS] tlb_vtag;
171 reg [`FIRE_DLC_MMU_TDR_DATA_BITS] tlb_data [0:7];
172 reg [2:0] sun4v_pgsz_ps2;
173 reg [27:0] vab2tlb_sun4v_pgnmb_ps2;
174 wire [2:0] sun4v_pgsz_ps1;
175 reg tlb2pab_byp_ps2;
176
177// ----------------------------------------------------------------------------
178// Zero In Checkers
179// ----------------------------------------------------------------------------
180
181// // 0in odd_parity -var {data[31:24], dpar[3]}
182// // 0in odd_parity -var {data[23:16], dpar[2]}
183// // 0in odd_parity -var {data[15:8], dpar[1]}
184// // 0in odd_parity -var {data[7:0], dpar[0]}
185
186// ----------------------------------------------------------------------------
187// Functions
188// ----------------------------------------------------------------------------
189 function [`FIRE_DLC_MMU_PTD_TAG_BITS] tsb_addr; // tsb_addr [42:6]
190// input [`FIRE_DLC_MMU_VTD_TAG_BITS] va; // va was 31:16
191 input [`FIRE_DLC_MMU_VTD_VPN_BITS] va; // va is now 39:16
192 input [27:0] sun4v_pgnmb; // va is now 39:16
193 input [`FIRE_DLC_MMU_CSR_TB_BITS] tb;
194 input [`FIRE_DLC_MMU_CSR_TS_BITS] ts;
195 input ps;
196 input mode; // 1 = sun4v
197 input [`FIRE_DLC_MMU_IOTSB_BSPA_BITS] tsbbpa; // value from iotsb ram, add 13 0's after for [38:0]
198
199 reg [32:0] a,b,c; // new adder is 36 bits
200 reg [21:6] offset;
201 reg [21:6] index;
202// reg [`FIRE_DLC_MMU_PTD_TAG_BITS] addr;
203
204// tsb_addr generates the translation table address for tablewalks based upon
205// the virtual address(va), tsb base address (tb), tsb table size (ts), and
206// page size (ps)
207
208 begin
209 offset = ps ? {3'b000, va[31:19]} : va[31:16];
210 case (ts)
211 4'b0000 : index = {9'b000000000, offset[12:6]};
212 4'b0001 : index = {8'b00000000, offset[13:6]};
213 4'b0010 : index = {7'b0000000, offset[14:6]};
214 4'b0011 : index = {6'b000000, offset[15:6]};
215 4'b0100 : index = {5'b00000, offset[16:6]};
216 4'b0101 : index = {4'b0000, offset[17:6]};
217 4'b0110 : index = {3'b000, offset[18:6]};
218 4'b0111 : index = {2'b00, offset[19:6]};
219 4'b1000 : index = {1'b0, offset[20:6]};
220 default : index = offset;
221 endcase
222
223// if sun4v mode, add the sun4v adjusted page shifted by 3 bits to the sun4v base number[38:0], so
224// the adjusted base page is added to 38:3 because each entry is 8 bytes(64 bits)
225// if sun4u mode, use the FIRE values
226
227 if (mode) begin
228 a = {{8{1'b0}},sun4v_pgnmb[27:3]};// this is sun4v adjusted page number, ie shift by 3
229 b = {tsbbpa,{7{1'b0}}}; // note [2:0] are always 0 for both a and b
230 end
231 else begin
232 a = {{7{1'b0}},tb[38:13]}; // sun4u, in this mode the adder starts at adr[13]
233 b = {{24{1'b0}},index[21:13]};
234 end
235 c = a + b; // 36 bit adder sun4u=0's,[42:13], sun4v=[38:3]
236
237// addr[PAM:13] = tb + { { PAM-21 { 1'b0 } }, index[21:13]};
238// addr[12:6] = index[12:6];
239 if (mode) begin
240 tsb_addr = {c[32:0]}; // always output [38:6], sun4v[39] always 0
241 end
242 else begin
243 tsb_addr = {c[25:0],index[12:6]}; // output [38:6]
244 end
245 end
246 endfunction // tsb_addr
247
248// ----------------------------------------------------------------------------
249// Combinational
250// ----------------------------------------------------------------------------
251
252// csr log data
253 assign tlb2csr_addr = addr_ps2;
254 assign tlb2csr_dbra = dbra_ps2;
255 assign tlb2csr_rqid = rqid_ps2;
256 assign tlb2tdb_rqid = rqid_ps2;
257 assign tlb2csr_type = type_ps2;
258
259// other outputs
260 assign tlb2pab_type = type_ps2;
261 assign tlb2ptb_addr = tlb_ptag;
262 assign tlb2rcb_addr = tlb_ptag;
263 assign tlb2vtb_addr = tlb_vtag;
264 assign tlb2vtb_iotsbno = tlb_iotsbno;
265
266// pipeline stage one
267 assign addr_ps1 = vab2tlb_addr;
268 assign dbra_ps1 = vtb2tlb_dbra;
269 assign rqid_ps1 = vab2tlb_rqid;
270 assign type_ps1 = vab2tlb_type;
271 assign iotsbno_ps1 = vab2tlb_iotsbno;
272 assign tsbbpa_ps1 = vab2tlb_tsbbpa;
273 assign sun4v_pgsz_ps1 = vab2tlb_sun4v_pgsz;
274
275// tlb data read address
276 assign ra = tcb2tlb_ras ? tcb2tlb_ra : dbra_ps2[`FILE_DLC_MMU_TTE_CNT_BITS];
277
278// tlb data and physical page number
279 assign data = tlb_data[ra];
280 assign ppn = data[`FIRE_DLC_MMU_TDR_PPN_BITS];
281
282//BP key error, similar to check in tdb
283 assign tlb2tmc_kerr = data[`FIRE_DLC_MMU_TDR_KEYVLD_BITS] &&
284 ~((tlb2tdb_rqid & {{13{1'b1}},data[`FIRE_DLC_MMU_TDR_FNM_BITS]}) ==
285 (data[`FIRE_DLC_MMU_TDR_KEY_BITS] & {{13{1'b1}},data[`FIRE_DLC_MMU_TDR_FNM_BITS]}));
286
287
288// physical tag which is the address of the tsb entry
289// assign new_ptag = tsb_addr(addr_ps2[`FIRE_DLC_MMU_VTD_TAG_BITS], // for FIRE it was [31:16]
290// csr2tlb_tb,
291// csr2tlb_ts,
292// csr2tlb_ps );
293//BP N2 tablewalk address calculated different for sun4u and sun4v, reuse sun4u adder here
294// for sun4v add the iotsb base page and the mode bit
295 assign new_ptag = tsb_addr(addr_ps2[`FIRE_DLC_MMU_VTD_VPN_BITS], // for N2 still output [42:6]
296 vab2tlb_sun4v_pgnmb_ps2, // only for sun4v mode
297 csr2tlb_tb,
298 csr2tlb_ts,
299 csr2tlb_ps,
300 sun4v_mode,
301 tsbbpa_ps2 ); // note sun4v base pa is [38:0] with 39 always 0
302
303
304// virtual tag which is the virtual address with bits masked by page size
305//BP 9-29-05 assign new_vtag[VTM:VTL+3] = addr_ps2[VTM:VTL+3];
306// assign new_vtag[VTL+2:VTL] = csr2tlb_ps ? 3'b000 : addr_ps2[VTL+2:VTL];
307// BP n2 8-16-04if sun4v_mode then page size is already accounted for
308//BP 9-29-05 assign new_vtag[VTL+2:VTL] = (csr2tlb_ps & !sun4v_mode) ? 3'b000 : addr_ps2[VTL+2:VTL];
309
310
311//BP 9-29-05
312always @(sun4v_mode or addr_ps2 or csr2tlb_ps or sun4v_new_vtag ) begin
313
314 if (!sun4v_mode) begin
315 new_vtag[VTM:VTL+3] = addr_ps2[VTM:VTL+3];
316 new_vtag[VTL+2:VTL] = (csr2tlb_ps ) ? 3'b000 : addr_ps2[VTL+2:VTL];
317 end
318 else begin
319 new_vtag[VTM:VTL] = sun4v_new_vtag[VTM:VTL]; //[VTM:VTL]=[39:16]
320 end
321end
322
323//BP 9-29-05 this logic 0's out the lower bits going into the cam, thus as the
324// page size gets larger more bits are 0'ed
325always @(sun4v_pgsz_ps2 or addr_ps2 ) begin
326
327 sun4v_new_vtag[VTM:VTL] = {24{1'b0}};
328
329 case(sun4v_pgsz_ps2)
330 3'b000: sun4v_new_vtag = addr_ps2[39:16]; // 8k pages
331 3'b001: sun4v_new_vtag = {addr_ps2[39:19],{3{1'b0}}}; // 64k pages
332 3'b010: sun4v_new_vtag = addr_ps2[39:16]; // invalid
333 3'b011: sun4v_new_vtag = {addr_ps2[39:25],{9{1'b0}}}; // 4M pages
334 3'b100: sun4v_new_vtag = addr_ps2[39:16]; // invalid
335 3'b101: sun4v_new_vtag = {addr_ps2[39:31],{15{1'b0}}}; // 256M pages
336 3'b110: sun4v_new_vtag = addr_ps2[39:16]; // invalid
337 3'b111: sun4v_new_vtag = addr_ps2[39:16]; // invalid
338 default: sun4v_new_vtag = addr_ps2[39:16];
339 endcase
340end
341
342
343
344// hit address which is the virtual address with bits masked by page size
345//BP 9-29-05 assign vtag_ps1[VTM:VTL+3] = addr_ps1[VTM:VTL+3];
346// assign vtag_ps1[VTL+2:VTL] = csr2tlb_ps ? 3'b000 : addr_ps1[VTL+2:VTL];
347//BP n2 8-16-04 if sun4v_mode then page size is already accounted for
348//BP 9-29-05 assign vtag_ps1[VTL+2:VTL] = (csr2tlb_ps & !sun4v_mode) ? 3'b000 : addr_ps1[VTL+2:VTL];
349
350//BP 9-29-05
351always @(sun4v_mode or addr_ps1 or csr2tlb_ps or sun4v_vtag_ps1 ) begin
352
353 if (!sun4v_mode) begin
354 vtag_ps1[VTM:VTL+3] = addr_ps1[VTM:VTL+3];
355 vtag_ps1[VTL+2:VTL] = (csr2tlb_ps ) ? 3'b000 : addr_ps1[VTL+2:VTL];
356 end
357 else begin
358 vtag_ps1[VTM:VTL] = sun4v_vtag_ps1[VTM:VTL]; //[VTM:VTL]=[39:16]
359 end
360end
361
362//BP 9-29-05 this logic 0's out the lower bits going into the cam, thus as the
363// page size gets larger more bits are 0'ed
364always @(sun4v_pgsz_ps1 or addr_ps1 ) begin
365
366 sun4v_vtag_ps1[VTM:VTL] = {24{1'b0}};
367
368 case(sun4v_pgsz_ps1)
369 3'b000: sun4v_vtag_ps1 = addr_ps1[39:16]; // 8k pages
370 3'b001: sun4v_vtag_ps1 = {addr_ps1[39:19],{3{1'b0}}}; // 64k pages
371 3'b010: sun4v_vtag_ps1 = addr_ps1[39:16]; // invalid
372 3'b011: sun4v_vtag_ps1 = {addr_ps1[39:25],{9{1'b0}}}; // 4M pages
373 3'b100: sun4v_vtag_ps1 = addr_ps1[39:16]; // invalid
374 3'b101: sun4v_vtag_ps1 = {addr_ps1[39:31],{15{1'b0}}}; // 256M pages
375 3'b110: sun4v_vtag_ps1 = addr_ps1[39:16]; // invalid
376 3'b111: sun4v_vtag_ps1 = addr_ps1[39:16]; // invalid
377 default: sun4v_vtag_ps1 = addr_ps1[39:16];
378 endcase
379end
380
381
382
383
384
385// vab address matches the tlb virtual tag
386// assign tlb2tcb_hit = (tlb_vtag == vtag_ps1);
387//BP N2/sun4v requires iotsbno match also
388 assign tlb2tcb_hit = sun4v_mode ? ((tlb_vtag == vtag_ps1) && (tlb_iotsbno == iotsbno_ps1 )) :
389 (tlb_vtag == vtag_ps1);
390
391// selects of the address based upon page size
392 assign sel[1] = tcb2tlb_sel;
393 assign sel[0] = tcb2tlb_sel | csr2tlb_ps;
394
395// pab address is selected between the pipeline address and the tlb data
396//BP 9-29-05 assign tlb2pab_addr[PAM:16] = sel[1] ? {{4{1'b0}},addr_ps2[`N2_PA_MSB:16]} : {{4{1'b0}},ppn[`N2_PA_MSB:16]};
397//BP 9-29-05 assign tlb2pab_addr[15:13] = sel[0] ? addr_ps2[15:13] : ppn[15:13];
398//BP 9-29-05 assign tlb2pab_addr[12:2] = addr_ps2[12:2];
399
400always @(sun4v_mode or addr_ps2 or sel or ppn or sun4v_tlb_addr ) begin
401
402 if (!sun4v_mode) begin
403 tlb2pab_addr[PAM:16] = sel[1] ? {{4{1'b0}},addr_ps2[`N2_PA_MSB:16]} :
404 {{4{1'b0}},ppn[`N2_PA_MSB:16]};
405 tlb2pab_addr[15:13] = (sel[0] ) ? addr_ps2[15:13] : ppn[15:13];
406 tlb2pab_addr[12:2] = addr_ps2[12:2];
407 end
408 else begin
409 tlb2pab_addr[PAM:2] = {{4{1'b0}},sun4v_tlb_addr[25:0],addr_ps2[12:2]};
410 end
411end
412
413//BP 9-29-05 this logic switches between the tdb data and the returning tablewalk data
414// ie. the single entry tlb value
415always @(sun4v_pgsz_ps2 or addr_ps2 or ppn or sel ) begin
416
417 sun4v_tlb_addr[25:0] = {26{1'b0}}; // PAM=42,`N2_PA_MSB=38
418
419 case(sun4v_pgsz_ps2)
420 3'b000: if (sel[1]) sun4v_tlb_addr = addr_ps2[`N2_PA_MSB:13]; // 8k pages
421 else sun4v_tlb_addr = ppn[`N2_PA_MSB:13];
422 3'b001: if (sel[1]) sun4v_tlb_addr = addr_ps2[`N2_PA_MSB:13]; // 64k pages
423 else sun4v_tlb_addr = {ppn[`N2_PA_MSB:16],addr_ps2[15:13]};
424 3'b010: sun4v_tlb_addr = {26{1'b0}}; // invalid
425 3'b011: if (sel[1]) sun4v_tlb_addr = addr_ps2[`N2_PA_MSB:13]; // 4M pages
426 else sun4v_tlb_addr = {ppn[`N2_PA_MSB:22],addr_ps2[21:13]};
427 3'b100: sun4v_tlb_addr = {26{1'b0}}; // invalid
428 3'b101: if (sel[1]) sun4v_tlb_addr = addr_ps2[`N2_PA_MSB:13]; // 256M pages
429 else sun4v_tlb_addr = {ppn[`N2_PA_MSB:28],addr_ps2[27:13]};
430 3'b110: sun4v_tlb_addr = {26{1'b0}}; // invalid
431 3'b111: sun4v_tlb_addr = {26{1'b0}}; // invalid
432 default: sun4v_tlb_addr = {26{1'b0}};
433 endcase
434end
435
436
437
438//BP 9-29-05
439 assign tlb2pab_sun4v_pgsz = sun4v_pgsz_ps2;
440
441// wrt and vld are always set when selecting pipeline address above otherwise
442// they come from the tlb data
443 wire tlb2pab_wrt = data[`FIRE_DLC_MMU_TDR_WRT_BITS] | tcb2tlb_sel;
444 wire tlb2pab_vld = data[`FIRE_DLC_MMU_TDR_VLD_BITS] | tcb2tlb_sel;
445
446// tdb data parity
447// assign dpar[3] = ~^data[31:24];
448// assign dpar[2] = ~^data[23:16];
449// assign dpar[1] = ~^data[15:8];
450// assign dpar[0] = ~^data[7:0];
451
452// tdb data includes parity bits
453// assign tlb2tdb_data[`FIRE_DLC_MMU_TDR_PAR_LSB+3] = dpar[3];
454// assign tlb2tdb_data[`FIRE_DLC_MMU_TDR_PAR_LSB+2] = dpar[2];
455// assign tlb2tdb_data[`FIRE_DLC_MMU_TDR_PAR_LSB+1] = dpar[1];
456// assign tlb2tdb_data[`FIRE_DLC_MMU_TDR_PAR_LSB] = dpar[0];
457 assign tlb2tdb_data[`FIRE_DLC_MMU_TDR_MINUS_PAR_BITS] = data;
458
459// ----------------------------------------------------------------------------
460// Sequential
461// ----------------------------------------------------------------------------
462 always @ (posedge clk)
463 if(~rst_l) begin
464 addr_ps2 <= {62{1'b0}};
465 dbra_ps2 <= {`FIRE_DLC_MMU_TAG_PTR_SIZE + 3{1'b0}};
466 rqid_ps2 <= {16{1'b0}};
467 type_ps2 <= {7{1'b0}};
468 iotsbno_ps2 <= {`FIRE_DLC_MMU_VTD_IOTSBNO_WDTH{1'b0}};
469 tsbbpa_ps2 <= {26{1'b0}};
470 sun4v_pgsz_ps2 <= {3{1'b0}};
471 vab2tlb_sun4v_pgnmb_ps2 <= {28{1'b0}};
472 tlb2pab_byp_ps2 <= {{1'b0}};
473 end
474 else begin
475 if (!tcb2tlb_hld) begin
476 addr_ps2 <= addr_ps1;
477 dbra_ps2 <= dbra_ps1;
478 rqid_ps2 <= rqid_ps1;
479 type_ps2 <= type_ps1;
480 iotsbno_ps2 <= iotsbno_ps1;
481 tsbbpa_ps2 <= tsbbpa_ps1;
482 sun4v_pgsz_ps2 <= sun4v_pgsz_ps1;
483 vab2tlb_sun4v_pgnmb_ps2 <= vab2tlb_sun4v_pgnmb;
484 tlb2pab_byp_ps2 <= vab2tlb_sun4v_byp_ps1;
485 end
486 end
487
488 always @ (posedge clk)
489 if(~rst_l) begin
490 tlb_ptag <= {33{1'b0}};
491 tlb_vtag <= {`FIRE_DLC_MMU_VTD_VPN_WDTH{1'b0}};
492 tlb_iotsbno <= {5{1'b0}};
493 end
494 else begin
495 if (tcb2tlb_tld) begin
496 tlb_ptag <= new_ptag;
497 tlb_vtag <= new_vtag;
498 tlb_iotsbno <= iotsbno_ps2;
499 end
500 end
501
502 always @ (posedge clk)
503 if(~rst_l) begin
504 tlb_data[0] <= {`FIRE_DLC_MMU_TDR_KEY_MSB+1{1'b0}};
505 tlb_data[1] <= {`FIRE_DLC_MMU_TDR_KEY_MSB+1{1'b0}};
506 tlb_data[2] <= {`FIRE_DLC_MMU_TDR_KEY_MSB+1{1'b0}};
507 tlb_data[3] <= {`FIRE_DLC_MMU_TDR_KEY_MSB+1{1'b0}};
508 tlb_data[4] <= {`FIRE_DLC_MMU_TDR_KEY_MSB+1{1'b0}};
509 tlb_data[5] <= {`FIRE_DLC_MMU_TDR_KEY_MSB+1{1'b0}};
510 tlb_data[6] <= {`FIRE_DLC_MMU_TDR_KEY_MSB+1{1'b0}};
511 tlb_data[7] <= {`FIRE_DLC_MMU_TDR_KEY_MSB+1{1'b0}};
512 end
513 else begin
514 if (tcb2tlb_dld) begin
515 tlb_data[0] <= tlb_data[2];
516 tlb_data[1] <= tlb_data[3];
517 tlb_data[2] <= tlb_data[4];
518 tlb_data[3] <= tlb_data[5];
519 tlb_data[4] <= tlb_data[6];
520 tlb_data[5] <= tlb_data[7];
521 tlb_data[6] <= rcb2tlb_dlo;
522 tlb_data[7] <= rcb2tlb_dhi;
523 end
524 end
525
526endmodule // dmu_mmu_tlb