Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / common / vera / niu_gen_pio / niu_gen_pio.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: niu_gen_pio.vr
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#include <vera_defines.vrh>
36#include "cMesg.vrh"
37
38#ifdef NEP_HT
39//#include "cht_tasks.vrh"
40//#include "nep_ht_pio.vrh"
41#endif
42
43#ifdef N2
44#include "ncu_stub.vrh"
45#endif
46
47
48#ifdef NEP_SAT
49#include "ncu_stub.vrh"
50#endif
51
52#ifdef NEP_PCIE
53#include "Pcie_pkt_gen.vrh"
54extern Pcie_pkt_gen pcie_pkt;
55#endif
56
57#define TIME {get_time(HI), get_time(LO)}
58
59extern Mesg be_msg;
60
61class niu_gen_pio {
62
63 local bit [63:0] base_addr;
64 local bit addr_mode; // 0 - 32-bit addr, 1 - 64-bit addr
65 local bit data_mode; // 0 - 32-bit data, 1 - 64-bit data
66 local bit [ 2:0] chip_mode; // 000 - NEP_HT, 001 - NEP_PE, 010 - NEP_SAT
67 // 011 - N2_SAT, 100 - N2_IOS
68 local bit [63:0] address;
69 local bit [63:0] wr_data; // data for pio_wr
70 local bit [63:0] rd_data; // data returned from pio_rd
71 local bit pio_64_bit; // 1 - 64-bit 0 - 32-bit
72 local bit np_pios; // 1 - mimic non-posted PIOs 0 - posted pios (To emulate Opetron)
73 local bit drop_pios; // PIOs are dropped
74 local integer sema_pio_drv;// flag to prevent multiple use of database
75 // anticipate pending activity
76 local integer pio_32bit_sema_id;
77 local bit cfg_access; // 1 = cfg_access; 0 = register access
78 local bit posted_cmd; // 1 = posted cmds; 0 = non-posted cmds
79 local bit expect_pio_err;// = 1'b1, whether a pio_error expected.
80
81
82 #ifdef N2
83 Cncu_stub ncu_driver; // instance of ncu driver for N2
84 #endif
85
86 #ifdef NEP_SAT
87 Cncu_stub ncu_driver; // No PE block and PIOs are done through ncu_stub
88 #endif
89 integer read_status; // 0 - NACK
90 // 1 - ACK
91 //-1 - ERROR
92
93 task new();
94 task cfg_access_en (bit cfg) ;
95 task set_posted (bit posted_en) ;
96 task pio_wr( bit [63:0] addr,
97 bit [63:0] write_data,
98 (bit exp_pio_err = 1'b0) ) ;
99
100 task pio_rd( bit [63:0] addr,
101 var bit [63:0] read_data,
102 (bit [63:0] exp_data = 64'b0),
103 (bit [63:0] data_mask = 64'hFFFF_FFFF_FFFF_FFFF),
104 (bit exp_data_valid = 1'b0),
105 (bit exp_pio_err = 1'b0) );
106
107#ifdef NEP_PCIE
108
109 task pcie_cfg_wr(bit [2:0] func_no, bit [31:0] reg_data,
110 bit [7:0] reg_addr, bit[3:0] ext_reg_num,
111 (bit[3:0] first_be = 4'b1111));
112
113 task pcie_cfg_rd(bit [2:0] func_no, var bit [31:0] reg_data,
114 bit [7:0] reg_addr, bit[3:0] ext_reg_num,
115 (bit[3:0] first_be = 4'b1111));
116
117 task pio_wr_32( bit [63:0] addr,
118 bit [63:0] write_data,
119 (bit exp_pio_err = 1'b0) ) ; // To be used only in NEPTUNE mode
120
121 task pio_rd_32( bit [63:0] addr,
122 var bit [63:0] read_data,
123 (bit [63:0] exp_data = 64'b0),
124 (bit [63:0] data_mask = 64'hFFFF_FFFF),
125 (bit exp_data_valid = 1'b0),
126 (bit exp_pio_err = 1'b0) ); // To be used only in NEPTUNE mode
127#endif
128
129}
130
131task niu_gen_pio::new() {
132
133 #ifdef NEP_HT
134
135// Get the Base Address from command line
136 if ( get_plus_arg(CHECK, "HT_BASE_ADDR=") )
137 {
138 base_addr = get_plus_arg(HNUM, "HT_BASE_ADDR=") ;
139 be_msg.print(e_mesg_debug4, "read_nep_reg", "niu_gen_pio",
140 "HT_BASE_ADDR is set to %0h \n ", base_addr);
141 }
142 else {
143 base_addr = 64'h00000000_ff000000;
144 be_msg.print(e_mesg_debug4, "read_nep_reg", "niu_gen_pio",
145 "HT_BASE_ADDR is set to %0h \n ", base_addr);
146 }
147
148// ht_pio = new;
149 chip_mode = 3'b000;
150
151 #endif
152
153 #ifdef NEP_PCIE
154 if ( get_plus_arg(CHECK, "NEP_32_BIT") ){
155 pio_64_bit = 0;
156 printf("%d niu_gen_pio :: PIOs are set to NEP_32_BIT \n", TIME);
157 }
158 else {
159 pio_64_bit = 1;
160 printf("%d niu_gen_pio :: PIOs are set to NEP_64_BIT \n", TIME);
161 }
162
163 if ( get_plus_arg(CHECK, "NEP_NP_PIOS_AMD_OPETRON") ){
164 np_pios = 1;
165 printf("%d niu_gen_pio :: PIO Writes are issued followed by Zero length read NEP_NP_PIOS_AMD_OPETRON \n", TIME);
166 }
167 else {
168 np_pios = 0;
169 printf("%d niu_gen_pio :: PIO Writes are issued with out Zero length read \n", TIME);
170 }
171
172 if ( get_plus_arg(CHECK, "PCIE_DISABLE_INIT_CFG") ){
173 drop_pios = 1;
174 printf("%d WARNING niu_gen_pio :: PIOs are Dropped !!!!!! \n", TIME);
175 }
176 else {
177 drop_pios = 0;
178 }
179
180 #endif
181
182 #ifdef NEP_SAT
183
184 #endif
185
186 #ifdef NEP_SAT
187 ncu_driver = new(ncu_bind);
188 #endif
189
190 #ifdef N2
191 #ifdef IOS_ENV
192 ncu_driver = new();
193 #else
194 #ifdef N2_FC
195 // ncu_driver = new();
196 #else
197 ncu_driver = new(ncu_bind);
198 #endif
199 #endif
200 #endif
201
202 addr_mode = 1'b0;
203 data_mode = 1'b1;
204
205 sema_pio_drv = alloc(SEMAPHORE, 0, 1, 1);
206 pio_32bit_sema_id = alloc(SEMAPHORE, 0, 1, 1);
207 cfg_access = 1'b0;
208 posted_cmd = 1'b1;
209 expect_pio_err = 1'b0;
210 read_status = -1;
211}
212
213
214task niu_gen_pio::cfg_access_en(bit cfg_en)
215{
216 // set the cfg_access bit to enable HT config space accesses
217 cfg_access = cfg_en;
218
219 be_msg.print(e_mesg_info, "cfg_access_en", "niu_gen_pio",
220 "posted_cmd bit is set to %0b \n ", cfg_en);
221}
222
223task niu_gen_pio::set_posted(bit posted_en)
224{
225 // set the posted bit to enable Posted commands on HT bus
226 posted_cmd = posted_en;
227
228 be_msg.print(e_mesg_info, "set_posted", "niu_gen_pio",
229 "posted_cmd bit is set to %0b \n ", posted_en);
230}
231
232#ifdef NEP_PCIE
233
234task niu_gen_pio::pcie_cfg_wr(bit [2:0] func_no, bit [31:0] reg_data,
235 bit [7:0] reg_addr, bit[3:0] ext_reg_num,
236 (bit[3:0] first_be = 4'b1111)){
237 printf("%d niu_gen_pio::pcie_cfg_wr func_no = %x reg_addr = %x ext_reg_num = %x reg_data = %x \n", TIME, func_no, reg_addr, ext_reg_num, reg_data);
238
239 pcie_pkt.pcie_cfg_wr(func_no, reg_data, reg_addr, ext_reg_num, first_be) ;
240}
241
242task niu_gen_pio::pcie_cfg_rd(bit [2:0] func_no, var bit [31:0] reg_data,
243 bit [7:0] reg_addr, bit[3:0] ext_reg_num,
244 (bit[3:0] first_be = 4'b1111)){
245
246 printf("%d niu_gen_pio::pcie_cfg_rd func_no = %x reg_addr = %x ext_reg_num = %x \n", TIME, func_no, reg_addr, ext_reg_num);
247 pcie_pkt.pcie_cfg_rd(func_no, reg_data, reg_addr, ext_reg_num, first_be) ;
248 printf("%d niu_gen_pio::pcie_cfg_rd func_no = %x reg_addr = %x ext_reg_num = %x reg_data = %x \n", TIME, func_no, reg_addr, ext_reg_num, reg_data);
249}
250
251task niu_gen_pio::pio_wr_32( bit [63:0] addr,
252 bit [63:0] write_data,
253 (bit exp_pio_err = 1'b0) )
254{
255 bit [ 1:0] func_no;
256 bit [63:0] rd_data;
257
258
259 func_no = addr[26:25];
260 addr[26:24] = 3'b000;
261
262 pcie_pkt.pcie_pio_wr(func_no, addr, write_data, size_32b);
263 if(np_pios)
264 pcie_pkt.pcie_pio_flush_rd(func_no, addr, rd_data, size_32b);
265#ifdef NEP_DEBUG
266 printf("%d niu_gen_pio::pio_wr_32 func_no = %b addr = %x write_data = %x \n", TIME, func_no, addr, write_data);
267#endif
268}
269
270
271task niu_gen_pio::pio_rd_32( bit [63:0] addr,
272 var bit [63:0] read_data,
273 (bit [63:0] exp_data = 64'b0),
274 (bit [63:0] data_mask = 64'hFFFF_FFFF),
275 (bit exp_data_valid = 1'b0),
276 (bit exp_pio_err = 1'b0) )
277{
278
279 bit [1:0] func_no;
280
281 read_status = 1;
282 func_no = addr[26:25];
283 addr[26:24] = 3'b000;
284
285#ifdef NEP_DEBUG
286 printf("%d niu_gen_pio::pio_rd_32 func_no = %b addr = %x \n", TIME, func_no, addr);
287#endif
288
289 pcie_pkt.pcie_pio_rd(func_no, addr, read_data, size_32b );
290 read_data[63:32] = 32'b0;
291
292 if (exp_data_valid) {
293 if ((read_data & data_mask) !== (exp_data & data_mask)) {
294 be_msg.print(e_mesg_error, "niu_gen_pio::pio_rd_32", "Data miscompare ", "Addr : 0x%h expected: %h observed: %h mask: %h \n", addr, exp_data, read_data, data_mask);
295
296 }
297 }
298#ifdef NEP_DEBUG
299 printf("%d niu_gen_pio::pio_rd func_no = %b addr = %x read_data = %x \n", TIME, func_no, addr, read_data);
300#endif
301}
302
303#endif
304
305task niu_gen_pio::pio_wr( bit [63:0] addr,
306 bit [63:0] write_data,
307 (bit exp_pio_err = 1'b0) )
308{
309
310
311#ifdef NEP_PCIE
312
313 bit [ 1:0] func_no;
314 bit [63:0] tmp_write_data;
315 bit [63:0] tmp_addr, rd_data;
316
317
318 if(drop_pios) {
319 printf("%d WARNING niu_gen_pio::pio_wr Dropped !!!! addr = %x write_data = %x \n", TIME, addr, write_data);
320 return;
321 }
322
323 func_no = addr[26:25];
324 addr[26:24] = 3'b000;
325
326 if(pio_64_bit == 0){ // pios are done in 32-bit mode
327 semaphore_get(WAIT,pio_32bit_sema_id,1);
328 tmp_addr = addr;
329 tmp_write_data = {32'h0055_99aa, write_data[31:0]};
330 pcie_pkt.pcie_pio_wr(func_no, tmp_addr, tmp_write_data, size_32b);
331 printf("%d niu_gen_pio::pio_wr_32_bit func_no = %b addr = %x write_data = %x \n", TIME, func_no, tmp_addr, tmp_write_data);
332 if(np_pios)
333 pcie_pkt.pcie_pio_flush_rd(func_no, tmp_addr, rd_data, size_32b);
334 tmp_addr = addr + 4;
335 tmp_write_data = {32'h0055_99aa, write_data[63:32]};
336 pcie_pkt.pcie_pio_wr(func_no, tmp_addr, tmp_write_data, size_32b );
337 printf("%d niu_gen_pio::pio_wr_32_bit func_no = %b addr = %x write_data = %x \n", TIME, func_no, tmp_addr, tmp_write_data);
338 if(np_pios)
339 pcie_pkt.pcie_pio_flush_rd(func_no, tmp_addr, rd_data, size_32b);
340 semaphore_put(pio_32bit_sema_id,1);
341 }
342 else {
343 pcie_pkt.pcie_pio_wr(func_no, addr, write_data );
344 if(np_pios) { // Mimicking Opetron HT non-posted writes
345// printf("%d niu_gen_pio::pio_wr Calling pcie_pio_flush_rd \n", TIME);
346 pcie_pkt.pcie_pio_flush_rd(func_no, addr, rd_data, size_32b);
347 }
348 }
349
350
351#ifdef NEP_DEBUG
352 printf("%d niu_gen_pio::pio_wr func_no = %b addr = %x write_data = %x \n", TIME, func_no, addr, write_data);
353#endif
354
355#endif
356
357 #ifdef NEP_SAT
358
359 ncu_driver.write_data(addr[39:0],write_data);
360
361 #endif
362
363 #ifdef N2
364 #ifdef N2_FC
365 #else
366 ncu_driver.write_data(addr[39:0],write_data);
367 #endif
368 #endif
369
370 printf("%d niu_gen_pio::pio_wr addr = %x write_data = %x \n", TIME, addr, write_data);
371}
372
373
374task niu_gen_pio::pio_rd( bit [63:0] addr,
375 var bit [63:0] read_data,
376 (bit [63:0] exp_data = 64'b0),
377 (bit [63:0] data_mask = 64'hFFFF_FFFF_FFFF_FFFF),
378 (bit exp_data_valid = 1'b0),
379 (bit exp_pio_err = 1'b0) )
380{
381
382 #ifdef NEP_SAT
383 integer status;
384 ncu_driver.read_data(addr[39:0],read_data,status,exp_pio_err);
385 read_status = status;
386 #endif
387
388 #ifdef N2
389 #ifdef N2_FC
390 #else
391 integer status;
392 ncu_driver.read_data(addr[39:0],read_data,status,exp_pio_err);
393 read_status = status;
394 #endif
395 #endif
396
397
398#ifdef NEP_PCIE
399 bit [1:0] func_no;
400 bit [63:0] tmp_read_data1, tmp_read_data2;
401 bit [63:0] tmp_addr1, tmp_addr2;
402
403 read_status = 1;
404 if(drop_pios) {
405 printf("%d WARNING niu_gen_pio::pio_rd Dropped !!!! addr = %x \n", TIME, addr);
406 read_data = 64'hdead_dead;
407 return;
408 }
409
410 func_no = addr[26:25];
411 addr[26:24] = 3'b000;
412 printf("%d niu_gen_pio::pio_rd func_no = %b addr = %x \n", TIME, func_no, addr);
413
414 if(pio_64_bit == 0){// pios are done in 32-bit mode
415
416 semaphore_get(WAIT,pio_32bit_sema_id,1);
417 tmp_addr1 = addr;
418 pcie_pkt.pcie_pio_rd(func_no, tmp_addr1, tmp_read_data1, size_32b );
419
420 tmp_addr2 = addr + 4;
421 pcie_pkt.pcie_pio_rd(func_no, tmp_addr2, tmp_read_data2, size_32b);
422
423 read_data = {tmp_read_data2[31:0], tmp_read_data1[31:0]};
424 semaphore_put(pio_32bit_sema_id,1);
425 }
426 else
427 pcie_pkt.pcie_pio_rd(func_no, addr, read_data);
428
429
430#ifdef NEP_DEBUG
431 if(pio_64_bit == 0){
432 printf("%d niu_gen_pio::pio_rd_32bit func_no = %b addr = %x read_data = %x \n", TIME, func_no, tmp_addr1, tmp_read_data1);
433 printf("%d niu_gen_pio::pio_rd_32bit func_no = %b addr = %x read_data = %x \n", TIME, func_no, tmp_addr2, tmp_read_data2);
434 }
435 printf("%d niu_gen_pio::pio_rd func_no = %b addr = %x read_data = %x \n", TIME, func_no, addr, read_data);
436#endif
437
438#endif
439 if ( exp_data_valid) {
440 if ((read_data & data_mask) !== (exp_data & data_mask)) {
441 // printf("PIO: pio_rd failure: Data miscompare\n");
442 be_msg.print(e_mesg_error, "niu_gen_pio::pio_rd", "Data miscompare ", "Addr : 0x%h expected: %h observed: %h mask: %h \n", addr, exp_data, read_data, data_mask);
443
444 }
445 }
446 printf("%d niu_gen_pio::pio_rd addr = %0h read_data = %0h \n", TIME, addr, read_data);
447
448}