Commit | Line | Data |
---|---|---|
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 ============================================ | |
35 | module 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 | ||
443 | endmodule // dmu_tmu_dim_datapath | |
444 | ||
445 | ||
446 | ||
447 |