Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: dmu_imu_rds_msi.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_imu_rds_msi ( | |
36 | clk, | |
37 | rst_l, | |
38 | ||
39 | pipe_select_in, | |
40 | msi_data, | |
41 | msi_error, | |
42 | ||
43 | pipe_select_out, | |
44 | header_good, | |
45 | msi_eq_num, | |
46 | ||
47 | msi_not_enabled_error, | |
48 | ||
49 | sw_mondo_data_0, | |
50 | sw_mondo_data_1, | |
51 | ||
52 | csrbus_valid, | |
53 | csrbus_done, | |
54 | csrbus_mapped, | |
55 | csrbus_wr_data, | |
56 | csrbus_wr, | |
57 | csrbus_read_data, | |
58 | csrbus_addr, | |
59 | csrbus_src_bus, | |
60 | csrbus_acc_vio, | |
61 | ||
62 | // Static ID Sel | |
63 | ||
64 | j2d_instance_id | |
65 | ||
66 | ); | |
67 | ||
68 | ||
69 | //############################################################################ | |
70 | // PORT DECLARATIONS | |
71 | //############################################################################ | |
72 | ||
73 | //------------------------------------------------------------------------ | |
74 | // Clock and Reset Signals | |
75 | //------------------------------------------------------------------------ | |
76 | input clk; | |
77 | input rst_l; | |
78 | ||
79 | ||
80 | //------------------------------------------------------------------------ | |
81 | // Input Select Signals | |
82 | //------------------------------------------------------------------------ | |
83 | input pipe_select_in; | |
84 | input [7:0] msi_data; | |
85 | input msi_error; | |
86 | ||
87 | //------------------------------------------------------------------------ | |
88 | // Output Signals | |
89 | //------------------------------------------------------------------------ | |
90 | output pipe_select_out; | |
91 | output header_good; | |
92 | output [5:0] msi_eq_num; | |
93 | ||
94 | output msi_not_enabled_error; | |
95 | ||
96 | ||
97 | output [`FIRE_CSR_DATA_WIDTH-7:0] sw_mondo_data_0; | |
98 | output [`FIRE_CSR_DATA_WIDTH-1:0] sw_mondo_data_1; | |
99 | ||
100 | //------------------------------------------------------------------------ | |
101 | // PIO INTERFACE | |
102 | //------------------------------------------------------------------------ | |
103 | input csrbus_valid; | |
104 | output csrbus_done; | |
105 | output csrbus_mapped; | |
106 | ||
107 | input [`FIRE_CSR_DATA_WIDTH-1:0] csrbus_wr_data; | |
108 | input csrbus_wr; | |
109 | ||
110 | output [`FIRE_CSR_DATA_WIDTH-1:0] csrbus_read_data; | |
111 | ||
112 | input [`FIRE_CSR_ADDR_MAX_WIDTH-1:0] csrbus_addr; | |
113 | ||
114 | input [`FIRE_CSR_SRC_BUS_ID_WIDTH-1:0] csrbus_src_bus; | |
115 | output csrbus_acc_vio; | |
116 | ||
117 | ||
118 | input [`FIRE_J2D_INSTANCE_ID_WDTH-1:0] j2d_instance_id; | |
119 | ||
120 | ||
121 | //############################################################################ | |
122 | // PARAMETERS | |
123 | //############################################################################ | |
124 | ||
125 | ||
126 | ||
127 | ||
128 | //############################################################################ | |
129 | // SIGNAL DECLARATIONS | |
130 | //############################################################################ | |
131 | ||
132 | ||
133 | //************************************************** | |
134 | // Wire | |
135 | //************************************************** | |
136 | ||
137 | ||
138 | //-------------------------- | |
139 | // SW Signal for CSRTOOl | |
140 | //-------------------------- | |
141 | wire [7:0] sw_addr; // SW address comming out of CSRTool to address 256 rows | |
142 | wire sw_wr; // SW write enable signal | |
143 | wire sw_map_select; // SW Select signal comming from CSRTool to say a PIO acesss is happening; | |
144 | wire sw_clr_select; // SW Select signal comming from CSRTool to say a PIO acesss is happening; | |
145 | ||
146 | ||
147 | wire [63:0] sw_map_rd_data; // SW Data Bus from CSRTool | |
148 | wire [63:0] sw_clr_rd_data; // SW Data Bus from CSRTool | |
149 | ||
150 | wire [5:0] sw_eq_num_wr_data; // Portion of the data bus thats these bits use for eq num | |
151 | wire sw_v_wr_data; // Portion of the data bus thats these bits use for valid bit | |
152 | wire sw_ok_2_wr_wr_data; // Portion of the data bus thats these bits use for ok 2 wr bit | |
153 | ||
154 | wire [5:0] sw_eq_num_rd_data; // Portion of the data bus thats these bits use for eq num | |
155 | wire sw_v_rd_data; // Portion of the data bus thats these bits use for valid bit | |
156 | wire sw_ok_2_wr_rd_data; // Portion of the data bus thats these bits use for ok 2 wr bit | |
157 | ||
158 | ||
159 | //-------------------------- | |
160 | // HW Address Signal | |
161 | //-------------------------- | |
162 | wire [7:0] hw_msi_addr; // HW address comming out the lower 8 bits of msi data | |
163 | //wire header_error; | |
164 | wire n_header_good; | |
165 | wire [5:0] n_msi_eq_num; | |
166 | wire n_msi_not_enabled_error; | |
167 | wire hw_set_ok_2_wr; | |
168 | wire [255:0] n_msi_ok_2_wr; | |
169 | ||
170 | ||
171 | //************************************************** | |
172 | // Registers that Are Not Flops | |
173 | //************************************************** | |
174 | ||
175 | //************************************************** | |
176 | // Registers that Are Flops | |
177 | //************************************************** | |
178 | reg [255:0] msi_ok_2_wr; | |
179 | reg [255:0] msi_valid; | |
180 | reg [255:0] msi_eq_num_0; | |
181 | reg [255:0] msi_eq_num_1; | |
182 | reg [255:0] msi_eq_num_2; | |
183 | reg [255:0] msi_eq_num_3; | |
184 | reg [255:0] msi_eq_num_4; | |
185 | reg [255:0] msi_eq_num_5; | |
186 | ||
187 | reg [255:0] msi_clr_vector; | |
188 | reg [255:0] msi_set_vector; | |
189 | ||
190 | ||
191 | reg pipe_select_out; | |
192 | reg header_good; | |
193 | ||
194 | reg [5:0] msi_eq_num; | |
195 | reg msi_not_enabled_error; | |
196 | ||
197 | ||
198 | //############################################################################ | |
199 | // ZERO IN CHECKERS | |
200 | //############################################################################ | |
201 | ||
202 | ||
203 | ||
204 | //############################################################################ | |
205 | // COMBINATIONAL LOGIC | |
206 | //############################################################################ | |
207 | ||
208 | //-------------------------------------------------------------------------- | |
209 | // Mux the proper bits for the Read Paths | |
210 | // | |
211 | // - Since there are 256 possible MSI's we need to mux the proper one | |
212 | // from the SW address | |
213 | // | |
214 | // - Need to do this for all 3 components of the MSI state | |
215 | // - valid bit | |
216 | // - ok to write bit | |
217 | // - EQ number | |
218 | //-------------------------------------------------------------------------- | |
219 | assign sw_v_rd_data = msi_valid[sw_addr]; | |
220 | assign sw_ok_2_wr_rd_data = msi_ok_2_wr[sw_addr]; | |
221 | assign sw_eq_num_rd_data = {msi_eq_num_5[sw_addr],msi_eq_num_4[sw_addr], msi_eq_num_3[sw_addr], | |
222 | msi_eq_num_2[sw_addr],msi_eq_num_1[sw_addr], msi_eq_num_0[sw_addr]}; | |
223 | ||
224 | ||
225 | //-------------------------------------------------------------------------- | |
226 | // Build up the PIO Data Read Bus | |
227 | // | |
228 | // - We have two possible read data paths | |
229 | // - msi mapping register | |
230 | // - msi clear register | |
231 | //-------------------------------------------------------------------------- | |
232 | assign sw_map_rd_data = {sw_v_rd_data, sw_ok_2_wr_rd_data, 56'h0,sw_eq_num_rd_data}; | |
233 | assign sw_clr_rd_data = {1'b0, sw_ok_2_wr_rd_data, 62'h0}; | |
234 | ||
235 | ||
236 | //-------------------------------------------------------------------------- | |
237 | // Assign the HW signals used for MSI look up | |
238 | // | |
239 | // - We use the msi data as the address for the MSI lookup | |
240 | // | |
241 | // -In HW, if MSI was ok to write (1'b0) we need to set so it is not | |
242 | // ok to write next time through | |
243 | // - If header was good, neeed to set this bit | |
244 | //-------------------------------------------------------------------------- | |
245 | ||
246 | assign hw_msi_addr = msi_data; | |
247 | ||
248 | assign hw_set_ok_2_wr = n_header_good; | |
249 | ||
250 | //-------------------------------------------------------------------------- | |
251 | // Get the outputs Ready to be flopped | |
252 | // | |
253 | // - Determine if the Header is Good | |
254 | // - The header is good if: | |
255 | // - pipe stage was selected | |
256 | // - msi is valid (as set by SW) for msi now in pipe | |
257 | // - Done by the mux set up above | |
258 | // - Using hw_msi_addr as select line | |
259 | // - msi is ok to write (1'b0) | |
260 | // | |
261 | // - Determin if the Value of the EQ | |
262 | // - Done by the mux set up above | |
263 | // - Using hw_msi_addr as select line | |
264 | // | |
265 | //-------------------------------------------------------------------------- | |
266 | ||
267 | assign n_header_good = pipe_select_in & ~msi_ok_2_wr[hw_msi_addr] & msi_valid[hw_msi_addr] & ~msi_error; | |
268 | ||
269 | assign n_msi_eq_num = {msi_eq_num_5[hw_msi_addr],msi_eq_num_4[hw_msi_addr], msi_eq_num_3[hw_msi_addr], | |
270 | msi_eq_num_2[hw_msi_addr],msi_eq_num_1[hw_msi_addr], msi_eq_num_0[hw_msi_addr]}; | |
271 | ||
272 | assign n_msi_not_enabled_error = pipe_select_in & ~msi_valid[hw_msi_addr]; | |
273 | ||
274 | //############################################################################ | |
275 | // SEQUENTIAL LOGIC | |
276 | //############################################################################ | |
277 | ||
278 | //-------------------------------------------------------------------------- | |
279 | // MSI VAlID BITS | |
280 | // - 1 bit | |
281 | // - Says if MSI is enabled by software | |
282 | // - SW has Read/ Write Access | |
283 | // - HW has read Only | |
284 | //-------------------------------------------------------------------------- | |
285 | ||
286 | always @ (posedge clk) | |
287 | if (!rst_l) // At reset reset all of them to zero. | |
288 | msi_valid <= 256'h0; | |
289 | else if (sw_map_select & sw_wr) // If SW does a PIO Wr update the value with the new bit | |
290 | msi_valid[sw_addr] <= sw_v_wr_data; | |
291 | else | |
292 | msi_valid <= msi_valid; // Hold the Value. | |
293 | ||
294 | ||
295 | //-------------------------------------------------------------------------- | |
296 | // EQ NUMBER BITS | |
297 | // - 6 bit | |
298 | // - Says what EQ the MSI should go to | |
299 | // - SW has Read/ Write Access | |
300 | // - HW has read Only | |
301 | //-------------------------------------------------------------------------- | |
302 | ||
303 | always @ (posedge clk) | |
304 | if (!rst_l) // At reset reset all of them to zero. | |
305 | msi_eq_num_0 <= 256'h0; | |
306 | else if (sw_map_select & sw_wr) // If SW does a PIO Wr update the value with the new bit | |
307 | msi_eq_num_0[sw_addr] <= sw_eq_num_wr_data[0]; | |
308 | else | |
309 | msi_eq_num_0 <= msi_eq_num_0; // Hold the Value. | |
310 | ||
311 | ||
312 | always @ (posedge clk) | |
313 | if (!rst_l) // At reset reset all of them to zero. | |
314 | msi_eq_num_1 <= 256'h0; | |
315 | else if (sw_map_select & sw_wr) // If SW does a PIO Wr update the value with the new bit | |
316 | msi_eq_num_1[sw_addr] <= sw_eq_num_wr_data[1]; | |
317 | else | |
318 | msi_eq_num_1 <= msi_eq_num_1; // Hold the Value. | |
319 | ||
320 | ||
321 | always @ (posedge clk) | |
322 | if (!rst_l) // At reset reset all of them to zero. | |
323 | msi_eq_num_2 <= 256'h0; | |
324 | else if (sw_map_select & sw_wr) // If SW does a PIO Wr update the value with the new bit | |
325 | msi_eq_num_2[sw_addr] <= sw_eq_num_wr_data[2]; | |
326 | else | |
327 | msi_eq_num_2 <= msi_eq_num_2; // Hold the Value. | |
328 | ||
329 | always @ (posedge clk) | |
330 | if (!rst_l) // At reset reset all of them to zero. | |
331 | msi_eq_num_3 <= 256'h0; | |
332 | else if (sw_map_select & sw_wr) // If SW does a PIO Wr update the value with the new bit | |
333 | msi_eq_num_3[sw_addr] <= sw_eq_num_wr_data[3]; | |
334 | else | |
335 | msi_eq_num_3 <= msi_eq_num_3; // Hold the Value. | |
336 | ||
337 | always @ (posedge clk) | |
338 | if (!rst_l) // At reset reset all of them to zero. | |
339 | msi_eq_num_4 <= 256'h0; | |
340 | else if (sw_map_select & sw_wr) // If SW does a PIO Wr update the value with the new bit | |
341 | msi_eq_num_4[sw_addr] <= sw_eq_num_wr_data[4]; | |
342 | else | |
343 | msi_eq_num_4 <= msi_eq_num_4; // Hold the Value. | |
344 | ||
345 | always @ (posedge clk) | |
346 | if (!rst_l) // At reset reset all of them to zero. | |
347 | msi_eq_num_5 <= 256'h0; | |
348 | else if (sw_map_select & sw_wr) // If SW does a PIO Wr update the value with the new bit | |
349 | msi_eq_num_5[sw_addr] <= sw_eq_num_wr_data[5]; | |
350 | else | |
351 | msi_eq_num_5 <= msi_eq_num_5; // Hold the Value. | |
352 | ||
353 | ||
354 | ||
355 | ||
356 | //-------------------------------------------------------------------------- | |
357 | // MSI OK 2 WR BITS | |
358 | // - 1 bit | |
359 | // - Says if MSI is ok to write to EQ and not a duplicate | |
360 | // - O = OK to write 1 = not ok to write | |
361 | // - SW has Read / Write Access | |
362 | // - HW has Read / Write Access | |
363 | //-------------------------------------------------------------------------- | |
364 | ||
365 | always @ (sw_clr_select or sw_wr or sw_ok_2_wr_wr_data or sw_addr) | |
366 | begin | |
367 | msi_clr_vector = 256'h0; | |
368 | msi_clr_vector[sw_addr] = sw_clr_select & sw_wr & sw_ok_2_wr_wr_data; | |
369 | end | |
370 | ||
371 | always @ (hw_set_ok_2_wr or hw_msi_addr) | |
372 | begin | |
373 | msi_set_vector = 256'h0; | |
374 | msi_set_vector[hw_msi_addr] = hw_set_ok_2_wr; | |
375 | end | |
376 | ||
377 | ||
378 | assign n_msi_ok_2_wr = (msi_ok_2_wr | msi_set_vector) & ~msi_clr_vector; | |
379 | ||
380 | always @ (posedge clk) | |
381 | if (!rst_l) // At reset reset all of them to zero. | |
382 | msi_ok_2_wr <= 256'h0; | |
383 | else | |
384 | msi_ok_2_wr <= n_msi_ok_2_wr; // Hold the Value. | |
385 | ||
386 | ||
387 | //-------------------------------------------------------------------------- | |
388 | // FLOP THE OUTPUTS | |
389 | // | |
390 | //-------------------------------------------------------------------------- | |
391 | ||
392 | always @ (posedge clk) | |
393 | if (!rst_l) | |
394 | begin // At reset reset all of them to zero. | |
395 | pipe_select_out <= 1'b0; | |
396 | header_good <= 1'b0; | |
397 | msi_eq_num <= 6'h0; | |
398 | msi_not_enabled_error <= 1'b0; | |
399 | end | |
400 | else | |
401 | begin // At reset reset all of them to zero. | |
402 | pipe_select_out <= pipe_select_in; | |
403 | header_good <= n_header_good; | |
404 | msi_eq_num <= n_msi_eq_num; | |
405 | msi_not_enabled_error <= n_msi_not_enabled_error; | |
406 | end | |
407 | ||
408 | ||
409 | ||
410 | //############################################################################ | |
411 | // MODULE INSTANTIATIONS | |
412 | //############################################################################ | |
413 | ||
414 | ||
415 | dmu_imu_rds_msi_csr csr ( | |
416 | .clk (clk), | |
417 | .csrbus_valid (csrbus_valid), | |
418 | .csrbus_done (csrbus_done), | |
419 | .csrbus_mapped (csrbus_mapped), | |
420 | .csrbus_wr_data (csrbus_wr_data), | |
421 | .csrbus_wr (csrbus_wr), | |
422 | .csrbus_read_data (csrbus_read_data), | |
423 | .csrbus_addr (csrbus_addr), | |
424 | .rst_l (rst_l), | |
425 | ||
426 | .csrbus_src_bus (csrbus_src_bus), | |
427 | .csrbus_acc_vio (csrbus_acc_vio), | |
428 | .instance_id (j2d_instance_id), | |
429 | ||
430 | .ext_addr (sw_addr), | |
431 | .ext_wr (sw_wr), | |
432 | ||
433 | .msi_mapping_v_ext_wr_data (sw_v_wr_data), | |
434 | .msi_mapping_eqnum_ext_wr_data (sw_eq_num_wr_data), | |
435 | .msi_clear_reg_eqwr_n_ext_wr_data (sw_ok_2_wr_wr_data), | |
436 | ||
437 | .msi_mapping_ext_select (sw_map_select), | |
438 | .msi_mapping_ext_read_data (sw_map_rd_data), | |
439 | ||
440 | .msi_clear_reg_ext_select (sw_clr_select), | |
441 | .msi_clear_reg_ext_read_data (sw_clr_rd_data), | |
442 | ||
443 | ||
444 | .int_mondo_data_0_reg_data_hw_read (sw_mondo_data_0), | |
445 | .int_mondo_data_1_reg_hw_read (sw_mondo_data_1) | |
446 | ); | |
447 | ||
448 | ||
449 | ||
450 | endmodule |