Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / dmu / rtl / dmu_mmu_vab.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: dmu_mmu_vab.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_vab
36 (
37 clk, // clock
38 rst_l, // synchronous reset
39 csr2vab_ps, // csr page size
40 csr2vab_ts, // csr table size
41 tcb2vab_hld, // tcb hold
42 vaq2vab_rcd, // vaq virtual address record
43 vaq2vab_iotsbno, // vaq iotsb number for sun4v
44 vaq2vab_tsbbpa, // vaq iotsb base pa for sun4v table walks
45 srq2vab_np, // iotsb number of pages from srq
46 srq2vab_adva, // adjusted va for sun4v mode
47 srq2vab_sun4v_pgsz, // page size for sun4v mode
48 srq2vab_sun4v_byp_ps0, // true if sun4v mode and bypass
49 vab2tcb_4vor, // sun4v out of range error
50 vab2tcb_s4uf, // sun4v underflow
51 vab2tcb_err, // tcb error
52 vab2tcb_vld, // tcb valid
53 vab2tcb_sun4v_va_oor, // sun4v va oor
54 vab2tlb_addr, // tlb address
55 vab2tlb_rqid, // tlb requester id
56 vab2tlb_type, // tlb type
57 vab2tlb_iotsbno, // tlb iotsb for sun4v mode
58 vab2tlb_tsbbpa, // tlb iotsb base pa for sun4v mode tablewalk
59 vab2tlb_sun4v_pgnmb, // sun4v page number for tablewalks
60 vab2tlb_sun4v_pgsz, // sun4v page size to adjust new tag write into vtb
61 vab2vtb_addr, // vtb address
62 vab2vtb_dbra, // vtb data buffer read address
63 vab2vtb_iotsbno, // vtb iotsb number for sun4v
64 sun4v_mode, // 1 if in sun4v mode for io address translations
65 vab2tlb_sun4v_byp_ps1 // use in pab to check tdb parity errors
66 );
67
68// ----------------------------------------------------------------------------
69// Parameters
70// ----------------------------------------------------------------------------
71 parameter VTL = `FIRE_DLC_MMU_VTD_VPN_LSB, // virtual tag LSB
72 VTM = `FIRE_DLC_MMU_VTD_VPN_MSB; // virtual tag MSB
73
74 parameter MEM_RDT = 7'b0000000,
75 MEM_RDB = 7'b0100000,
76 MEM_WRT = 7'b1000000,
77 MEM_WRB = 7'b1100000,
78 MSG_WRT = 7'b1010000,
79 MSG_WRB = 7'b1110000,
80 MSI_WRT = 7'b1011000,
81 MSI_WRB = 7'b1111000;
82
83// ----------------------------------------------------------------------------
84// Ports
85// ----------------------------------------------------------------------------
86 input clk;
87 input rst_l;
88
89 input csr2vab_ps;
90 input [`FIRE_DLC_MMU_CSR_TS_BITS] csr2vab_ts;
91 input tcb2vab_hld;
92 input [`FIRE_DLC_MMU_VAR_BITS] vaq2vab_rcd;
93 input [`FIRE_DLC_MMU_VAR_IOTSB_BITS] vaq2vab_iotsbno;
94 input [`FIRE_DLC_MMU_IOTSB_BSPA_BITS] vaq2vab_tsbbpa;
95 input [3:0] srq2vab_np;
96 input [27:0] srq2vab_adva;
97 input [2:0] srq2vab_sun4v_pgsz;
98 input srq2vab_sun4v_byp_ps0;
99 input sun4v_mode;
100
101 output [`FIRE_DLC_MMU_VAB_ERR_BITS] vab2tcb_err;
102 output [`FIRE_DLC_MMU_VAB_VLD_BITS] vab2tcb_vld;
103 output vab2tcb_sun4v_va_oor;
104 output vab2tcb_4vor;
105 output vab2tcb_s4uf;
106 output [`FIRE_DLC_MMU_VA_ADDR_BITS] vab2tlb_addr;
107 output [`FIRE_DLC_MMU_VA_RQID_BITS] vab2tlb_rqid;
108 output [`FIRE_DLC_MMU_VA_TYPE_BITS] vab2tlb_type;
109 output [`FIRE_DLC_MMU_VAR_IOTSB_BITS] vab2tlb_iotsbno;
110 output [`FIRE_DLC_MMU_IOTSB_BSPA_BITS] vab2tlb_tsbbpa;
111 output [27:0] vab2tlb_sun4v_pgnmb;
112 output [2:0] vab2tlb_sun4v_pgsz;
113 output [`FIRE_DLC_MMU_VTD_VPN_BITS] vab2vtb_addr;
114 output [`FILE_DLC_MMU_TTE_CNT_BITS] vab2vtb_dbra;
115 output [`FIRE_DLC_MMU_VAR_IOTSB_BITS] vab2vtb_iotsbno;
116 output vab2tlb_sun4v_byp_ps1;
117
118// ----------------------------------------------------------------------------
119// Variables
120// ----------------------------------------------------------------------------
121 wire [`FIRE_DLC_MMU_VA_ADDR_BITS] vab2tlb_addr, addr_ps0;
122 wire [`FIRE_DLC_MMU_VA_RQID_BITS] vab2tlb_rqid, rqid_ps0;
123 wire [`FIRE_DLC_MMU_VA_TYPE_BITS] vab2tlb_type, type_ps0;
124 wire [`FIRE_DLC_MMU_VAR_IOTSB_BITS] vab2tlb_iotsbno, iotsbno_ps0;
125 wire [`FIRE_DLC_MMU_IOTSB_BSPA_BITS] tsbbpa_ps0;
126 reg [`FIRE_DLC_MMU_VTD_VPN_BITS] vab2vtb_addr;
127 reg [`FIRE_DLC_MMU_VTD_VPN_BITS] sun4v_adj_va;
128 reg [`FILE_DLC_MMU_TTE_CNT_BITS] vab2vtb_dbra,sun4v_adj_dbra;
129 wire [`FIRE_DLC_MMU_CSR_TS_BITS] size;
130 wire [`FIRE_DLC_MMU_VAB_ERR_BITS] vab2tcb_err;
131 wire [`FIRE_DLC_MMU_VAB_VLD_BITS] vab2tcb_vld;
132 wire sun4v_mode;
133 reg [`FIRE_DLC_MMU_VAR_IOTSB_BITS] iotsbno_ps1;
134 reg [`FIRE_DLC_MMU_IOTSB_BSPA_BITS] tsbbpa_ps1;
135 reg [`FIRE_DLC_MMU_VA_ADDR_BITS] addr_ps1;
136 reg [`FIRE_DLC_MMU_VA_RQID_BITS] rqid_ps1;
137 reg [`FIRE_DLC_MMU_VA_TYPE_BITS] type_ps1;
138 reg [`FIRE_DLC_MMU_VAB_ERR_BITS] aok;
139 reg [`FIRE_DLC_MMU_VAB_VLD_BITS] vld;
140 reg [3:0] np_ps1;
141 reg [27:0] adva_ps1;
142 reg [2:0] sun4v_pgsz_ps1;
143 reg sun4v_byp_ps1;
144
145// ----------------------------------------------------------------------------
146// Combinational
147// ----------------------------------------------------------------------------
148
149// tlb address, requester id, and type
150 assign vab2tlb_addr = addr_ps1;
151 assign vab2tlb_rqid = rqid_ps1;
152 assign vab2tlb_type = type_ps1;
153 assign vab2tlb_iotsbno = iotsbno_ps1;
154 assign vab2tlb_tsbbpa = tsbbpa_ps1;
155 assign vab2tlb_sun4v_pgnmb = adva_ps1; // this is adjusted sun4v page number
156 assign vab2tlb_sun4v_pgsz = sun4v_pgsz_ps1;
157 assign vab2tlb_sun4v_byp_ps1 = sun4v_byp_ps1;
158
159// virtual address record parsing
160 assign addr_ps0 = vaq2vab_rcd[`FIRE_DLC_MMU_VAR_ADDR_BITS];
161 assign rqid_ps0 = vaq2vab_rcd[`FIRE_DLC_MMU_VAR_RQID_BITS];
162 assign type_ps0 = vaq2vab_rcd[`FIRE_DLC_MMU_VAR_TYPE_BITS];
163 assign iotsbno_ps0 = vaq2vab_iotsbno[`FIRE_DLC_MMU_VAR_IOTSB_BITS];
164 assign tsbbpa_ps0 = vaq2vab_tsbbpa[`FIRE_DLC_MMU_IOTSB_BSPA_BITS];
165
166// vtb address is the virtual address with bits masked by the page size
167// assign vab2vtb_addr[VTM:VTL+3] = addr_ps0[VTM:VTL+3];
168// assign vab2vtb_addr[VTL+2:VTL] = (csr2vab_ps & !sun4v_mode) ? 3'b000 : addr_ps0[VTL+2:VTL];
169
170always @(sun4v_mode or addr_ps0 or csr2vab_ps or sun4v_adj_va ) begin
171
172 if (!sun4v_mode) begin
173 vab2vtb_addr[VTM:VTL+3] = addr_ps0[VTM:VTL+3];
174 vab2vtb_addr[VTL+2:VTL] = (csr2vab_ps ) ? 3'b000 : addr_ps0[VTL+2:VTL];
175 end
176 else begin
177 vab2vtb_addr[VTM:VTL] = sun4v_adj_va[VTM:VTL];
178 end
179end
180
181//BP 9-29-05 this logic 0's out the lower bits going into the cam, thus as the
182// page size gets larger more bits are 0'ed, also need to modify tlb tag writes
183always @(srq2vab_sun4v_pgsz or addr_ps0 ) begin
184
185 sun4v_adj_va[VTM:VTL] = {24{1'b0}};
186
187 case(srq2vab_sun4v_pgsz)
188 3'b000: sun4v_adj_va = addr_ps0[39:16]; // 8k pages
189 3'b001: sun4v_adj_va = {addr_ps0[39:19],{3{1'b0}}}; // 64k pages
190 3'b010: sun4v_adj_va = addr_ps0[39:16]; // invalid
191 3'b011: sun4v_adj_va = {addr_ps0[39:25],{9{1'b0}}}; // 4M pages
192 3'b100: sun4v_adj_va = addr_ps0[39:16]; // invalid
193 3'b101: sun4v_adj_va = {addr_ps0[39:31],{15{1'b0}}}; // 256M pages
194 3'b110: sun4v_adj_va = addr_ps0[39:16]; // invalid
195 3'b111: sun4v_adj_va = addr_ps0[39:16]; // invalid
196 default: sun4v_adj_va = addr_ps0[39:16];
197 endcase
198end
199
200
201 assign vab2vtb_iotsbno = iotsbno_ps0;
202
203// vtb data buffer read address of the entry within a cacheline
204// assign vab2vtb_dbra = csr2vab_ps ? addr_ps1[VTL+2:VTL] : addr_ps1[VTL-1:VTL-3];
205//BP N2 if snu4v mode always use adr[15:13] since the page size is taken into
206// account by the iotsb ram lookups.
207// assign vab2vtb_dbra = (csr2vab_ps & !sun4v_mode) ? addr_ps1[VTL+2:VTL] : addr_ps1[VTL-1:VTL-3];
208
209always @(sun4v_mode or addr_ps1 or csr2vab_ps or sun4v_adj_dbra) begin
210
211 if (!sun4v_mode) begin
212 vab2vtb_dbra[2:0] = (csr2vab_ps ) ? addr_ps1[VTL+2:VTL] : addr_ps1[VTL-1:VTL-3];
213 end
214 else begin
215 vab2vtb_dbra[2:0] = sun4v_adj_dbra[2:0];
216 end
217end
218
219always @(sun4v_pgsz_ps1 or addr_ps1 ) begin
220
221 sun4v_adj_dbra[2:0] = {3{1'b0}};
222
223 case(sun4v_pgsz_ps1)
224 3'b000: sun4v_adj_dbra = addr_ps1[15:13]; // 8k pages
225 3'b001: sun4v_adj_dbra = addr_ps1[18:16]; // 64k pages
226 3'b010: sun4v_adj_dbra = {3{1'b0}}; // invalid
227 3'b011: sun4v_adj_dbra = addr_ps1[24:22]; // 4M pages
228 3'b100: sun4v_adj_dbra = {3{1'b0}}; // invalid
229 3'b101: sun4v_adj_dbra = addr_ps1[30:28]; // 256M pages
230 3'b110: sun4v_adj_dbra = {3{1'b0}}; // invalid
231 3'b111: sun4v_adj_dbra = {3{1'b0}}; // invalid
232 default: sun4v_adj_dbra = {3{1'b0}};
233 endcase
234end
235
236
237
238
239
240
241// size is the tsb size adjusted by the page size
242 assign size = csr2vab_ps ? csr2vab_ts + 4'h3 : csr2vab_ts;
243
244// aok[1] is address ok for translation mode, aok[0] is for bypass mode
245 always @ (addr_ps1 or size) begin
246 case (size)
247 4'h0 : aok[1] = &(addr_ps1[31:23]);
248 4'h1 : aok[1] = &(addr_ps1[31:24]);
249 4'h2 : aok[1] = &(addr_ps1[31:25]);
250 4'h3 : aok[1] = &(addr_ps1[31:26]);
251 4'h4 : aok[1] = &(addr_ps1[31:27]);
252 4'h5 : aok[1] = &(addr_ps1[31:28]);
253 4'h6 : aok[1] = &(addr_ps1[31:29]);
254 4'h7 : aok[1] = &(addr_ps1[31:30]);
255 4'h8 : aok[1] = addr_ps1[31];
256 4'h9 : aok[1] = 1'b1;
257 default : aok[1] = 1'b0;
258 endcase
259// aok[0] = (addr_ps1[63:42] == 22'h3fff00); //BP old value for fire
260 aok[0] = (addr_ps1[63:39] == 25'h1fff800);
261 end
262
263// iotsb/sun4v out of range calculation
264// now check for overflow,
265reg [26:0] number_of_pages;
266reg sun4v_or; // sun4v our of range
267always @( np_ps1 )begin
268
269 number_of_pages = 27'b0;
270
271 case (np_ps1)
272 4'b0000: number_of_pages = 27'b000_0000_0000_0000_0100_0000_0000 ; // 1k pages
273 4'b0001: number_of_pages = 27'b000_0000_0000_0000_1000_0000_0000 ; // 2k pages
274 4'b0010: number_of_pages = 27'b000_0000_0000_0001_0000_0000_0000 ; // 4k pages
275 4'b0011: number_of_pages = 27'b000_0000_0000_0010_0000_0000_0000 ; // 8k pages
276 4'b0100: number_of_pages = 27'b000_0000_0000_0100_0000_0000_0000 ; // 16k pages
277 4'b0101: number_of_pages = 27'b000_0000_0000_1000_0000_0000_0000 ; // 32k pages
278 4'b0110: number_of_pages = 27'b000_0000_0001_0000_0000_0000_0000 ; // 64k pages
279 4'b0111: number_of_pages = 27'b000_0000_0010_0000_0000_0000_0000 ; // 128k pages
280 4'b1000: number_of_pages = 27'b000_0000_0100_0000_0000_0000_0000 ; //256k pages
281 4'b1001: number_of_pages = 27'b000_0000_1000_0000_0000_0000_0000 ; //512k pages
282 4'b1010: number_of_pages = 27'b000_0001_0000_0000_0000_0000_0000 ; //1024k pages
283 4'b1011: number_of_pages = 27'b000_0010_0000_0000_0000_0000_0000 ; //2048k pages
284 4'b1100: number_of_pages = 27'b000_0100_0000_0000_0000_0000_0000 ; //4096k pages
285 4'b1101: number_of_pages = 27'b000_1000_0000_0000_0000_0000_0000 ; //8192k pages
286 4'b1110: number_of_pages = 27'b001_0000_0000_0000_0000_0000_0000 ; //16384k pages
287 4'b1111: number_of_pages = 27'b010_0000_0000_0000_0000_0000_0000 ; //32768k pages
288// default: number_of_pages = 27'bx;
289 endcase
290end
291
292always @(number_of_pages or adva_ps1 )begin
293 if ((adva_ps1[26:0] < number_of_pages[26:0]) )begin
294 sun4v_or = 1'b0;
295 end
296 else sun4v_or = 1'b1;
297 end
298//BP 9-05-05 these are gated with translate mode in dmu_mmu_tcb_tmc.v ie. tmv
299// the translate mode is decoded below and sent to dmu_mmu_tcb_tmc.v
300assign vab2tcb_4vor = sun4v_or & sun4v_mode; // 1 if sun4v out of range
301assign vab2tcb_s4uf = adva_ps1[27] & sun4v_mode; // if 1 there was an underflow
302
303
304// vld[1] is a valid translation mode type, vld[0] is for bypass mode
305 always @ (type_ps0 or sun4v_mode or srq2vab_sun4v_byp_ps0) begin
306 case ({srq2vab_sun4v_byp_ps0,sun4v_mode,type_ps0})
307 {1'b0,1'b0,MEM_RDT} : vld = 3'b010; // Memory read (translation)
308 {1'b0,1'b0,MEM_RDB} : vld = 3'b001; // Memory read (bypass)
309 {1'b0,1'b0,MEM_WRT} : vld = 3'b010; // Memory write (translation)
310 {1'b0,1'b0,MEM_WRB} : vld = 3'b001; // Memory write (bypass)
311 {1'b0,1'b0,MSG_WRT} : vld = 3'b010; // Msg EQ write (translation)
312 {1'b0,1'b0,MSG_WRB} : vld = 3'b001; // Msg EQ write (bypass)
313 {1'b0,1'b0,MSI_WRT} : vld = 3'b010; // MSI EQ write (translation)
314 {1'b0,1'b0,MSI_WRB} : vld = 3'b001; // MSI EQ write (bypass)
315
316 {1'b0,1'b1,MEM_RDT} : vld = 3'b010; // Memory read (translation) // 32 bit adr
317 {1'b0,1'b1,MEM_RDB} : vld = 3'b010; // Memory read (translation) // 64 bit adr
318 {1'b0,1'b1,MEM_WRT} : vld = 3'b010; // Memory write (translation) // 32 bit adr
319 {1'b0,1'b1,MEM_WRB} : vld = 3'b010; // Memory write (translation) // 64 bit adr
320
321 {1'b1,1'b1,MEM_RDB} : vld = 3'b001; // Memory read (bypass) // 64 bit adr
322 {1'b1,1'b1,MEM_WRB} : vld = 3'b001; // Memory write (bypass) // 64 bit adr
323
324 {1'b0,1'b1,MSG_WRT} : vld = 3'b010; // Msg EQ write (translation)
325 {1'b0,1'b1,MSG_WRB} : vld = 3'b010; // Msg EQ write (translation) // 64 bit adr
326 {1'b0,1'b1,MSI_WRT} : vld = 3'b010; // MSI EQ write (translation)
327 {1'b0,1'b1,MSI_WRB} : vld = 3'b010; // MSI EQ write (translation) // 64 bit adr
328
329 {1'b1,1'b1,MSG_WRT} : vld = 3'b101; // Msg EQ write (bypass)
330 {1'b1,1'b1,MSI_WRT} : vld = 3'b101; // MSI EQ write (bypass)
331 {1'b1,1'b1,MSG_WRB} : vld = 3'b101; // Msg EQ write (bypass)
332 {1'b1,1'b1,MSI_WRB} : vld = 3'b101; // MSI EQ write (bypass)
333 default : vld = 3'b000;
334 endcase
335 end
336
337// tcb error and valid
338// assign vab2tcb_err = ~aok;
339 assign vab2tcb_err = {(~(aok[1] & ~sun4v_mode)), ~aok[0]};
340 assign vab2tcb_vld = vld;
341// BP 11-30-05 note this is a ps0 stage
342assign vab2tcb_sun4v_va_oor = sun4v_mode & ~(addr_ps0[62:40] == 23'h000000) &
343 ~srq2vab_sun4v_byp_ps0 ; // if 1 adr 62:40 not eq 0 for translating
344 // transactions
345
346// ----------------------------------------------------------------------------
347// Sequential
348// ----------------------------------------------------------------------------
349 always @ (posedge clk)
350 if(~rst_l) begin
351 addr_ps1 <= {62{1'b0}};
352 rqid_ps1 <= {16{1'b0}};
353 type_ps1 <= {7{1'b0}};
354 iotsbno_ps1 <= {`FIRE_DLC_MMU_VTD_IOTSBNO_WDTH{1'b0}};
355 tsbbpa_ps1 <= {26{1'b0}};
356 np_ps1 <= {4{1'b0}};
357 adva_ps1 <= {28{1'b0}};
358 sun4v_pgsz_ps1 <= {3{1'b0}};
359 sun4v_byp_ps1 <= {1'b0};
360 end
361 else begin
362 if (!tcb2vab_hld) begin
363 addr_ps1 <= addr_ps0;
364 rqid_ps1 <= rqid_ps0;
365 type_ps1 <= type_ps0;
366 iotsbno_ps1 <= iotsbno_ps0;
367 tsbbpa_ps1 <= tsbbpa_ps0;
368 np_ps1 <= srq2vab_np;
369 adva_ps1 <= srq2vab_adva;
370 sun4v_pgsz_ps1 <= srq2vab_sun4v_pgsz;
371 sun4v_byp_ps1 <= srq2vab_sun4v_byp_ps0;
372 end
373 end
374
375endmodule