Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: dmu_mmu_tcb_tmc.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 ============================================ | |
35 | module dmu_mmu_tcb_tmc | |
36 | ( | |
37 | clk, // clock | |
38 | rst_l, // reset | |
39 | csr2tcb_av, // csr access violation | |
40 | csr2tcb_be, // csr bypass enable | |
41 | csr2tcb_cm, // csr cache mode | |
42 | csr2tcb_ds_a, // csr debug select a | |
43 | csr2tcb_ds_b, // csr debug select b | |
44 | csr2tcb_pd, // csr processing disable | |
45 | csr2tcb_te, // csr translation enable | |
46 | pab2tcb_err, // pab errors | |
47 | tlb2tcb_hit, // tlb virtual tag hit | |
48 | vab2tcb_err, // vab errors | |
49 | vab2tcb_vld, // vab valids | |
50 | vab2tcb_sun4v_va_oor, // sun4v va oor | |
51 | vab2tcb_4vor, // sun4v out of range | |
52 | vab2tcb_s4uf, // sun4v underflow | |
53 | qcb2tcb_hld, // qcb hold | |
54 | qcb2tcb_vld, // qcb valid | |
55 | vtb2tcb_hit, // vtb hit | |
56 | tcc2tmc_ack, // tcc acknowledge | |
57 | tcc2tmc_dbg, // tcc debug | |
58 | tcc2tmc_vld, // tcc valid | |
59 | tdc2tmc_dbg, // tdc debug | |
60 | tdc2tmc_err, // tdc errors | |
61 | tcb2csr_dbg_a, // csr debug bus a | |
62 | tcb2csr_dbg_b, // csr debug bus b | |
63 | tcb2csr_err, // csr errors | |
64 | tcb2csr_prf, // csr performance events | |
65 | tcb2csr_tpl, // csr translation pipeline not empty | |
66 | tcb2pab_err, // pab error | |
67 | tcb2pab_sel, // pab select | |
68 | tcb2qcb_hld, // qcb hold | |
69 | tcb2qcb_vld, // qcb valids | |
70 | tcb2tlb_hld, // tlb holds | |
71 | tcb2tlb_sel, // tlb select | |
72 | tcb2vab_hld, // vab hold | |
73 | tcb2vtb_hld, // vtb holds | |
74 | tcb2vtb_tmv, // vtb valid | |
75 | vaq2tcb_deq_en, | |
76 | tmc2tcc_req, // tcc request | |
77 | tdb2tmc_kerr, // key error on ppn readout out of ram | |
78 | tlb2tmc_kerr, // key error on ppn readout out of tlb single entry | |
79 | srq2tmc_ipe, // iotsb parity error sunv4 mode only | |
80 | srq2tmc_ivld, // iotsb valid bit and'ed with sun4v_mode | |
81 | sun4v_mode, // 1 = sun4v_mode | |
82 | srq2tmc_sun4v_pgsz_err // 1 = sun4v_mode illegal page size | |
83 | ); | |
84 | ||
85 | // ---------------------------------------------------------------------------- | |
86 | // Parameters | |
87 | // ---------------------------------------------------------------------------- | |
88 | parameter IDLE = 2'b00, // state machine states | |
89 | THLD = 2'b01, | |
90 | QHLD = 2'b10, | |
91 | BOTH = 2'b11; | |
92 | ||
93 | // parameter ERR_MSK = 16'hFDFF; // error mask | |
94 | parameter ERR_MSK = 21'h1FFDFF; // error mask | |
95 | ||
96 | // ---------------------------------------------------------------------------- | |
97 | // Ports | |
98 | // ---------------------------------------------------------------------------- | |
99 | input clk; | |
100 | input rst_l; | |
101 | ||
102 | input csr2tcb_av; | |
103 | input csr2tcb_be; | |
104 | input [`FIRE_DLC_MMU_CSR_CM_BITS] csr2tcb_cm; | |
105 | input [`FIRE_DLC_MMU_CSR_DS_BITS] csr2tcb_ds_a; | |
106 | input [`FIRE_DLC_MMU_CSR_DS_BITS] csr2tcb_ds_b; | |
107 | input csr2tcb_pd; | |
108 | input csr2tcb_te; | |
109 | input [`FIRE_DLC_MMU_PAB_ERR_BITS] pab2tcb_err; | |
110 | input tlb2tcb_hit; | |
111 | input [`FIRE_DLC_MMU_VAB_ERR_BITS] vab2tcb_err; | |
112 | input [`FIRE_DLC_MMU_VAB_VLD_BITS] vab2tcb_vld; | |
113 | input vab2tcb_sun4v_va_oor; | |
114 | input vab2tcb_4vor; | |
115 | input vab2tcb_s4uf; | |
116 | input qcb2tcb_hld; | |
117 | input qcb2tcb_vld; | |
118 | input vtb2tcb_hit; | |
119 | input tcc2tmc_ack; | |
120 | input [`FIRE_DBG_DATA_BITS] tcc2tmc_dbg; | |
121 | input tcc2tmc_vld; | |
122 | input [`FIRE_DBG_DATA_BITS] tdc2tmc_dbg; | |
123 | input [`FIRE_DLC_MMU_TDC_ERR_BITS] tdc2tmc_err; | |
124 | input vaq2tcb_deq_en; | |
125 | input tdb2tmc_kerr; | |
126 | input tlb2tmc_kerr; | |
127 | input srq2tmc_ipe; | |
128 | input srq2tmc_ivld; | |
129 | input sun4v_mode; | |
130 | input srq2tmc_sun4v_pgsz_err; | |
131 | ||
132 | output [`FIRE_DBG_DATA_BITS] tcb2csr_dbg_a; | |
133 | output [`FIRE_DBG_DATA_BITS] tcb2csr_dbg_b; | |
134 | output [`FIRE_DLC_MMU_CSR_ERR_BITS] tcb2csr_err; | |
135 | output [`FIRE_DLC_MMU_TCB_PRF_BITS] tcb2csr_prf; | |
136 | output tcb2csr_tpl; | |
137 | output tcb2pab_err; | |
138 | output tcb2pab_sel; | |
139 | output tcb2qcb_hld; | |
140 | output [`FIRE_DLC_MMU_PLS_DPTH:1] tcb2qcb_vld; | |
141 | output tcb2tlb_hld; | |
142 | output tcb2tlb_sel; | |
143 | output tcb2vab_hld; | |
144 | output tcb2vtb_hld; | |
145 | output tcb2vtb_tmv; | |
146 | output tmc2tcc_req; | |
147 | ||
148 | // ---------------------------------------------------------------------------- | |
149 | // Variables | |
150 | // ---------------------------------------------------------------------------- | |
151 | wire [`FIRE_DBG_DATA_BITS] tcb2csr_dbg_a, tcb2csr_dbg_b; | |
152 | wire [`FIRE_DLC_MMU_CSR_ERR_BITS] tcb2csr_err, err_ne0, err_ne1, err_ne2; | |
153 | wire [`FIRE_DLC_MMU_TCB_PRF_BITS] tcb2csr_prf; | |
154 | wire [`FIRE_DLC_MMU_PLS_DPTH:1] tcb2qcb_vld, nxt_vld; | |
155 | wire [`FIRE_DLC_MMU_PLS_DPTH-1:1] nxt_bmv, nxt_tmv; | |
156 | wire [`FIRE_DLC_MMU_TDC_ERR_BITS] nxt_err, twk_err; | |
157 | ||
158 | reg [`FIRE_DLC_MMU_TDC_ERR_BITS] err; | |
159 | reg [`FIRE_DLC_MMU_CSR_ERR_BITS] err_ps1, err_ps2; | |
160 | reg [`FIRE_DLC_MMU_PLS_DPTH:0] vld; | |
161 | reg [`FIRE_DLC_MMU_PLS_DPTH-1:0] bmv, tmv; | |
162 | reg [`FIRE_DLC_MMU_PLS_DPTH-1:0] hld; | |
163 | reg [1:0] state, nxt_state; | |
164 | reg ack, req, nxt_req; | |
165 | reg hit_ps1, hit_ps2; | |
166 | reg bmv_err, tmv_err, tdm_err; | |
167 | reg sun4v_pgsz_err; | |
168 | ||
169 | reg [`FIRE_DLC_MMU_CSR_DS_BITS] dbg_sel [0:1]; | |
170 | reg [`FIRE_DBG_DATA_BITS] dbg_bus [0:1]; | |
171 | ||
172 | integer i; | |
173 | ||
174 | // ---------------------------------------------------------------------------- | |
175 | // Zero In Checkers | |
176 | // ---------------------------------------------------------------------------- | |
177 | ||
178 | // 0in state_transition -var state -val IDLE -next THLD QHLD BOTH | |
179 | // 0in state_transition -var state -val THLD -next IDLE QHLD BOTH | |
180 | // 0in state_transition -var state -val QHLD -next IDLE THLD BOTH | |
181 | // 0in state_transition -var state -val BOTH -next IDLE THLD QHLD | |
182 | ||
183 | // ---------------------------------------------------------------------------- | |
184 | // Combinational | |
185 | // ---------------------------------------------------------------------------- | |
186 | assign tcb2csr_tpl = |vld; | |
187 | assign tcb2qcb_vld = vld[`FIRE_DLC_MMU_PLS_DPTH:1]; | |
188 | ||
189 | // ---------------------------------------------------------------------------- | |
190 | // Pipeline stage 0 controls | |
191 | // ---------------------------------------------------------------------------- | |
192 | reg vaq2tcb_deq_en_d; | |
193 | always @(posedge clk) begin | |
194 | if(rst_l == 1'b0) begin | |
195 | vaq2tcb_deq_en_d <= 1'b0; | |
196 | end | |
197 | else vaq2tcb_deq_en_d <= vaq2tcb_deq_en; | |
198 | end | |
199 | ||
200 | wire vld_ps0 = qcb2tcb_vld & ~csr2tcb_pd & ~hld[0] & (vaq2tcb_deq_en && vaq2tcb_deq_en_d); | |
201 | ||
202 | // valid signals | |
203 | always @ (csr2tcb_be or csr2tcb_te or vab2tcb_vld or vld_ps0 or srq2tmc_sun4v_pgsz_err) begin | |
204 | bmv_err = ~(csr2tcb_be | vab2tcb_vld[2]) & vld_ps0 & vab2tcb_vld[0]; | |
205 | bmv[0] = (csr2tcb_be | vab2tcb_vld[2]) & vld_ps0 & vab2tcb_vld[0]; | |
206 | tmv_err = ~csr2tcb_te & vld_ps0 & vab2tcb_vld[1]; | |
207 | tmv[0] = csr2tcb_te & vld_ps0 & vab2tcb_vld[1]; | |
208 | vld[0] = vld_ps0; | |
209 | sun4v_pgsz_err = srq2tmc_sun4v_pgsz_err & tmv[0]; | |
210 | end | |
211 | ||
212 | // vtb valid | |
213 | wire tcb2vtb_tmv = tmv[0]; | |
214 | wire ivld = tmv[0] & srq2tmc_ivld; | |
215 | wire ipe = tmv[0] & srq2tmc_ipe; | |
216 | wire sun4v_va_oor = tmv[0] & vab2tcb_sun4v_va_oor; | |
217 | ||
218 | //BP 11-30-05 | |
219 | // I don't need to explicitly add ~bmv_err to mask sun4v errors since tmv is added to | |
220 | // all of the error cases, the same for tmv_err | |
221 | // errors | |
222 | assign err_ne0[0] = bmv_err; // bypass error | |
223 | assign err_ne0[1] = 0; // bypass out of range error | |
224 | assign err_ne0[2] = sun4v_pgsz_err & // sun4v page size error, illegal selection | |
225 | ~sun4v_va_oor & ~ipe & ~ivld ; | |
226 | assign err_ne0[3] = 0; // spare | |
227 | assign err_ne0[4] = tmv_err; // translation error | |
228 | assign err_ne0[5] = 0; // translation out of range error | |
229 | assign err_ne0[6] = 0; // tte invalid | |
230 | assign err_ne0[7] = 0; // tte protection error | |
231 | assign err_ne0[8] = 0; // tte cache parity error | |
232 | assign err_ne0[9] = 0; // csr cache access violation | |
233 | assign err_ne0[10] = 0; // spare | |
234 | assign err_ne0[11] = 0; // spare | |
235 | assign err_ne0[12] = 0; // tablewalk disabled error | |
236 | assign err_ne0[13] = 0; // tablewalk unexpected data | |
237 | assign err_ne0[14] = 0; // tablewalk error | |
238 | assign err_ne0[15] = 0; // tablewalk parity error | |
239 | assign err_ne0[16] = ivld & // sun4v iotsb valid bit not set | |
240 | ~sun4v_va_oor & ~srq2tmc_ipe ; | |
241 | assign err_ne0[17] = ipe & // sun4v iotsb parity error | |
242 | ~sun4v_va_oor ; | |
243 | assign err_ne0[18] = sun4v_va_oor ; // sun4v va out of range | |
244 | assign err_ne0[19] = 0; // sun4v va underflow | |
245 | assign err_ne0[20] = 0; // sun4v key error | |
246 | ||
247 | // next valids | |
248 | assign nxt_bmv[1] = bmv[0]; | |
249 | assign nxt_tmv[1] = tmv[0]; | |
250 | assign nxt_vld[1] = vld[0]; | |
251 | ||
252 | // ---------------------------------------------------------------------------- | |
253 | // Pipeline stage 1 controls | |
254 | // ---------------------------------------------------------------------------- | |
255 | ||
256 | // tlb hit and tablewalk test | |
257 | wire tlb_hit = tlb2tcb_hit & tcc2tmc_vld; | |
258 | // wire twk_tst = tmv[1] & ~hld[1] & ~vab2tcb_err[1]; | |
259 | //BP n2 9-24-04 inhibit tablewalk on all 4 of the n2 errors, bits [19:16], bit 20 is after translation | |
260 | // so it is handled similar to a tdb parity error | |
261 | wire sun4v_uf,sun4v_or; | |
262 | wire twk_tst = tmv[1] & ~hld[1] & ~((vab2tcb_err[1] & ~sun4v_mode) | | |
263 | (err_ps1[18] | err_ps1[17] | err_ps1[16] | err_ps1[2] | sun4v_or | sun4v_uf )); | |
264 | ||
265 | // tablewalk request | |
266 | always @ (csr2tcb_cm or vtb2tcb_hit or tlb_hit or twk_tst) begin | |
267 | case (csr2tcb_cm) // synopsys parallel_case | |
268 | 2'b00 : nxt_req = twk_tst & ~tlb_hit; | |
269 | 2'b01 : nxt_req = 1'b0; | |
270 | 2'b10 : nxt_req = twk_tst & ~(tlb_hit | vtb2tcb_hit); | |
271 | 2'b11 : nxt_req = twk_tst & ~(tlb_hit | vtb2tcb_hit); | |
272 | endcase | |
273 | end | |
274 | ||
275 | // tablewalk disabled miss error | |
276 | always @ (csr2tcb_cm or vtb2tcb_hit or twk_tst) begin | |
277 | case (csr2tcb_cm) // synopsys parallel_case | |
278 | 2'b00 : tdm_err = 1'b0; | |
279 | 2'b01 : tdm_err = twk_tst & ~vtb2tcb_hit; | |
280 | 2'b10 : tdm_err = 1'b0; | |
281 | 2'b11 : tdm_err = 1'b0; | |
282 | endcase | |
283 | end | |
284 | ||
285 | // hit | |
286 | always @ (csr2tcb_cm or vtb2tcb_hit or twk_tst) begin | |
287 | case (csr2tcb_cm) // synopsys parallel_case | |
288 | 2'b00 : hit_ps1 = 1'b0; | |
289 | 2'b01 : hit_ps1 = twk_tst & vtb2tcb_hit; | |
290 | 2'b10 : hit_ps1 = twk_tst & vtb2tcb_hit; | |
291 | 2'b11 : hit_ps1 = twk_tst & vtb2tcb_hit; | |
292 | endcase | |
293 | end | |
294 | ||
295 | // sun4v mode errors , n2 only | |
296 | assign sun4v_or = tmv[1] & ~hld[1] & vab2tcb_4vor; | |
297 | assign sun4v_uf = tmv[1] & ~hld[1] & vab2tcb_s4uf ; | |
298 | ||
299 | // errors | |
300 | assign err_ne1[0] = err_ps1[0]; | |
301 | assign err_ne1[1] = err_ps1[1] | (bmv[1] & vab2tcb_err[0]); | |
302 | assign err_ne1[2] = err_ps1[2] ; | |
303 | assign err_ne1[3] = err_ps1[3]; | |
304 | assign err_ne1[4] = err_ps1[4]; | |
305 | assign err_ne1[5] = err_ps1[5] | (tmv[1] & (vab2tcb_err[1] & ~sun4v_mode)) | | |
306 | (sun4v_or & ~sun4v_uf & ~err_ps1[18] & ~err_ps1[17] & ~err_ps1[16] & ~err_ps1[2]); | |
307 | assign err_ne1[6] = err_ps1[6]; | |
308 | assign err_ne1[7] = err_ps1[7]; | |
309 | assign err_ne1[8] = err_ps1[8]; | |
310 | assign err_ne1[9] = err_ps1[9]; | |
311 | assign err_ne1[10] = err_ps1[10]; | |
312 | assign err_ne1[11] = err_ps1[11]; | |
313 | assign err_ne1[12] = err_ps1[12] | tdm_err; | |
314 | assign err_ne1[13] = err_ps1[13]; | |
315 | assign err_ne1[14] = err_ps1[14]; | |
316 | assign err_ne1[15] = err_ps1[15]; | |
317 | assign err_ne1[16] = err_ps1[16]; | |
318 | assign err_ne1[17] = err_ps1[17]; | |
319 | assign err_ne1[18] = err_ps1[18] ; | |
320 | assign err_ne1[19] = err_ps1[19] | (sun4v_uf & ~err_ps1[18] & ~err_ps1[17] & ~err_ps1[16] & ~err_ps1[2]); | |
321 | assign err_ne1[20] = err_ps1[20]; | |
322 | ||
323 | // next valids | |
324 | assign nxt_bmv[2] = bmv[1] & ~hld[1] & ~vab2tcb_err[0]; | |
325 | assign nxt_tmv[2] = tmv[1] & ~hld[1] & ~((vab2tcb_err[1] & ~sun4v_mode) | | |
326 | (err_ps1[18] | err_ps1[17] | err_ps1[16] | err_ps1[2] | sun4v_or | sun4v_uf )) & ~tdm_err; | |
327 | assign nxt_vld[2] = vld[1] & ~hld[1]; | |
328 | ||
329 | // tablewalk request | |
330 | wire tmc2tcc_req = nxt_req; | |
331 | ||
332 | // ---------------------------------------------------------------------------- | |
333 | // Pipeline stage 2 controls | |
334 | // ---------------------------------------------------------------------------- | |
335 | ||
336 | // tablewalk errors | |
337 | assign twk_err = err | tdc2tmc_err; | |
338 | assign nxt_err = hld[2] ? twk_err : 0; | |
339 | ||
340 | // pab error enable | |
341 | wire pab_en = tmv[2] & ~|twk_err; | |
342 | ||
343 | //BP n2 10-05-04 | |
344 | // log key errors, 4 cases, see pg 226 fire prm | |
345 | reg key_err; | |
346 | always @ (csr2tcb_cm or tlb2tmc_kerr or tdb2tmc_kerr or pab_en or tcb2pab_sel) begin | |
347 | case (csr2tcb_cm) // synopsys parallel_case | |
348 | 2'b00 : key_err = pab_en & tlb2tmc_kerr; | |
349 | 2'b01 : key_err = pab_en & tdb2tmc_kerr; | |
350 | 2'b10 : key_err = pab_en & (tcb2pab_sel ? tlb2tmc_kerr : tdb2tmc_kerr ); | |
351 | 2'b11 : key_err = pab_en & (tcb2pab_sel ? tlb2tmc_kerr : tdb2tmc_kerr ); | |
352 | endcase | |
353 | end | |
354 | ||
355 | ||
356 | // errors | |
357 | assign err_ne2[0] = err_ps2[0]; | |
358 | assign err_ne2[1] = err_ps2[1]; | |
359 | assign err_ne2[2] = err_ps2[2]; | |
360 | assign err_ne2[3] = err_ps2[3]; | |
361 | assign err_ne2[4] = err_ps2[4]; | |
362 | assign err_ne2[5] = err_ps2[5]; | |
363 | assign err_ne2[6] = err_ps2[6] | (pab_en & pab2tcb_err[0] ); | |
364 | assign err_ne2[7] = err_ps2[7] | (pab_en & pab2tcb_err[1] ); | |
365 | assign err_ne2[8] = err_ps2[8] | (pab_en & pab2tcb_err[2] ); | |
366 | assign err_ne2[9] = err_ps2[9] | csr2tcb_av; | |
367 | assign err_ne2[10] = err_ps2[10]; | |
368 | assign err_ne2[11] = err_ps2[11]; | |
369 | assign err_ne2[12] = err_ps2[12]; | |
370 | assign err_ne2[13] = err_ps2[13] | twk_err[0]; | |
371 | assign err_ne2[14] = err_ps2[14] | twk_err[1]; | |
372 | assign err_ne2[15] = err_ps2[15] | twk_err[2]; | |
373 | assign err_ne2[16] = err_ps2[16] ; | |
374 | assign err_ne2[17] = err_ps2[17] ; | |
375 | assign err_ne2[18] = err_ps2[18] ; | |
376 | assign err_ne2[19] = err_ps2[19] ; | |
377 | assign err_ne2[20] = err_ps2[20] | key_err ; | |
378 | ||
379 | // next valids | |
380 | assign nxt_vld[3] = vld[2] & ~hld[2]; | |
381 | ||
382 | // errors and selects | |
383 | assign tcb2csr_err = nxt_vld[3] ? err_ne2 : err_ne2 & ~ERR_MSK; | |
384 | wire tcb2pab_err = |(err_ne2 & ERR_MSK); | |
385 | wire tcb2pab_sel = ~hit_ps2; | |
386 | wire tcb2tlb_sel = ~tmv[2]; | |
387 | ||
388 | // ---------------------------------------------------------------------------- | |
389 | // Pipeline hold state machine | |
390 | // ---------------------------------------------------------------------------- | |
391 | ||
392 | // next state | |
393 | always @ (state or qcb2tcb_hld or ack or req) begin | |
394 | case (state) // synopsys parallel_case | |
395 | IDLE : | |
396 | case ({qcb2tcb_hld, req}) // synopsys parallel_case | |
397 | 2'b00 : nxt_state = IDLE; | |
398 | 2'b01 : nxt_state = THLD; | |
399 | 2'b10 : nxt_state = QHLD; | |
400 | 2'b11 : nxt_state = BOTH; | |
401 | endcase | |
402 | THLD : | |
403 | case ({qcb2tcb_hld, ack}) // synopsys parallel_case | |
404 | 2'b00 : nxt_state = THLD; | |
405 | 2'b01 : nxt_state = IDLE; | |
406 | 2'b10 : nxt_state = BOTH; | |
407 | 2'b11 : nxt_state = QHLD; | |
408 | endcase | |
409 | QHLD : | |
410 | case ({qcb2tcb_hld, req}) // synopsys parallel_case | |
411 | 2'b00 : nxt_state = IDLE; | |
412 | 2'b01 : nxt_state = THLD; | |
413 | 2'b10 : nxt_state = QHLD; | |
414 | 2'b11 : nxt_state = BOTH; | |
415 | endcase | |
416 | BOTH : | |
417 | case ({qcb2tcb_hld, ack}) // synopsys parallel_case | |
418 | 2'b00 : nxt_state = THLD; | |
419 | 2'b01 : nxt_state = IDLE; | |
420 | 2'b10 : nxt_state = BOTH; | |
421 | 2'b11 : nxt_state = QHLD; | |
422 | endcase | |
423 | endcase | |
424 | end | |
425 | ||
426 | // state machine outputs | |
427 | always @ (state or nxt_state) begin | |
428 | case (state) // synopsys parallel_case | |
429 | IDLE : | |
430 | case (nxt_state) // synopsys parallel_case | |
431 | IDLE : hld = 3'b000; | |
432 | THLD : hld = 3'b111; | |
433 | QHLD : hld = 3'b011; | |
434 | BOTH : hld = 3'b111; | |
435 | endcase | |
436 | THLD : | |
437 | case (nxt_state) // synopsys parallel_case | |
438 | IDLE : hld = 3'b000; | |
439 | THLD : hld = 3'b111; | |
440 | QHLD : hld = 3'b011; | |
441 | BOTH : hld = 3'b111; | |
442 | endcase | |
443 | QHLD : | |
444 | case (nxt_state) // synopsys parallel_case | |
445 | IDLE : hld = 3'b000; | |
446 | THLD : hld = 3'b000; | |
447 | QHLD : hld = 3'b111; | |
448 | BOTH : hld = 3'b011; | |
449 | endcase | |
450 | BOTH : | |
451 | case (nxt_state) // synopsys parallel_case | |
452 | IDLE : hld = 3'b000; | |
453 | THLD : hld = 3'b111; | |
454 | QHLD : hld = 3'b111; | |
455 | BOTH : hld = 3'b111; | |
456 | endcase | |
457 | endcase | |
458 | end | |
459 | ||
460 | // holds | |
461 | //SV wire tcb2qcb_hld = hld[0] | csr2tcb_pd; | |
462 | wire tcb2qcb_hld = hld[0] | csr2tcb_pd | ~(vaq2tcb_deq_en && vaq2tcb_deq_en_d); | |
463 | wire tcb2tlb_hld = hld[2]; | |
464 | wire tcb2vab_hld = hld[1]; | |
465 | wire tcb2vtb_hld = hld[1]; | |
466 | ||
467 | // ---------------------------------------------------------------------------- | |
468 | // Performance Events | |
469 | // ---------------------------------------------------------------------------- | |
470 | assign tcb2csr_prf[0] = ~hld[2] & (bmv[2] | tmv[2]); // total tranlations | |
471 | assign tcb2csr_prf[1] = |state; // total stall cycles | |
472 | assign tcb2csr_prf[2] = ack; // total misses | |
473 | assign tcb2csr_prf[3] = state[0]; // tablewalk stall cycles | |
474 | assign tcb2csr_prf[4] = ~hld[2] & bmv[2]; // bypass mode trans | |
475 | assign tcb2csr_prf[5] = ~hld[2] & tmv[2]; // translation mode trans | |
476 | assign tcb2csr_prf[6] = state[1]; // flow control stall | |
477 | ||
478 | // ---------------------------------------------------------------------------- | |
479 | // Debug | |
480 | // ---------------------------------------------------------------------------- | |
481 | always @ (csr2tcb_ds_a or csr2tcb_ds_b) begin | |
482 | dbg_sel[0] = csr2tcb_ds_a; | |
483 | dbg_sel[1] = csr2tcb_ds_b; | |
484 | end | |
485 | ||
486 | assign tcb2csr_dbg_a = dbg_bus[0]; | |
487 | assign tcb2csr_dbg_b = dbg_bus[1]; | |
488 | ||
489 | // ---------------------------------------------------------------------------- | |
490 | // Sequential | |
491 | // ---------------------------------------------------------------------------- | |
492 | always @ (posedge clk) begin | |
493 | if (!rst_l) begin | |
494 | ack <= 0; | |
495 | err <= 0; | |
496 | req <= 0; | |
497 | state <= IDLE; | |
498 | end | |
499 | else begin | |
500 | ack <= tcc2tmc_ack; | |
501 | err <= nxt_err; | |
502 | req <= nxt_req; | |
503 | state <= nxt_state; | |
504 | end | |
505 | end | |
506 | ||
507 | // pipeline stage 1 | |
508 | always @ (posedge clk) begin | |
509 | if (!rst_l) begin | |
510 | err_ps1 <= 0; | |
511 | bmv[1] <= 0; | |
512 | tmv[1] <= 0; | |
513 | vld[1] <= 0; | |
514 | end | |
515 | else if (~hld[1]) begin | |
516 | err_ps1 <= err_ne0; | |
517 | bmv[1] <= nxt_bmv[1]; | |
518 | tmv[1] <= nxt_tmv[1]; | |
519 | vld[1] <= nxt_vld[1]; | |
520 | end | |
521 | end | |
522 | ||
523 | // pipeline stage 2 | |
524 | always @ (posedge clk) begin | |
525 | if (!rst_l) begin | |
526 | err_ps2 <= 0; | |
527 | hit_ps2 <= 0; | |
528 | bmv[2] <= 0; | |
529 | tmv[2] <= 0; | |
530 | vld[2] <= 0; | |
531 | end | |
532 | else if (~hld[2]) begin | |
533 | err_ps2 <= err_ne1; | |
534 | hit_ps2 <= hit_ps1; | |
535 | bmv[2] <= nxt_bmv[2]; | |
536 | tmv[2] <= nxt_tmv[2]; | |
537 | vld[2] <= nxt_vld[2]; | |
538 | end | |
539 | end | |
540 | ||
541 | // pipeline stage 3 | |
542 | always @ (posedge clk) begin | |
543 | if (!rst_l) begin | |
544 | vld[3] <= 0; | |
545 | end | |
546 | else begin | |
547 | vld[3] <= nxt_vld[3]; | |
548 | end | |
549 | end | |
550 | ||
551 | // debug | |
552 | always @ (posedge clk) begin | |
553 | if (!rst_l) begin | |
554 | for (i = 0; i < 2; i = i + 1) begin | |
555 | dbg_bus[i] <= 8'b0; | |
556 | end | |
557 | end | |
558 | else begin | |
559 | for (i = 0; i < 2; i = i + 1) begin | |
560 | case (dbg_sel[i]) // synopsys infer_mux | |
561 | 3'b000: dbg_bus[i] <= { 1'b0, hld, vld }; | |
562 | 3'b001: dbg_bus[i] <= { state, tmv, bmv }; | |
563 | 3'b010: dbg_bus[i] <= { tlb2tcb_hit, tcc2tmc_vld, hld, tmv}; | |
564 | 3'b011: dbg_bus[i] <= { vtb2tcb_hit, twk_tst, hld, tmv}; | |
565 | 3'b100: dbg_bus[i] <= tcc2tmc_dbg; | |
566 | 3'b101: dbg_bus[i] <= tdc2tmc_dbg; | |
567 | 3'b110: dbg_bus[i] <= tcb2csr_err[7:0]; | |
568 | 3'b111: dbg_bus[i] <= tcb2csr_err[15:8]; | |
569 | endcase | |
570 | end | |
571 | end | |
572 | end | |
573 | ||
574 | endmodule // dmu_mmu_tcb_tmc |