Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / dmu / rtl / dmu_mmu_pab.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: dmu_mmu_pab.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_pab
36 (
37 clk, // clock
38 rst_l, // reset
39 csr2pab_ps, // csr page size
40 tcb2pab_err, // tcb error
41 tcb2pab_sel, // tcb select
42 tdb2pab_par, // tdb parity
43 tdb2pab_ppn, // tdb pyhsical page number
44 tdb2pab_wrt, // tdb write
45 tdb2pab_vld, // tdb valid
46 tdb2pab_keyvld, // pab key valid
47 tdb2pab_fnm, // pab function number
48 tdb2pab_key, // pab key
49 tlb2pab_addr, // tlb address
50 tlb2pab_type, // tlb type
51 tlb2pab_vld, // tlb valid
52 tlb2pab_wrt, // tlb write
53 pab2paq_rcd, // paq physical address record
54 pab2tcb_err, // tcb error
55 tlb2pab_sun4v_pgsz, // sun4v page size to concat pa offset
56 sun4v_mode, // sun4v mode
57 tlb2pab_byp_ps2 // 1 if sun4v mode and bypass detected
58 );
59
60// ----------------------------------------------------------------------------
61// Parameters
62// ----------------------------------------------------------------------------
63 parameter PAM = `FIRE_PA_MSB; // physical address MSB = 42
64 parameter PAM_N2 = `N2_PA_MSB; // physical address MSB = 38
65
66 parameter MEM_RDT = 7'b0000000, // type encodings
67 MEM_RDB = 7'b0100000,
68 MEM_WRT = 7'b1000000,
69 MEM_WRB = 7'b1100000,
70 MSG_WRT = 7'b1010000,
71 MSG_WRB = 7'b1110000,
72 MSI_WRT = 7'b1011000,
73 MSI_WRB = 7'b1111000;
74
75// ----------------------------------------------------------------------------
76// Ports
77// ----------------------------------------------------------------------------
78 input clk;
79 input rst_l;
80
81 input csr2pab_ps;
82 input tcb2pab_err;
83 input tcb2pab_sel;
84 input [`FIRE_DLC_MMU_TDD_PAR_BITS] tdb2pab_par;
85 input [`FIRE_DLC_MMU_TDD_PPN_BITS] tdb2pab_ppn;
86 input tdb2pab_wrt;
87 input tdb2pab_vld;
88 input [`FIRE_DLC_MMU_PA_ADDR_BITS] tlb2pab_addr;
89 input [`FIRE_DLC_MMU_PA_TYPE_BITS] tlb2pab_type;
90 input tlb2pab_vld;
91 input tlb2pab_wrt;
92 input [`FIRE_DLC_MMU_TDD_KEY_BITS] tdb2pab_key;
93 input [`FIRE_DLC_MMU_TDD_FNM_BITS] tdb2pab_fnm;
94 input tdb2pab_keyvld;
95 output [`FIRE_DLC_MMU_PAR_BITS] pab2paq_rcd;
96 output [`FIRE_DLC_MMU_PAB_ERR_BITS] pab2tcb_err;
97 input [2:0] tlb2pab_sun4v_pgsz;
98 input sun4v_mode;
99 input tlb2pab_byp_ps2;
100
101// ----------------------------------------------------------------------------
102// Variables
103// ----------------------------------------------------------------------------
104 wire [`FIRE_DLC_MMU_PAR_BITS] pab2paq_rcd;
105 reg [`FIRE_DLC_MMU_PA_ADDR_BITS] addr_ps2;
106 wire [3:0] dpe, par;
107 wire [1:0] sel;
108 reg [25:0] sun4v_pab_addr;
109
110 reg [`FIRE_DLC_MMU_PAB_ERR_BITS] pab2tcb_err;
111 reg [`FIRE_DLC_MMU_PA_ADDR_BITS] addr_ps3;
112 reg [`FIRE_DLC_MMU_PA_TYPE_BITS] type_ps3;
113 reg aerr_ps3;
114 reg dok, vok, wok;
115
116// ----------------------------------------------------------------------------
117// Zero In Checkers
118// ----------------------------------------------------------------------------
119//BP N2 comment out until new tdb ram parity is finalized
120// // 0in odd_parity -var {tdb2pab_ppn[PAM:PAM-7], tdb2pab_par[`FIRE_DLC_MMU_TDD_PAR_LSB+3]} -active ~tcb2pab_sel
121// // 0in odd_parity -var {tdb2pab_ppn[PAM-8:PAM-15], tdb2pab_par[`FIRE_DLC_MMU_TDD_PAR_LSB+2]} -active ~tcb2pab_sel
122// // 0in odd_parity -var {tdb2pab_ppn[PAM-16:PAM-23], tdb2pab_par[`FIRE_DLC_MMU_TDD_PAR_LSB+1]} -active ~tcb2pab_sel
123// // 0in odd_parity -var {tdb2pab_ppn[PAM-24:13], tdb2pab_vld, tdb2pab_wrt, tdb2pab_par[`FIRE_DLC_MMU_TDD_PAR_LSB]} -active ~tcb2pab_sel
124
125// 0in odd_parity -var {tdb2pab_key[`FIRE_DLC_MMU_TDD_KEY_MSB:`FIRE_DLC_MMU_TDD_KEY_LSB+4], tdb2pab_par[`FIRE_DLC_MMU_TDD_PAR_LSB+3]} -active ~tcb2pab_sel
126// 0in odd_parity -var {tdb2pab_key[`FIRE_DLC_MMU_TDD_KEY_LSB+3:`FIRE_DLC_MMU_TDD_KEY_LSB],tdb2pab_ppn[`FIRE_DLC_MMU_TDD_PPN_MSB:`FIRE_DLC_MMU_TDD_PPN_MSB-7], tdb2pab_par[`FIRE_DLC_MMU_TDD_PAR_LSB+2]} -active ~tcb2pab_sel
127// 0in odd_parity -var {tdb2pab_ppn[`FIRE_DLC_MMU_TDD_PPN_MSB-8:`FIRE_DLC_MMU_TDD_PPN_LSB+6], tdb2pab_par[`FIRE_DLC_MMU_TDD_PAR_LSB+1]} -active ~tcb2pab_sel
128// 0in odd_parity -var {tdb2pab_ppn[`FIRE_DLC_MMU_TDD_PPN_LSB+5:`FIRE_DLC_MMU_TDD_PPN_LSB],tdb2pab_fnm,tdb2pab_keyvld,tdb2pab_wrt,tdb2pab_vld, tdb2pab_par[`FIRE_DLC_MMU_TDD_PAR_LSB] } -active ~tcb2pab_sel
129
130// ----------------------------------------------------------------------------
131// Combinational
132// ----------------------------------------------------------------------------
133
134// physical address record creation
135 assign pab2paq_rcd[`FIRE_DLC_MMU_PAR_ADDR_BITS] = addr_ps3;
136 assign pab2paq_rcd[`FIRE_DLC_MMU_PAR_AERR_BITS] = aerr_ps3;
137 assign pab2paq_rcd[`FIRE_DLC_MMU_PAR_TYPE_BITS] = type_ps3;
138
139// errors
140 always @ (dok or wok or vok) begin
141 case ({dok, wok, vok}) // synopsys parallel_case
142 3'b000 : pab2tcb_err = 3'b100;
143 3'b001 : pab2tcb_err = 3'b100;
144 3'b010 : pab2tcb_err = 3'b100;
145 3'b011 : pab2tcb_err = 3'b100;
146 3'b100 : pab2tcb_err = 3'b001;
147 3'b101 : pab2tcb_err = 3'b010;
148 3'b110 : pab2tcb_err = 3'b001;
149 3'b111 : pab2tcb_err = 3'b000;
150 endcase
151 end
152
153// parity
154// assign par[3] = ^tdb2pab_ppn[PAM:PAM-7];
155// assign par[2] = ^tdb2pab_ppn[PAM-8:PAM-15];
156// assign par[1] = ^tdb2pab_ppn[PAM-16:PAM-23];
157// assign par[0] = ^tdb2pab_ppn[PAM-24:13] ^ tdb2pab_vld ^ tdb2pab_wrt;
158
159 assign par[3] = ^{tdb2pab_key[`FIRE_DLC_MMU_TDD_KEY_MSB:`FIRE_DLC_MMU_TDD_KEY_LSB+4]};
160 assign par[2] = ^{tdb2pab_key[`FIRE_DLC_MMU_TDD_KEY_LSB+3:`FIRE_DLC_MMU_TDD_KEY_LSB],tdb2pab_ppn[`FIRE_DLC_MMU_TDD_PPN_MSB:`FIRE_DLC_MMU_TDD_PPN_MSB-7]};
161 assign par[1] = ^tdb2pab_ppn[`FIRE_DLC_MMU_TDD_PPN_MSB-8:`FIRE_DLC_MMU_TDD_PPN_LSB+6];
162 assign par[0] = ^{tdb2pab_ppn[`FIRE_DLC_MMU_TDD_PPN_LSB+5:`FIRE_DLC_MMU_TDD_PPN_LSB],tdb2pab_fnm,tdb2pab_keyvld,tdb2pab_wrt,tdb2pab_vld};
163
164// data parity errors
165 assign dpe[3] = ~par[3] ^ tdb2pab_par[`FIRE_DLC_MMU_TDD_PAR_LSB+3];
166 assign dpe[2] = ~par[2] ^ tdb2pab_par[`FIRE_DLC_MMU_TDD_PAR_LSB+2];
167 assign dpe[1] = ~par[1] ^ tdb2pab_par[`FIRE_DLC_MMU_TDD_PAR_LSB+1];
168 assign dpe[0] = ~par[0] ^ tdb2pab_par[`FIRE_DLC_MMU_TDD_PAR_LSB];
169
170// select data, write, and valid
171//BP N2 fix after parity is done in tdb ram 8-26-04
172 wire dat = tcb2pab_sel | ~(|dpe);
173// wire dat = tcb2pab_sel ;
174 wire wrt = tcb2pab_sel ? tlb2pab_wrt : tdb2pab_wrt;
175 wire vld = tcb2pab_sel ? tlb2pab_vld : tdb2pab_vld;
176
177// select based upon page size
178 assign sel[1] = tcb2pab_sel;
179 assign sel[0] = tcb2pab_sel | csr2pab_ps;
180
181// physical address
182//BP 9-29-05 assign addr_ps2[PAM:16] = sel[1] ? tlb2pab_addr[PAM:16] : {{4{1'b0}},tdb2pab_ppn[PAM_N2:16]};
183//BP 9-29-05 assign addr_ps2[15:13] = sel[0] ? tlb2pab_addr[15:13] : tdb2pab_ppn[15:13];
184//BP 9-29-05 assign addr_ps2[12:2] = tlb2pab_addr[12:2];
185//BP 9-29-05 sun4v requires 4 page sizes
186always @(sun4v_mode or tlb2pab_addr or sel or tdb2pab_ppn or sun4v_pab_addr ) begin
187
188 if (!sun4v_mode) begin
189 addr_ps2[PAM:16] = sel[1] ? tlb2pab_addr[PAM:16] :
190 {{4{1'b0}},tdb2pab_ppn[PAM_N2:16]};
191 addr_ps2[15:13] = (sel[0] ) ? tlb2pab_addr[15:13] : tdb2pab_ppn[15:13];
192 addr_ps2[12:2] = tlb2pab_addr[12:2];
193 end
194 else begin
195 addr_ps2[PAM:2] = {{4{1'b0}},sun4v_pab_addr[25:0],tlb2pab_addr[12:2]};
196 end
197end
198//BP 9-29-05 this logic switches between the tlb data(pipeline or tablewalk)
199// and the tdb pa value
200always @(tlb2pab_sun4v_pgsz or tlb2pab_addr or tdb2pab_ppn or sel ) begin
201
202 sun4v_pab_addr[25:0] = {26{1'b0}}; // PAM=42,`N2_PA_MSB=38
203
204 case(tlb2pab_sun4v_pgsz)
205 3'b000: if (sel[1]) sun4v_pab_addr = tlb2pab_addr[`N2_PA_MSB:13]; // 8k pages
206 else sun4v_pab_addr = tdb2pab_ppn[`N2_PA_MSB:13];
207 3'b001: if (sel[1]) sun4v_pab_addr = tlb2pab_addr[`N2_PA_MSB:13]; // 64k pages
208 else sun4v_pab_addr = {tdb2pab_ppn[`N2_PA_MSB:16],tlb2pab_addr[15:13]};
209 3'b010: sun4v_pab_addr = {26{1'b0}}; // invalid
210 3'b011: if (sel[1]) sun4v_pab_addr = tlb2pab_addr[`N2_PA_MSB:13]; // 4M pages
211 else sun4v_pab_addr = {tdb2pab_ppn[`N2_PA_MSB:22],tlb2pab_addr[21:13]};
212 3'b100: sun4v_pab_addr = {26{1'b0}}; // invalid
213 3'b101: if (sel[1]) sun4v_pab_addr = tlb2pab_addr[`N2_PA_MSB:13]; // 256M pages
214 else sun4v_pab_addr = {tdb2pab_ppn[`N2_PA_MSB:28],tlb2pab_addr[27:13]};
215 3'b110: sun4v_pab_addr = {26{1'b0}}; // invalid
216 3'b111: sun4v_pab_addr = {26{1'b0}}; // invalid
217 default: sun4v_pab_addr = {26{1'b0}};
218 endcase
219end
220
221
222
223
224
225
226// address error
227 wire aerr_ps2 = tcb2pab_err;
228
229//BP n2 12-14-05 fire assumed all 64 bit address were bypass , n2 needs
230// to add 64 bit translation also
231// data ok
232 always @ (tlb2pab_type or dat or sun4v_mode or tlb2pab_byp_ps2) begin
233 case ({tlb2pab_byp_ps2,sun4v_mode,tlb2pab_type}) // synopsys parallel_case
234 {1'b0,1'b0,MEM_RDT} : dok = dat; // sun4u
235 {1'b0,1'b0,MEM_WRT} : dok = dat; // sun4u
236 {1'b0,1'b0,MSG_WRT} : dok = dat; // sun4u
237 {1'b0,1'b0,MSI_WRT} : dok = dat; // sun4u
238
239 {1'b0,1'b1,MEM_RDT} : dok = dat; // sun4v
240 {1'b0,1'b1,MEM_WRT} : dok = dat; // sun4v
241 {1'b0,1'b1,MSG_WRT} : dok = dat; // sun4v
242 {1'b0,1'b1,MSI_WRT} : dok = dat; // sun4v
243 {1'b0,1'b1,MEM_RDB} : dok = dat; // sun4v
244 {1'b0,1'b1,MEM_WRB} : dok = dat; // sun4v
245 {1'b0,1'b1,MSG_WRB} : dok = dat; // sun4v
246 {1'b0,1'b1,MSI_WRB} : dok = dat; // sun4v
247 default : dok = 1'b1;
248 endcase
249 end
250
251// write ok
252 always @ (tlb2pab_type or wrt) begin
253 case (tlb2pab_type) // synopsys parallel_case
254 MEM_WRT : wok = wrt;
255 MEM_WRB : wok = wrt;
256 MSG_WRT : wok = wrt;
257 MSG_WRB : wok = wrt;
258 MSI_WRT : wok = wrt;
259 MSI_WRB : wok = wrt;
260 default : wok = 1'b1;
261 endcase
262 end
263
264// valid ok
265 always @ (tlb2pab_type or vld) begin
266 case (tlb2pab_type) // synopsys parallel_case
267 MEM_RDT : vok = vld;
268 MEM_RDB : vok = vld;
269 MEM_WRT : vok = vld;
270 MEM_WRB : vok = vld;
271 MSG_WRT : vok = vld;
272 MSG_WRB : vok = vld;
273 MSI_WRT : vok = vld;
274 MSI_WRB : vok = vld;
275 default : vok = 1'b1;
276 endcase
277 end
278
279// ----------------------------------------------------------------------------
280// Sequential
281// ----------------------------------------------------------------------------
282 always @ (posedge clk) begin
283 if (!rst_l) begin
284 addr_ps3 <= 0;
285 aerr_ps3 <= 0;
286 type_ps3 <= 0;
287 end
288 else begin
289 addr_ps3 <= addr_ps2;
290 aerr_ps3 <= aerr_ps2;
291 type_ps3 <= tlb2pab_type;
292 end
293 end
294
295endmodule // dmu_mmu_pab