Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / dmu / rtl / dmu_mmu_vtb.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: dmu_mmu_vtb.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_vtb
36 (
37 l2clk, // clock for rams
38 clk, // clock
39 rst_l, // reset
40 scan_in,
41 tcu_array_bypass,
42 tcu_se_scancollar_in,
43 tcu_scan_en,
44 tcu_array_wr_inhibit,
45 tcu_pce_ov,
46 tcu_aclk,
47 tcu_bclk,
48 scan_out,
49
50 csr2vtb_ra, // csr read address
51 csr2vtb_wa, // csr write address
52 csr2vtb_wd, // csr write data
53 csr2vtb_we, // csr write enable
54 ptb2vtb_inv, // ptb invalidate
55 tcb2vtb_hld, // tcb hold
56 tcb2vtb_sel, // tcb select
57 tcb2vtb_tmv, // tcb translation mode valid
58 tcb2vtb_vld, // tcb valid
59 tcb2vtb_wa, // tcb write address
60 tcb2vtb_we, // tcb write enable
61 tlb2vtb_addr, // tlb virtual tag
62 tlb2vtb_iotsbno, // tlb virtual iotsb for sun4v mode
63 vab2vtb_addr, // vab address
64 vab2vtb_dbra, // vab read address
65 vab2vtb_iotsbno, // vab iotsb number for sun4v mode
66 sun4v_mode, // 1 if in suv4v mode
67 vtb2crb_hit, // crb hit
68 vtb2crb_inv, // crb tag invalidate
69 vtb2crb_tag, // crb invalidate tag
70 vtb2crb_vld, // crb valid
71 vtb2csr_prf, // vtb performance event
72 vtb2csr_rd, // csr read data
73 vtb2tcb_hit, // tcb virtual tag hit
74 vtb2tdb_dbra, // tdb data buffer read address
75 vtb2tlb_dbra, // tlb data buffer read address
76
77 dmu_cb0_run,
78 dmu_cb0_addr,
79 dmu_cb0_wdata_key,
80 dmu_cb0_mmu_vtb_wr_en,
81 dmu_cb0_mmu_vtb_rd_en,
82 dmu_cb0_mmu_vtb_lkup_en,
83 dmu_cb0_hld,
84 mmu_vtb_hit,
85 vtb_dout_4msb
86
87 );
88
89// ----------------------------------------------------------------------------
90// Ports
91// ----------------------------------------------------------------------------
92 input l2clk;
93 input clk;
94 input rst_l;
95 input scan_in;
96 input tcu_array_bypass;
97 input tcu_se_scancollar_in;
98 input tcu_scan_en;
99 input tcu_array_wr_inhibit;
100 input tcu_pce_ov;
101 input tcu_aclk;
102 input tcu_bclk;
103 output scan_out;
104
105 input [`FIRE_DLC_MMU_TAG_PTR_BITS] csr2vtb_ra;
106 input [`FIRE_DLC_MMU_TAG_PTR_BITS] csr2vtb_wa;
107 input [`FIRE_DLC_MMU_VTR_BITS] csr2vtb_wd;
108 input csr2vtb_we;
109 input [`FIRE_DLC_MMU_TAG_BITS] ptb2vtb_inv;
110 input tcb2vtb_hld;
111 input tcb2vtb_sel;
112 input tcb2vtb_tmv;
113 input tcb2vtb_vld;
114 input [`FIRE_DLC_MMU_TAG_PTR_BITS] tcb2vtb_wa;
115 input tcb2vtb_we;
116 input [`FIRE_DLC_MMU_VTD_VPN_BITS] tlb2vtb_addr;
117 input [`FIRE_DLC_MMU_VAR_IOTSB_BITS] tlb2vtb_iotsbno;
118 input [`FIRE_DLC_MMU_VTD_VPN_BITS] vab2vtb_addr;
119 input [`FILE_DLC_MMU_TTE_CNT_BITS] vab2vtb_dbra;
120 input [`FIRE_DLC_MMU_VAR_IOTSB_BITS] vab2vtb_iotsbno;
121 input sun4v_mode;
122
123 output [`FIRE_DLC_MMU_TAG_BITS] vtb2crb_hit;
124 output vtb2crb_inv;
125 output [`FIRE_DLC_MMU_TAG_PTR_BITS] vtb2crb_tag;
126 output [`FIRE_DLC_MMU_TAG_BITS] vtb2crb_vld;
127 output vtb2csr_prf;
128 output [`FIRE_DLC_MMU_VTR_BITS] vtb2csr_rd;
129 output vtb2tcb_hit;
130 output [`FIRE_DLC_MMU_TDB_PTR_BITS] vtb2tdb_dbra;
131 output [`FIRE_DLC_MMU_TDB_PTR_BITS] vtb2tlb_dbra;
132
133 input dmu_cb0_run;
134 input [5:0] dmu_cb0_addr;
135 input [32:0] dmu_cb0_wdata_key;
136 input dmu_cb0_mmu_vtb_wr_en;
137 input dmu_cb0_mmu_vtb_rd_en;
138 input dmu_cb0_mmu_vtb_lkup_en;
139 input dmu_cb0_hld;
140 output [63:0] mmu_vtb_hit;
141 output [3:0] vtb_dout_4msb;
142
143// ----------------------------------------------------------------------------
144// Variables
145// ----------------------------------------------------------------------------
146 wire [`FIRE_DLC_MMU_VTR_BITS] vtb2csr_rd;
147 wire [`FIRE_DLC_MMU_TAG_PTR_BITS] vtb2crb_tag, hit_tag;
148 wire [`FIRE_DLC_MMU_TAG_BITS] vtb2crb_hit, vtb2crb_vld, hit_vld;
149 wire [`FIRE_DLC_MMU_TDB_PTR_BITS] vtb2tdb_dbra, vtb2tlb_dbra, dbra_ps1;
150 wire [`FIRE_DLC_MMU_VTD_VPN_BITS] new_tag;
151 wire [`FIRE_DLC_MMU_TAG_PTR_BITS] new_wa;
152 wire [`FIRE_DLC_MMU_TAG_BITS] nxt_vld, clr_vld;
153 wire [`FIRE_DLC_MMU_VAR_IOTSB_BITS] new_tag_iotsbno;
154 wire sun4v_mode;
155
156// reg [`FIRE_DLC_MMU_VTD_VPN_BITS] tag [`FIRE_DLC_MMU_TAG_MEM_BITS];
157 wire [`FIRE_DLC_MMU_TAG_BITS] hit_ps1,hit_out;
158 reg [`FIRE_DLC_MMU_TAG_BITS] tag_ld, tld;
159 reg [`FIRE_DLC_MMU_TAG_BITS] vld, set_vld, clr_vct;
160
161// integer i;
162
163// ----------------------------------------------------------------------------
164// Zero In Checkers
165// ----------------------------------------------------------------------------
166
167 // 0in bits_on -var {csr2vtb_we, tcb2vtb_we} -max 1
168 // 0in bits_on -var hit_vld -max 1
169 // 0in decoder -in new_wa -out set_vld -active set_bit
170 // 0in decoder -in new_wa -out clr_vct -active clr_bit
171 // 0in decoder -in new_wa -out tag_ld -active new_we
172 // 0in encoder -in hit_vld -out hit_tag -zero off
173 // 0in encoder -in ptb2vtb_inv -out vtb2crb_tag -zero off -active ~sun4v_mode
174
175// ----------------------------------------------------------------------------
176// Functions
177// ----------------------------------------------------------------------------
178 function [`FIRE_DLC_MMU_TAG_PTR_BITS] tag_enc;
179 input [`FIRE_DLC_MMU_TAG_BITS] di;
180
181 reg [`FIRE_DLC_MMU_TAG_PTR_BITS] do;
182 reg [1+`FIRE_DLC_MMU_TAG_PTR_BITS] i;
183
184 parameter MAX = { 1'b0, { `FIRE_DLC_MMU_TAG_PTR_SIZE {1'b1} } };
185
186 begin
187 do = 0;
188 for (i = 0; i <= MAX; i = i + 1) begin
189 if (di[i[`FIRE_DLC_MMU_TAG_PTR_BITS]])
190 do = i[`FIRE_DLC_MMU_TAG_PTR_BITS];
191 end
192 tag_enc = do;
193 end
194 endfunction // tag_enc
195
196// ----------------------------------------------------------------------------
197// Combinational
198// ----------------------------------------------------------------------------
199// new tag address, write address, and write enable
200 assign new_tag = tcb2vtb_sel ? tlb2vtb_addr : csr2vtb_wd
201 [`FIRE_DLC_MMU_VTR_VPN_BITS];
202 assign new_tag_iotsbno = sun4v_mode ? (tcb2vtb_sel ? tlb2vtb_iotsbno : csr2vtb_wd[`FIRE_DLC_MMU_VTR_IOTSBNO_BITS]) : 5'b0;
203
204 assign new_wa = tcb2vtb_sel ? tcb2vtb_wa : csr2vtb_wa;
205
206 wire new_we = tcb2vtb_we | csr2vtb_we;
207
208// csr valid set and clear
209 wire csr_set = csr2vtb_we & csr2vtb_wd[`FIRE_DLC_MMU_VTR_VLD_BITS];
210 wire csr_clr = csr2vtb_we & ~csr2vtb_wd[`FIRE_DLC_MMU_VTR_VLD_BITS];
211
212// tcb valid set and clear
213 wire tcb_set = tcb2vtb_we & tcb2vtb_vld;
214 wire tcb_clr = tcb2vtb_we & ~tcb2vtb_vld;
215
216// valid bit set and clear
217 wire set_bit = tcb_set | csr_set;
218 wire clr_bit = tcb_clr | csr_clr;
219
220// valid bit set for the valid bit vector
221 always @ (new_wa or set_bit) begin
222 set_vld = 0;
223 set_vld[new_wa] = set_bit;
224 end
225
226// valid bit clear for the valid bit vector
227 always @ (new_wa or clr_bit) begin
228 clr_vct = 0;
229 clr_vct[new_wa] = clr_bit;
230 end
231
232 assign clr_vld = clr_vct | ptb2vtb_inv;
233
234// next valid bit vector
235 assign nxt_vld = (vld & ~clr_vld) | set_vld;
236
237// tag write enables
238 always @ (new_we or new_wa or rst_l) begin
239 tag_ld = { `FIRE_DLC_MMU_TAG_SIZE { ~rst_l } };
240 tag_ld[new_wa] = new_we | ~rst_l;
241 end
242
243// hit valid and hit invalidate
244 assign hit_vld = hit_ps1 & vld;
245 wire hit_inv = |ptb2vtb_inv;
246
247// data buffer read address encoding
248 assign hit_tag = tag_enc (hit_vld);
249 assign dbra_ps1 = {hit_tag, vab2vtb_dbra};
250
251// crb hit, invalidate, tag, and valid
252 assign vtb2crb_hit = hit_vld;
253 wire vtb2crb_inv = hit_inv;
254 assign vtb2crb_tag = tag_enc (ptb2vtb_inv);
255 assign vtb2crb_vld = vld;
256
257// csr performance events
258 wire vtb2csr_prf = hit_inv;
259
260// csr read data
261// assign vtb2csr_rd[`FIRE_DLC_MMU_VTR_TAG_BITS] = tag[csr2vtb_ra];
262 assign vtb2csr_rd[`FIRE_DLC_MMU_VTR_VLD_BITS] = vld[csr2vtb_ra];
263
264// tcb hit is the virtual address tag hit
265 wire vtb2tcb_hit = |(hit_vld & ~tld);
266
267// data buffer read addresses
268 assign vtb2tdb_dbra = dbra_ps1;
269 assign vtb2tlb_dbra = dbra_ps1;
270
271// ----------------------------------------------------------------------------
272// Sequential
273// ----------------------------------------------------------------------------
274 always @ (posedge clk) begin
275 if (!rst_l) begin
276 vld <= 0;
277 end
278 else begin
279 vld <= nxt_vld;
280 end
281 end
282
283 always @ (posedge clk)
284 if(~rst_l) begin
285 tld <= {`FIRE_DLC_MMU_TAG_SIZE{1'b0}};
286 end
287 else begin
288 if (!tcb2vtb_hld) begin
289 tld <= tag_ld;
290 end
291 else begin
292 tld <= tld | tag_ld;
293 end
294 end
295
296// always @ (posedge clk) begin
297// for (i = 0; i < `FIRE_DLC_MMU_TAG_SIZE; i = i + 1) begin
298// if (tag_ld[i]) begin
299// tag[i] <= new_tag;
300// end
301// if (!tcb2vtb_hld) begin
302// hit_ps1[i] <= tcb2vtb_tmv & vld[i] & (vab2vtb_addr == tag[i]);
303// end
304// end
305// end
306//BP n2 6-30-04 new cam model
307wire [3:0] spare;
308wire [4:0] sun4v_bits;
309assign sun4v_bits = sun4v_mode ? vab2vtb_iotsbno : {5{1'b0}};
310
311//BP 9-23-04 add dout bypass mux for scan
312// note tlb2vtb_addr comes from flops in dmu_mmu_tlb.v
313wire [23:0] vtb_out1;
314wire [4:0] vtb_out2;
315assign vtb2csr_rd[`FIRE_DLC_MMU_VTR_IOTSBNO_BITS] = tcu_array_bypass ? tlb2vtb_addr[20:16] : vtb_out2 ;
316assign vtb2csr_rd[`FIRE_DLC_MMU_VTR_VPN_BITS] = tcu_array_bypass ? tlb2vtb_addr : vtb_out1 ;
317
318//SV 02/24/05 added BIST logic
319 wire [32:0] din_cam, key_cam ;
320 wire [5:0] rd_addr_cam, wr_addr_cam ;
321 wire wr_en_cam, rd_en_cam, lkup_en_cam, hld_cam ;
322
323 assign mmu_vtb_hit = hit_out ;
324 assign vtb_dout_4msb = spare[3:0] ;
325 assign din_cam = dmu_cb0_run ? dmu_cb0_wdata_key : ({{4{1'b0}},new_tag_iotsbno,new_tag}) ;
326 assign rd_addr_cam = dmu_cb0_run ? dmu_cb0_addr : csr2vtb_ra ;
327 assign wr_addr_cam = dmu_cb0_run ? dmu_cb0_addr : new_wa ;
328 assign wr_en_cam = dmu_cb0_run ? dmu_cb0_mmu_vtb_wr_en : new_we ;
329 assign rd_en_cam = dmu_cb0_run ? dmu_cb0_mmu_vtb_rd_en : 1'b1 ;
330 assign hld_cam = dmu_cb0_run ? dmu_cb0_hld : tcb2vtb_hld ;
331 assign key_cam = dmu_cb0_run ? dmu_cb0_wdata_key : ({{4{1'b0}},sun4v_bits,vab2vtb_addr}) ;
332 assign lkup_en_cam = dmu_cb0_run ? dmu_cb0_mmu_vtb_lkup_en : tcb2vtb_tmv ;
333
334
335/* 0in memory_access -read_addr rd_addr_cam -read (rd_en_cam & ~wr_en_cam)
336 -write_addr wr_addr_cam -write wr_en_cam
337 -latency 1
338 -write_data din_cam
339 -read_data {spare[3:0],vtb_out2,vtb_out1}
340*/
341 n2_mmu_cm_64x34s_cust vtb_cam
342 (
343 // address ports
344 .rd_addr (rd_addr_cam),
345 .wr_addr (wr_addr_cam),
346
347 // clock ports
348 .clk (l2clk),
349
350 // data input ports
351 .din (din_cam),
352
353 // data output ports
354// .dout ({spare,vtb2csr_rd[`FIRE_DLC_MMU_VTR_IOTSBNO_BITS],vtb2csr_rd[`FIRE_DLC_MMU_VTR_VPN_BITS]}),
355 .dout ({spare[3:0],vtb_out2,vtb_out1}),
356
357 // port enables
358 .wr_en (wr_en_cam),
359 .rd_en (rd_en_cam),
360
361 // key--address to CAM against
362 .key (key_cam),
363
364 // key--address to CAM against
365 .lkup_en (lkup_en_cam),
366
367 // hold key
368 .hld (hld_cam),
369
370 // 64 hit values after CAM'ing
371 .hit (hit_out),
372
373
374 // scan ports
375 .scan_in (scan_in),
376 .tcu_se_scancollar_in (tcu_se_scancollar_in),
377 .tcu_scan_en (tcu_scan_en),
378 .tcu_array_wr_inhibit (tcu_array_wr_inhibit),
379 .tcu_pce_ov (tcu_pce_ov),
380 .pce (1'b1),
381 .tcu_aclk (tcu_aclk),
382 .tcu_bclk (tcu_bclk),
383 .scan_out (scan_out)
384 );
385
386reg [63:0] vld_d;
387 always @ (posedge clk)
388 if(~rst_l) begin
389 vld_d <= {64{1'b0}};
390 end
391 else begin
392 if (!tcb2vtb_hld) begin
393 vld_d <= vld;
394 end
395 end
396//assign hit_ps1 = {64{tcb2vtb_tmv}} & vld & hit_out;
397assign hit_ps1 = vld_d & hit_out;
398
399endmodule // dmu_mmu_vtb