Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / dmu / rtl / dmu_tmu_dim_datapath.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: dmu_tmu_dim_datapath.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_tmu_dim_datapath (
36 clk,
37 rst_l,
38
39 // data path
40 k2y_buf_addr,
41 y2k_buf_data,
42 y2k_buf_dpar,
43
44 // DIU interface
45 tm2di_data,
46 tm2di_bmask,
47 tm2di_dpar,
48
49 // IMU interface
50 tm2im_data,
51
52 // talk to datafsm.v
53 idb_rptr_inc,
54 data_mux_select,
55 first_dwbe_dp,
56 last_dwbe_dp,
57 align_addr_dp,
58 end_addr_dp,
59 payld_len_is_one_dp,
60 ld_saved_data_dp
61
62 );
63
64 //synopsys sync_set_reset "rst_l"
65
66 // >>>>>>>>>>>>>>>>>>>>>>>>> Parameter Declarations <<<<<<<<<<<<<<<<<<<<<<<<<
67
68 // data_mux_select
69 parameter ONLY_VDB = 0,
70 LAST_VDB = 1,
71 MID_VDB = 2,
72 FRST_VDB = 3,
73 ZERO_FILL = 4;
74
75 // data_mux_select number
76 parameter DATA_MUX_NUM = 5;
77
78 // >>>>>>>>>>>>>>>>>>>>>>>>> Port Declarations <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
79
80 //------------------------------------------------------------------------
81 // Clock and Reset Signals
82 //------------------------------------------------------------------------
83 input clk;
84 input rst_l;
85
86 //------------------------------------------------------------------------
87 // data path to ILU
88 //------------------------------------------------------------------------
89 output [`FIRE_DLC_ITI_ADDR_WDTH-1:0] k2y_buf_addr; // read pointer to IDB
90 input [`FIRE_DLC_ITI_DATA_WDTH-1:0] y2k_buf_data; // 16-byte data
91 input [`FIRE_DLC_ITI_DPAR_WDTH-1:0] y2k_buf_dpar; // data parity
92
93
94 //------------------------------------------------------------------------
95 // DIU interface
96 //------------------------------------------------------------------------
97 output [`FIRE_DLC_TRD_DATA_WDTH-1:0] tm2di_data; // data to DIU
98 output [`FIRE_DLC_TRD_BMASK_WDTH-1:0] tm2di_bmask; // byte mask
99 output [`FIRE_DLC_TRD_DPAR_WDTH-1:0] tm2di_dpar; // data parity
100
101 //------------------------------------------------------------------------
102 // IMU interface
103 //------------------------------------------------------------------------
104 output [`FIRE_DLC_MDF_REC_WDTH-1:0] tm2im_data; // ingress
105
106 //------------------------------------------------------------------------
107 // talk to datafsm.v - data_mux_select encoding is
108 // { zero_fill, f_vdb, m_vdb, l_vdb, only_vdb}
109 //------------------------------------------------------------------------
110 input idb_rptr_inc;
111 input [DATA_MUX_NUM-1:0] data_mux_select;
112 input [3:0] first_dwbe_dp;
113 input [3:0] last_dwbe_dp;
114 input [3:2] align_addr_dp;
115 input [3:2] end_addr_dp;
116 input payld_len_is_one_dp;
117 input ld_saved_data_dp;
118
119 // >>>>>>>>>>>>>>>>>>>>>>>>> Data Type Declarations <<<<<<<<<<<<<<<<<<<<<<<<<
120
121 // ~~~~~~~~~~~~~~~~~~~~~~~~~ REGISTER - FLOPS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
122 reg [`FIRE_DLC_ITI_ADDR_WDTH-1:0] k2y_buf_addr; // read pointer to IDB
123
124 reg [127:0] current_data;
125 reg [3:0] current_dpar;
126
127 reg [95:0] saved_data;
128 reg [2:0] saved_dpar;
129
130 reg [127:0] tm2di_data;
131 reg [4:0] tm2di_dpar;
132 reg [15:0] tm2di_bmask;
133
134 reg msi_parity_err;
135
136 // ~~~~~~~~~~~~~~~~~~~~~~~~~ REGISTER - NON-FLOPS ~~~~~~~~~~~~~~~~~~~~~~~~
137 reg [127:0] n_tm2di_data;
138 reg [4:0] n_tm2di_dpar;
139 reg [15:0] n_tm2di_bmask;
140
141 reg [127:0] data_pattern;
142 reg [3:0] dpar_pattern;
143
144 reg [127:0] f_vdb_data;
145 reg [127:0] m_vdb_data;
146 wire [127:0] l_vdb_data;
147
148 reg [4:0] f_vdb_dpar;
149 reg [4:0] m_vdb_dpar;
150
151 reg [15:0] f_vdb_bmask;
152 reg [15:0] m_vdb_bmask;
153 reg [15:0] l_vdb_bmask;
154
155 // ~~~~~~~~~~~~~~~~~~~~~~~~~ NETS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
156 wire [127:0] only_vdb_data;
157 wire [4:0] l_vdb_dpar;
158 wire [4:0] only_vdb_dpar;
159 wire [15:0] only_vdb_bmask;
160
161 wire calc_parity;
162 wire n_msi_parity_err;
163
164 wire [3:0] first_dwbe; // bit swap of first_dwbe_dp
165 wire [3:0] last_dwbe; // bit swap of last_dwbe_dp
166
167
168 // >>>>>>>>>>>>>>>>>>>>>>>>> Function Declarations <<<<<<<<<<<<<<<<<<<<<<<<<<
169 function calc_dpar_bit; // odd parity
170 input [15:0] data;
171 begin
172 calc_dpar_bit = ~(^data[15:0]);
173 end
174 endfunction // calc_dpar_bit
175
176 // >>>>>>>>>>>>>>>>>>>>>>>>> RTL/Behavioral Model <<<<<<<<<<<<<<<<<<<<<<<<<<<
177
178 //------------------------------------------------------------------------
179 // bit swap of first_dwbe_dp and last_dwbe_dp
180 // set last_dwbe to 4'b1111 if payld_len_is_one_dp == 1'b1 for
181 // only_vdb_bmask formation, which is f_vdb_bmask & l_vdb_bmask
182 //------------------------------------------------------------------------
183 assign first_dwbe[3] = first_dwbe_dp[0];
184 assign first_dwbe[2] = first_dwbe_dp[1];
185 assign first_dwbe[1] = first_dwbe_dp[2];
186 assign first_dwbe[0] = first_dwbe_dp[3];
187
188 assign last_dwbe[3] = payld_len_is_one_dp ? 1'b1 : last_dwbe_dp[0];
189 assign last_dwbe[2] = payld_len_is_one_dp ? 1'b1 : last_dwbe_dp[1];
190 assign last_dwbe[1] = payld_len_is_one_dp ? 1'b1 : last_dwbe_dp[2];
191 assign last_dwbe[0] = payld_len_is_one_dp ? 1'b1 : last_dwbe_dp[3];
192
193 //------------------------------------------------------------------------
194 // parity check for first DW data and form tm2im_data
195 //------------------------------------------------------------------------
196
197 // calculate the first DW parity bit - odd parity
198 assign calc_parity = ~(^y2k_buf_data[127:96]);
199
200 assign n_msi_parity_err = (calc_parity ^ y2k_buf_dpar[3]); // fire uses odd parity
201
202// MSI-X assign tm2im_data = {msi_parity_err, current_data[127:112]};
203 assign tm2im_data = {msi_parity_err, current_data[127:96]};
204
205 //------------------------------------------------------------------------
206 // form f_vdb_data, dpar and bmask
207 //------------------------------------------------------------------------
208 always @ (align_addr_dp or current_data or current_dpar or first_dwbe)
209 begin
210 case (align_addr_dp)
211 2'b00:
212 begin
213 f_vdb_data = current_data;
214 f_vdb_dpar[4:1] = current_dpar;
215 f_vdb_bmask = {first_dwbe, 12'hfff};
216 end
217 2'b01:
218 begin
219 f_vdb_data = {32'b0, current_data[127:32]};
220 f_vdb_dpar[4:1] = {1'b1, current_dpar[3:1]};
221 f_vdb_bmask = {4'b0, first_dwbe, 8'hff};
222 end
223 2'b10:
224 begin
225 f_vdb_data = {64'b0, current_data[127:64]};
226 f_vdb_dpar[4:1] = {2'b11, current_dpar[3:2]};
227 f_vdb_bmask = {8'b0, first_dwbe, 4'hf};
228 end
229 2'b11:
230 begin
231 f_vdb_data = {96'b0, current_data[127:96]};
232 f_vdb_dpar[4:1] = {3'b111, current_dpar[3]};
233 f_vdb_bmask = {12'b0, first_dwbe};
234 end
235 endcase // case(align_addr_low_dp)
236 f_vdb_dpar[0] = calc_dpar_bit(f_vdb_bmask); // odd parity bit for bmask
237 end
238
239 //------------------------------------------------------------------------
240 // form m_vdb_data, dpar and bmask
241 //------------------------------------------------------------------------
242 always @ (align_addr_dp or current_data or current_dpar or
243 saved_data or saved_dpar)
244 begin
245 m_vdb_dpar[0] = 1'b1; // because the bmask is 16'hffff
246 m_vdb_bmask = 16'hffff;
247 case (align_addr_dp)
248 2'b00:
249 begin
250 m_vdb_data = current_data;
251 m_vdb_dpar[4:1] = current_dpar;
252 end
253 2'b01:
254 begin
255 m_vdb_data = {saved_data[31:0], current_data[127:32]};
256 m_vdb_dpar[4:1] = {saved_dpar[0], current_dpar[3:1]};
257 end
258 2'b10:
259 begin
260 m_vdb_data = {saved_data[63:0], current_data[127:64]};
261 m_vdb_dpar[4:1] = {saved_dpar[1:0], current_dpar[3:2]};
262 end
263 2'b11:
264 begin
265 m_vdb_data = {saved_data[95:0], current_data[127:96]};
266 m_vdb_dpar[4:1] = {saved_dpar[2:0], current_dpar[3]};
267 end
268 endcase // case(align_addr_dp)
269 end
270
271
272 //------------------------------------------------------------------------
273 // mux out patterns for l_vdb_data, dpar[4:1] and only_vdb_data, dpar[4:1]
274 //------------------------------------------------------------------------
275 always @ (end_addr_dp)
276 begin
277 case (end_addr_dp)
278 2'b00:
279 begin
280 data_pattern = {{32{1'b1}}, {32{1'b1}}, {32{1'b1}}, {32{1'b1}}};
281 dpar_pattern = {1'b0, 1'b0, 1'b0, 1'b0};
282 end
283 2'b01:
284 begin
285 data_pattern = {{32{1'b1}}, 32'b0, 32'b0, 32'b0};
286 dpar_pattern = {1'b0, 1'b1, 1'b1, 1'b1};
287 end
288 2'b10:
289 begin
290 data_pattern = {{32{1'b1}}, {32{1'b1}}, 32'b0, 32'b0};
291 dpar_pattern = {1'b0, 1'b0, 1'b1, 1'b1};
292 end
293 2'b11:
294 begin
295 data_pattern = {{32{1'b1}}, {32{1'b1}}, {32{1'b1}}, 32'b0};
296 dpar_pattern = {1'b0, 1'b0, 1'b0, 1'b1};
297 end
298 endcase // case(end_addr_dp)
299 end
300
301 //------------------------------------------------------------------------
302 // form l_vdb_data, dpar and bmask
303 //------------------------------------------------------------------------
304 always @ (end_addr_dp or last_dwbe)
305 begin
306 case (end_addr_dp)
307 2'b00:
308 begin
309 l_vdb_bmask = {12'hfff, last_dwbe};
310 end
311 2'b01:
312 begin
313 l_vdb_bmask = {last_dwbe, 12'b0};
314 end
315 2'b10:
316 begin
317 l_vdb_bmask = {4'hf, last_dwbe, 8'b0};
318 end
319 2'b11:
320 begin
321 l_vdb_bmask = {8'hff, last_dwbe, 4'b0};
322 end
323 endcase // case(end_addr_dp)
324 end
325
326 assign l_vdb_dpar[0] = calc_dpar_bit(l_vdb_bmask); // parity bit for bmask
327 assign l_vdb_data = m_vdb_data & data_pattern;
328 assign l_vdb_dpar[4:1] = m_vdb_dpar[4:1] | dpar_pattern;
329
330
331 //------------------------------------------------------------------------
332 // form only_vdb_data, dpar and bmask
333 //------------------------------------------------------------------------
334
335 assign only_vdb_bmask = f_vdb_bmask & l_vdb_bmask;
336 assign only_vdb_data = f_vdb_data & data_pattern;
337 assign only_vdb_dpar[4:1] = f_vdb_dpar[4:1] | dpar_pattern;
338 assign only_vdb_dpar[0] = calc_dpar_bit(only_vdb_bmask);
339
340 //------------------------------------------------------------------------
341 // mux out from zero-fill, f_vdb, m_vdb, l_vdb, only_vdb
342 //------------------------------------------------------------------------
343
344 always @ (data_mux_select or
345 f_vdb_data or m_vdb_data or
346 l_vdb_data or only_vdb_data or
347 f_vdb_dpar or m_vdb_dpar or
348 l_vdb_dpar or only_vdb_dpar or
349 f_vdb_bmask or m_vdb_bmask or
350 l_vdb_bmask or only_vdb_bmask )
351 begin
352 n_tm2di_data = 128'b0;
353 n_tm2di_bmask = 16'b0;
354 n_tm2di_dpar = 5'b11111;
355 case (1'b1) // synopsys parallel_case
356 data_mux_select[ZERO_FILL]:
357// 5'b10000: // zero-fill
358 begin
359 n_tm2di_data = 128'b0;
360 n_tm2di_bmask = 16'b0;
361 n_tm2di_dpar = 5'b11111;
362 end
363 data_mux_select[FRST_VDB]:
364// 5'b01000: // f_vdb
365 begin
366 n_tm2di_data = f_vdb_data;
367 n_tm2di_bmask = f_vdb_bmask;
368 n_tm2di_dpar = f_vdb_dpar;
369 end
370 data_mux_select[MID_VDB]:
371// 5'b00100: // m_vdb
372 begin
373 n_tm2di_data = m_vdb_data;
374 n_tm2di_bmask = m_vdb_bmask;
375 n_tm2di_dpar = m_vdb_dpar;
376 end
377 data_mux_select[LAST_VDB]:
378// 5'b00010: // l_vdb
379 begin
380 n_tm2di_data = l_vdb_data;
381 n_tm2di_bmask = l_vdb_bmask;
382 n_tm2di_dpar = l_vdb_dpar;
383 end
384 data_mux_select[ONLY_VDB]:
385// 5'b00001: // only_vdb
386 begin
387 n_tm2di_data = only_vdb_data;
388 n_tm2di_bmask = only_vdb_bmask;
389 n_tm2di_dpar = only_vdb_dpar;
390 end
391 endcase // case(1'b1)
392 end
393
394
395 //------------------------------------------------------------------------
396 // rptr to IDB
397 //------------------------------------------------------------------------
398 always @ (posedge clk)
399 if (!rst_l)
400 begin
401 k2y_buf_addr <= {`FIRE_DLC_ITI_ADDR_WDTH{1'b0}};
402 end
403 else if (idb_rptr_inc)
404 begin
405 k2y_buf_addr <= k2y_buf_addr + 1'b1;
406 end
407
408 //------------------------------------------------------------------------
409 // flops
410 //------------------------------------------------------------------------
411 always @ (posedge clk)
412 if(~rst_l) begin
413 current_data <= {128{1'b0}};
414 current_dpar <= {4{1'b0}};
415 saved_data <= {96{1'b0}};
416 saved_dpar <= {3{1'b0}};
417 msi_parity_err <= 1'b0;
418 tm2di_data <= {128{1'b0}};
419 tm2di_dpar <= {5{1'b0}};
420 tm2di_bmask <= {16{1'b0}};
421 end
422 else begin
423 current_data <= y2k_buf_data;
424 current_dpar <= y2k_buf_dpar;
425
426 if (ld_saved_data_dp) begin
427 saved_data <= current_data[95:0];
428 saved_dpar <= current_dpar[2:0];
429 end
430
431 msi_parity_err <= n_msi_parity_err;
432
433 tm2di_data <= n_tm2di_data;
434 tm2di_dpar <= n_tm2di_dpar;
435 tm2di_bmask <= n_tm2di_bmask;
436 end
437
438
439 // >>>>>>>>>>>>>>>>>>>>>>>>> Instantiations <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
440
441
442
443endmodule // dmu_tmu_dim_datapath
444
445
446
447