Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: utility.h | |
5 | * Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved | |
6 | * 4150 Network Circle, Santa Clara, California 95054, U.S.A. | |
7 | * | |
8 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
9 | * | |
10 | * This program is free software; you can redistribute it and/or modify | |
11 | * it under the terms of the GNU General Public License as published by | |
12 | * the Free Software Foundation; version 2 of the License. | |
13 | * | |
14 | * This program is distributed in the hope that it will be useful, | |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | * GNU General Public License for more details. | |
18 | * | |
19 | * You should have received a copy of the GNU General Public License | |
20 | * along with this program; if not, write to the Free Software | |
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
22 | * | |
23 | * For the avoidance of doubt, and except that if any non-GPL license | |
24 | * choice is available it will apply instead, Sun elects to use only | |
25 | * the General Public License version 2 (GPLv2) at this time for any | |
26 | * software where a choice of GPL license versions is made | |
27 | * available with the language indicating that GPLv2 or any later version | |
28 | * may be used, or where a choice of which version of the GPL is applied is | |
29 | * otherwise unspecified. | |
30 | * | |
31 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
32 | * CA 95054 USA or visit www.sun.com if you need additional information or | |
33 | * have any questions. | |
34 | * | |
35 | * | |
36 | * ========== Copyright Header End ============================================ | |
37 | */ | |
38 | #include "vcsuser.h" | |
39 | #include "acc_user.h" | |
40 | #include <malloc.h> | |
41 | #include <stdio.h> | |
42 | #include <string.h> | |
43 | ||
44 | #define BUFFER 1024 | |
45 | ||
46 | typedef struct f_state_node{ | |
47 | union{ | |
48 | char cval[144];//total number of dimms | |
49 | int ival[36]; | |
50 | } aval; | |
51 | char bval[144]; | |
52 | }state_node, *f_state_ptr; | |
53 | // define avl tree data structure for memory model | |
54 | typedef struct avl_node{ | |
55 | long long addr; | |
56 | f_state_ptr val; | |
57 | int state, balance; | |
58 | char* comment; | |
59 | struct avl_node *leftPtr; | |
60 | struct avl_node *rightPtr; | |
61 | } *avl_node_ptr; | |
62 | ||
63 | // define avl data structure. | |
64 | typedef struct avl_conf_node{ | |
65 | avl_node_ptr data; | |
66 | int dram; | |
67 | int size, d_size; | |
68 | int word, d_word; | |
69 | int addr; //how many bits | |
70 | int half_byte;//how many half_byte; | |
71 | } *avl_conf_ptr; | |
72 | avl_node_ptr search_node(avl_node_ptr* t_ptr, long long* addr); | |
73 | /*------------------------------------------------------------------------------- | |
74 | create new avl_node. | |
75 | state bit : | |
76 | 0 dirty, | |
77 | 1 valid | |
78 | 2 clean | |
79 | --------------------------------------------------------------------------------*/ | |
80 | avl_node_ptr create_avl_node(long long addr, f_state_ptr val){ | |
81 | avl_node_ptr n_ptr; | |
82 | f_state_ptr t_tmp; | |
83 | ||
84 | n_ptr = (avl_node_ptr)malloc(sizeof(struct avl_node)); | |
85 | if(n_ptr != 0){ | |
86 | t_tmp = (f_state_ptr)malloc(sizeof(struct f_state_node)); | |
87 | t_tmp[0] = val[0]; | |
88 | n_ptr->val = t_tmp; | |
89 | n_ptr->state = 2; | |
90 | n_ptr->addr = addr; | |
91 | n_ptr->balance = 0; | |
92 | n_ptr->leftPtr = 0; | |
93 | n_ptr->rightPtr= 0; | |
94 | } | |
95 | else { | |
96 | io_printf((char *)"Error : Out of memory\n"); | |
97 | tf_dofinish(); | |
98 | } | |
99 | return n_ptr; | |
100 | } | |
101 | /*------------------------------------------------------------------------------- | |
102 | check difference. | |
103 | --------------------------------------------------------------------------------*/ | |
104 | int difference(avl_node_ptr t_ptr){ | |
105 | int left, right; | |
106 | left = -1;right = -1; | |
107 | ||
108 | if(t_ptr == 0)return 0; | |
109 | if(t_ptr->leftPtr != 0)left = t_ptr->leftPtr->balance; | |
110 | if(t_ptr->rightPtr != 0)right = t_ptr->rightPtr->balance; | |
111 | return (left - right); | |
112 | } | |
113 | /*------------------------------------------------------------------------------- | |
114 | rotate nodes pointed to by pivotptr. | |
115 | pivotptr: leftPtr. | |
116 | --------------------------------------------------------------------------------*/ | |
117 | void rotate_right(avl_node_ptr* pivot_ptr){ | |
118 | avl_node_ptr t_ptr; | |
119 | ||
120 | if((*pivot_ptr) != 0){ | |
121 | if((*pivot_ptr)->leftPtr != 0){ | |
122 | t_ptr = (*pivot_ptr)->leftPtr; | |
123 | (*pivot_ptr)->leftPtr = t_ptr->rightPtr; | |
124 | t_ptr->rightPtr = *pivot_ptr; | |
125 | *pivot_ptr = t_ptr; // t_ptr becomes new root of this whole subtree. | |
126 | } | |
127 | } | |
128 | } | |
129 | /*------------------------------------------------------------------------------- | |
130 | rotate nodes pointed to by pivotptr. | |
131 | pivotptr: leftPtr. | |
132 | --------------------------------------------------------------------------------*/ | |
133 | void rotate_left(avl_node_ptr* pivot_ptr){ | |
134 | avl_node_ptr t_ptr; | |
135 | ||
136 | if((*pivot_ptr) != 0){ | |
137 | if((*pivot_ptr)->rightPtr != 0){ | |
138 | t_ptr = (*pivot_ptr)->rightPtr; | |
139 | (*pivot_ptr)->rightPtr = t_ptr->leftPtr; | |
140 | t_ptr->leftPtr = *pivot_ptr; | |
141 | *pivot_ptr = t_ptr; // t_ptr becomes new root of this whole subtree. | |
142 | } | |
143 | } | |
144 | } | |
145 | /*------------------------------------------------------------------------------- | |
146 | rotate nodes pointed to by pivotptr. | |
147 | pivotptr: leftPtr. | |
148 | --------------------------------------------------------------------------------*/ | |
149 | void balance_right(avl_node_ptr* t_ptr){ | |
150 | ||
151 | if(difference((*t_ptr)->rightPtr) == 0){ | |
152 | rotate_left(&(*t_ptr)); | |
153 | (*t_ptr)->balance--; | |
154 | (*t_ptr)->leftPtr->balance++; | |
155 | ||
156 | } | |
157 | else if(difference((*t_ptr)->rightPtr) < 0){ | |
158 | rotate_left(&(*t_ptr)); | |
159 | (*t_ptr)->leftPtr->balance -= 2; | |
160 | } | |
161 | else{ | |
162 | rotate_right(&(*t_ptr)->rightPtr); | |
163 | rotate_left(&(*t_ptr)); | |
164 | (*t_ptr)->balance++; | |
165 | (*t_ptr)->leftPtr->balance -= 2; | |
166 | (*t_ptr)->rightPtr->balance--; | |
167 | } | |
168 | } | |
169 | /*------------------------------------------------------------------------------- | |
170 | rotate nodes pointed to by pivotptr. | |
171 | pivotptr: rightPtr. | |
172 | --------------------------------------------------------------------------------*/ | |
173 | void balance_left(avl_node_ptr* t_ptr){ | |
174 | ||
175 | if(difference((*t_ptr)->leftPtr) == 0){ | |
176 | rotate_right(&(*t_ptr)); | |
177 | (*t_ptr)->balance--; | |
178 | (*t_ptr)->rightPtr->balance++; | |
179 | ||
180 | } | |
181 | else if(difference((*t_ptr)->leftPtr) < 0){ | |
182 | rotate_right(&(*t_ptr)); | |
183 | (*t_ptr)->rightPtr->balance -= 2; | |
184 | } | |
185 | else{ | |
186 | rotate_left(&(*t_ptr)->leftPtr); | |
187 | rotate_right(&(*t_ptr)); | |
188 | (*t_ptr)->balance++; | |
189 | (*t_ptr)->rightPtr->balance -= 2; | |
190 | (*t_ptr)->leftPtr->balance--; | |
191 | } | |
192 | } | |
193 | /*------------------------------------------------------------------------------- | |
194 | update balance. | |
195 | --------------------------------------------------------------------------------*/ | |
196 | void fixFB(avl_node_ptr t_ptr){ | |
197 | int left, right; | |
198 | left = -1;right = -1; | |
199 | ||
200 | if(t_ptr->leftPtr != 0)left = t_ptr->leftPtr->balance; | |
201 | if(t_ptr->rightPtr != 0)right = t_ptr->rightPtr->balance; | |
202 | if(left > right)t_ptr->balance = left + 1; | |
203 | else t_ptr->balance = right + 1; | |
204 | } | |
205 | /*------------------------------------------------------------------------------- | |
206 | write data into memory. | |
207 | --------------------------------------------------------------------------------*/ | |
208 | int insert_avl_node(avl_node_ptr *t_ptr, long long* addr, f_state_ptr val){ | |
209 | ||
210 | if((*t_ptr) == 0){ | |
211 | (*t_ptr) = create_avl_node(*addr, val); // add new node to tree. | |
212 | if((*t_ptr) == 0){ | |
213 | io_printf((char *)"Error : Out of Memory\n"); | |
214 | tf_dofinish(); | |
215 | } | |
216 | } | |
217 | else if(*addr == (*t_ptr)->addr)return 1; | |
218 | else{ | |
219 | if(*addr < (*t_ptr)->addr)insert_avl_node(&(*t_ptr)->leftPtr, addr, val); | |
220 | else insert_avl_node(&(*t_ptr)->rightPtr, addr, val); | |
221 | fixFB(*t_ptr); | |
222 | if(difference(*t_ptr) > 1) balance_left (&(*t_ptr)); | |
223 | else if(difference(*t_ptr) < -1) balance_right(&(*t_ptr)); | |
224 | } | |
225 | return 0; | |
226 | } | |
227 | /*------------------------------------------------------------------------------- | |
228 | search address on avl. | |
229 | --------------------------------------------------------------------------------*/ | |
230 | avl_node_ptr search_node(avl_node_ptr* t_ptr, long long* addr){ | |
231 | ||
232 | if((*t_ptr)->addr == *addr){ | |
233 | return *t_ptr; | |
234 | } | |
235 | if((*t_ptr)->addr > *addr){ | |
236 | if((*t_ptr)->leftPtr == 0){ | |
237 | return 0; | |
238 | } | |
239 | return search_node(&(*t_ptr)->leftPtr, addr); | |
240 | } | |
241 | else{ | |
242 | if((*t_ptr)->rightPtr == 0){ | |
243 | return 0; | |
244 | } | |
245 | return search_node(&(*t_ptr)->rightPtr, addr); | |
246 | } | |
247 | } | |
248 | /*------------------------------------------------------------------------------- | |
249 | convert unsigned int to char array | |
250 | --------------------------------------------------------------------------------*/ | |
251 | long long mask_upbit(int width, long long val){ | |
252 | long long mask; | |
253 | ||
254 | mask = ~0x0; | |
255 | mask <<= width; | |
256 | mask = ~mask; | |
257 | val = (val) & mask; | |
258 | return val; | |
259 | } | |
260 | /*------------------------------------------------------------------------------- | |
261 | traverse an avl-tree by visitint a left subtree. | |
262 | --------------------------------------------------------------------------------*/ | |
263 | void in_order(avl_node_ptr* t_ptr, FILE* fp, int* shft, int* size){ | |
264 | int i, num; | |
265 | if(*t_ptr != 0){ | |
266 | in_order(&(*t_ptr)->leftPtr, fp, shft, size); | |
267 | if(*shft > 0){ | |
268 | fprintf(fp, "way -> %x ", mask_upbit(64 - (*shft), (*t_ptr)->addr >> (*shft))); | |
269 | fprintf(fp, "index -> %02x data -> ", mask_upbit(*shft, (*t_ptr)->addr)); | |
270 | num = (*size) / 32;if(((*size) % 32) != 0)num++; | |
271 | for(i = num - 1;i >= 0;i--)fprintf(fp, "%x", (*t_ptr)->val[i].aval); | |
272 | fprintf(fp, "\n"); | |
273 | } | |
274 | else{ | |
275 | fprintf(fp, "address -> %016llx data -> ", (*t_ptr)->addr); | |
276 | num = (*size) / 32;if(((*size) % 32) != 0)num++; | |
277 | for(i = num - 1;i >= 0;i--)fprintf(fp, "%x", (*t_ptr)->val[i].aval); | |
278 | fprintf(fp, "\n"); | |
279 | } | |
280 | in_order(&(*t_ptr)->rightPtr, fp, shft, size); | |
281 | } | |
282 | } | |
283 | /*------------------------------------------------------------------------------- | |
284 | utility routines. | |
285 | --------------------------------------------------------------------------------*/ | |
286 | /*------------------------------------------------------------------------------- | |
287 | remove leading space or tab. | |
288 | if found carriage return, return -1 to indicate anenpty string. | |
289 | --------------------------------------------------------------------------------*/ | |
290 | int remove_leading_space(char* buf, int index, int max){ | |
291 | while((index < max) && (buf[index] == ' ' || buf[index] == '\t'))index++; | |
292 | return buf[index] == '\n' || buf[index] == '\0' ? -1 : index; | |
293 | } | |
294 | /*------------------------------------------------------------------------------- | |
295 | make address from alpha string. | |
296 | --------------------------------------------------------------------------------*/ | |
297 | long long ato_long(char* buf, int* index){ | |
298 | long long val; | |
299 | val = 0; | |
300 | while((buf[*index] != ' ') && (buf[*index] != '\0') && (buf[*index] != '\n')){ | |
301 | val <<= 4; | |
302 | val |= buf[*index] > '9' ? ((buf[*index] & 0xf) + 9) : buf[*index] & 0xf; | |
303 | (*index)++; | |
304 | } | |
305 | return val; | |
306 | } | |
307 | /*------------------------------------------------------------------------------- | |
308 | convert ascii to hex array. | |
309 | --------------------------------------------------------------------------------*/ | |
310 | void convert_a2b(char* buf, int* index, char* d_buf, int* d_ind, int* num_bit){ | |
311 | ||
312 | while((buf[*index] != ' ') && (buf[*index] != '\0') && (buf[*index] != '\n')){ | |
313 | d_buf[*d_ind] = buf[*index] > '9' ? ((buf[*index] & 0xf) + 9) : buf[*index] & 0xf; | |
314 | (*index)++; | |
315 | (*d_ind)++; | |
316 | *num_bit += 4; | |
317 | } | |
318 | } | |
319 | /*------------------------------------------------------------------------------- | |
320 | convert unsigned int to char array | |
321 | --------------------------------------------------------------------------------*/ | |
322 | unsigned int mask_low_bits(int mask_num, int num, unsigned int val){ | |
323 | unsigned int mask; | |
324 | ||
325 | val >>= (num - mask_num);// shift and drop bits. | |
326 | mask = ~0x0; | |
327 | mask <<= mask_num; | |
328 | mask = ~mask; | |
329 | val = val & mask; | |
330 | return val; | |
331 | } | |
332 | /*------------------------------------------------------------------------------- | |
333 | convert ascii to hex. | |
334 | --------------------------------------------------------------------------------*/ | |
335 | void shift_left(unsigned int o_data, char* val, int num){ | |
336 | *val = (o_data << num) | *val; | |
337 | } | |
338 | ||
339 | /*------------------------------------------------------------------------------- | |
340 | calculate tag. | |
341 | --------------------------------------------------------------------------------*/ | |
342 | void tag_address(long long addr, long long * way, unsigned int* tag_data){ | |
343 | ||
344 | *way = addr & 0xfffff; | |
345 | *tag_data = (addr >> 16) & 0xffffff; //[39:16] | |
346 | } | |
347 | /*------------------------------------------------------------------------------- | |
348 | slam meory. | |
349 | slam_memory(data pointer, size, argument location, valid); | |
350 | --------------------------------------------------------------------------------*/ | |
351 | void slam_memory(f_state_ptr val, int size, int arg_loc, int valid, int loc){ | |
352 | char* avalPtr, *bvalPtr; | |
353 | int word, ind, groups; | |
354 | s_tfnodeinfo node_info; | |
355 | s_tfexprinfo expr_info; | |
356 | tf_nodeinfo(arg_loc, &node_info); | |
357 | switch(node_info.node_type){ | |
358 | case TF_MEMORY_NODE : | |
359 | tf_nodeinfo(arg_loc, &node_info); | |
360 | word = node_info.node_ngroups * 2; | |
361 | ind = 0; | |
362 | for(size = 0;size < node_info.node_mem_size;size++){ | |
363 | avalPtr = node_info.node_value.memoryval_p + size * word; | |
364 | bvalPtr = avalPtr + node_info.node_ngroups; | |
365 | for(groups = node_info.node_ngroups - 1; groups >= 0;groups--){ | |
366 | avalPtr[groups] = valid ? val[ind].aval.cval[loc] : 0 ; //0xff; | |
367 | bvalPtr[groups] = valid ? val[ind].bval[loc] : 0; //0xff; | |
368 | ind++; | |
369 | } | |
370 | } | |
371 | break; | |
372 | case TF_REG_NODE : | |
373 | tf_exprinfo(arg_loc, &expr_info); | |
374 | for(groups = 0; groups < expr_info.expr_ngroups ; groups++){ | |
375 | expr_info.expr_value_p[groups].avalbits = valid ? val[groups].aval.cval[loc] : 0xffffffff; | |
376 | expr_info.expr_value_p[groups].bvalbits = valid ? val[groups].bval[loc] : 0xffffffff; | |
377 | } | |
378 | tf_propagatep(arg_loc); | |
379 | break; | |
380 | case TF_NETVECTOR_NODE : | |
381 | tf_exprinfo(arg_loc, &expr_info); | |
382 | for(groups = 0; groups < expr_info.expr_ngroups ; groups++){ | |
383 | expr_info.expr_value_p[groups].avalbits = valid ? val[groups].aval.cval[loc] : 0xffffffff; | |
384 | expr_info.expr_value_p[groups].bvalbits = valid ? val[groups].bval[loc] : 0xffffffff; | |
385 | } | |
386 | tf_propagatep(arg_loc); | |
387 | break; | |
388 | } | |
389 | } | |
390 | ||
391 | /*------------------------------------------------------------------------------- | |
392 | slam meory. | |
393 | slam_memory(data pointer, size, argument location, valid); | |
394 | --------------------------------------------------------------------------------*/ | |
395 | void dump_memory(f_state_ptr val, int size, int arg_loc, int loc){ | |
396 | char* avalPtr, *bvalPtr; | |
397 | int word, ind, groups; | |
398 | s_tfnodeinfo node_info; | |
399 | ||
400 | tf_nodeinfo(arg_loc, &node_info); | |
401 | switch(node_info.node_type){ | |
402 | case TF_MEMORY_NODE : | |
403 | word = node_info.node_ngroups * 2; | |
404 | ind = 0; | |
405 | for(size = 0;size < node_info.node_mem_size;size++){ | |
406 | avalPtr = node_info.node_value.memoryval_p + size * word; | |
407 | bvalPtr = avalPtr + node_info.node_ngroups; | |
408 | } | |
409 | break; | |
410 | case TF_REG_NODE : | |
411 | for(groups = 0; groups < node_info.node_ngroups ; groups++){ | |
412 | val[groups].aval.cval[loc] = node_info.node_value.vecval_p[groups].avalbits; | |
413 | val[groups].bval[loc] = node_info.node_value.vecval_p[groups].bvalbits; | |
414 | } | |
415 | break; | |
416 | case TF_NETVECTOR_NODE : | |
417 | for(groups = 0; groups < node_info.node_ngroups ; groups++){ | |
418 | val[groups].aval.cval[loc] = node_info.node_value.vecval_p[groups].avalbits; | |
419 | val[groups].bval[loc] = node_info.node_value.vecval_p[groups].bvalbits; | |
420 | } | |
421 | break; | |
422 | } | |
423 | } | |
424 | /*------------------------------------------------------------------------------- | |
425 | convert unsigned int to char array | |
426 | --------------------------------------------------------------------------------*/ | |
427 | void mask_value(int width, long long* val){ | |
428 | long long mask; | |
429 | ||
430 | mask = ~0x0; | |
431 | mask <<= width; | |
432 | mask = ~mask; | |
433 | *val = (*val) & mask; | |
434 | } | |
435 | /*------------------------------------------------------------------------------- | |
436 | create new avl_node. | |
437 | ||
438 | state bit : | |
439 | 0 dirty, | |
440 | 1 valid | |
441 | 2 clean | |
442 | --------------------------------------------------------------------------------*/ | |
443 | avl_node_ptr create_event_node(long long addr, f_state_ptr val, char* buf, int size){ | |
444 | avl_node_ptr n_ptr; | |
445 | f_state_ptr t_tmp; | |
446 | int i; | |
447 | char *cmt; | |
448 | ||
449 | n_ptr = (avl_node_ptr)malloc(sizeof(struct avl_node)); | |
450 | if(n_ptr != 0){ | |
451 | t_tmp = (f_state_ptr)malloc(sizeof(struct f_state_node) * 1); | |
452 | if(strlen(buf)){ | |
453 | cmt = (char*)malloc(strlen(buf)); | |
454 | strcpy(cmt, buf); | |
455 | } | |
456 | else cmt = 0; | |
457 | for(i = 0; i < size;i++)t_tmp[i] = val[i]; | |
458 | n_ptr->comment = cmt; | |
459 | n_ptr->val = t_tmp; | |
460 | n_ptr->state = 2; | |
461 | n_ptr->addr = addr; | |
462 | n_ptr->balance = 0; | |
463 | n_ptr->leftPtr = 0; | |
464 | n_ptr->rightPtr = 0; | |
465 | } | |
466 | return n_ptr; | |
467 | } | |
468 | /*------------------------------------------------------------------------------- | |
469 | write data into memory. | |
470 | --------------------------------------------------------------------------------*/ | |
471 | int insert_event_node(avl_node_ptr *t_ptr, long long* addr, | |
472 | f_state_ptr val, char* buf, int* size){ | |
473 | ||
474 | if((*t_ptr) == 0){ | |
475 | (*t_ptr) = create_event_node(*addr, val, buf, *size); // add new node to tree. | |
476 | if((*t_ptr) == 0){ | |
477 | io_printf((char *)"Error : Out of memory\n"); | |
478 | tf_dofinish(); | |
479 | } | |
480 | } | |
481 | else if(*addr == (*t_ptr)->addr){ | |
482 | int i;//update memory | |
483 | for(i = 0; i < *size;i++)(*t_ptr)->val[i] = val[i]; | |
484 | return 1; | |
485 | } | |
486 | else{ | |
487 | if(*addr < (*t_ptr)->addr)insert_event_node(&(*t_ptr)->leftPtr, addr, val, buf, size); | |
488 | else insert_event_node(&(*t_ptr)->rightPtr, addr, val, buf, size); | |
489 | fixFB(*t_ptr); | |
490 | if(difference(*t_ptr) > 1) balance_left (&(*t_ptr)); | |
491 | else if(difference(*t_ptr) < -1) balance_right(&(*t_ptr)); | |
492 | } | |
493 | return 0; | |
494 | } | |
495 | /*------------------------------------------------------------------------------- | |
496 | read event file | |
497 | --------------------------------------------------------------------------------*/ | |
498 | void get_event(avl_conf_ptr a_tree, FILE *fp){ | |
499 | long long addr; | |
500 | char buf[BUFFER], d_buf[BUFFER]; | |
501 | int ind, d_ind, num_bit, type, reg, size; | |
502 | state_node f_val[2]; | |
503 | num_bit = 0; | |
504 | size = 1; | |
505 | while(fgets(buf, BUFFER, fp)){ | |
506 | ind = remove_leading_space(buf, 0, BUFFER); | |
507 | if(ind < 0)continue;//empty string | |
508 | d_ind = 0; | |
509 | if(strncmp(buf,"trig_pc_d", 9) == 0){ | |
510 | strcpy(buf, buf + 10); | |
511 | for(ind = 0; ind < strlen(buf); ind++) | |
512 | if(buf[ind] == '-' || | |
513 | buf[ind] == '>' || | |
514 | buf[ind] == ',' || | |
515 | buf[ind] == ')' || | |
516 | buf[ind] == '(')buf[ind] = ' '; | |
517 | ind = remove_leading_space(buf, 0, BUFFER); | |
518 | convert_a2b(buf, &ind, d_buf, &d_ind, &num_bit); | |
519 | strcpy(buf, buf + ind);//remove dummy argument | |
520 | ind = remove_leading_space(buf, 0, BUFFER); | |
521 | strcpy(buf, buf + ind);//remove hexa indicator | |
522 | for(ind = 0; ind < strlen(buf); ind++) | |
523 | if(((buf[ind] == '\'') && (buf[ind+1] == 'h')) || | |
524 | ((buf[ind] == '0') && (buf[ind+1] == 'x'))) { | |
525 | ind++; | |
526 | strcpy(buf, buf + ind); | |
527 | } | |
528 | //get pc value | |
529 | ind = 0; | |
530 | addr = ato_long(buf, &ind); | |
531 | strcpy(buf, buf + ind); | |
532 | //what is the event? | |
533 | ind = remove_leading_space(buf, 0, BUFFER); | |
534 | strcpy(buf, buf + ind); | |
535 | type = 0; | |
536 | if(strncmp(buf,"printhex", 8) == 0)type = 1; | |
537 | if(strncmp(buf,"printdec", 8) == 0)type = 2; | |
538 | if(type == 0)continue;//find verilog event only | |
539 | strcpy(buf, buf + 8); | |
540 | ind = remove_leading_space(buf, 0, BUFFER); | |
541 | strcpy(buf, buf + ind); | |
542 | if(buf[0] == '"'){ | |
543 | strcpy(buf, buf + 1);//remove the leading " | |
544 | //get comments | |
545 | for(ind = 0; ind < strlen(buf);ind++) | |
546 | if((buf[ind] != '"') && | |
547 | (buf[ind] != '\0')&& | |
548 | (buf[ind] != '\n'))d_buf[ind] = buf[ind]; | |
549 | else break; | |
550 | if(buf[ind] == '\0' || | |
551 | buf[ind] == '\n' )continue; | |
552 | strcpy(buf, buf + ind + 1);//remove the tailing " | |
553 | ind = remove_leading_space(buf, 0, BUFFER); | |
554 | strcpy(buf, buf + ind); | |
555 | } | |
556 | else d_buf[0] = '\0'; | |
557 | //get register number | |
558 | if(buf[0] == '%'){ | |
559 | switch(buf[1]){ | |
560 | case('g') : | |
561 | reg = buf[2] & 0x0f; | |
562 | break; | |
563 | case('o') : | |
564 | reg = 8 + (buf[2] & 0x0f); | |
565 | break; | |
566 | case('l') : | |
567 | reg = 16 + (buf[2] & 0x0f); | |
568 | break; | |
569 | case('i') : | |
570 | reg = 24 + (buf[2] & 0x0f); | |
571 | break; | |
572 | default :continue; | |
573 | } | |
574 | } | |
575 | else continue;//no register | |
576 | f_val[0].aval.ival[0] = reg; | |
577 | f_val[0].bval[0] = type; | |
578 | insert_event_node(&(a_tree)->data, &addr, f_val, d_buf, &size); | |
579 | } | |
580 | } | |
581 | } | |
582 | // /*------------------------------------------------------------------------------- | |
583 | // create an instance for any needs. | |
584 | // --------------------------------------------------------------------------------*/ | |
585 | // void create_event_handle_call() | |
586 | // { | |
587 | // avl_conf_ptr a_tree; | |
588 | // FILE *fp; | |
589 | // char *str; | |
590 | // | |
591 | // a_tree = (avl_conf_ptr)malloc(sizeof(struct avl_conf_node)); | |
592 | // str = tf_getcstringp(1); // get a file name. | |
593 | // if((fp = fopen(str, "r")) == NULL){ | |
594 | // tf_error((char *)"Error: cannot open the file %s for reading\n", str); | |
595 | // tf_dofinish(); | |
596 | // } | |
597 | // a_tree->data = 0; | |
598 | // a_tree->dram = 0;//dram | |
599 | // get_event(a_tree, fp); | |
600 | // tf_putp(0, (unsigned int)a_tree);//reurn handle | |
601 | // fclose(fp); | |
602 | // } | |
603 | // /*------------------------------------------------------------------------------- | |
604 | // monitor verilog even and do the proper action when it hits. | |
605 | // --------------------------------------------------------------------------------*/ | |
606 | // void mon_event_call() | |
607 | // { | |
608 | // long long addr, val; | |
609 | // int thread, word, size, groups, low, high; | |
610 | // avl_conf_ptr handle; | |
611 | // avl_node_ptr t_ptr; | |
612 | // char* avalPtr; | |
613 | // s_tfnodeinfo node_info; | |
614 | // char str; | |
615 | // | |
616 | // handle = (avl_conf_ptr) tf_getp(1); | |
617 | // // addr = (unsigned long long)tf_getp(3); | |
618 | // low = tf_getlongp(&high, 3); | |
619 | // addr = high; | |
620 | // addr <<= 32; | |
621 | // addr |= low; | |
622 | // t_ptr = search_node(&(handle)->data, &addr); | |
623 | // if(t_ptr == 0)return; | |
624 | // //active window. | |
625 | // if(t_ptr->val[0].aval.ival[0] < 8)str = 'g'; | |
626 | // else if(t_ptr->val[0].aval.ival[0] < 16)str = 'o'; | |
627 | // else if(t_ptr->val[0].aval.ival[0] < 24)str = 'l'; | |
628 | // else str= 'i'; | |
629 | // thread = tf_getp(2);//get thread | |
630 | // size = (thread << 5) | (t_ptr->val[0].aval.ival[0] & 0x1f); | |
631 | // tf_nodeinfo(4, &node_info); | |
632 | // word = node_info.node_ngroups * 2; | |
633 | // avalPtr = node_info.node_value.memoryval_p + size * word; | |
634 | // val = 0; | |
635 | // for(groups = node_info.node_ngroups - 2; groups >= 0;groups--){ | |
636 | // val<<= 8; | |
637 | // val |= (avalPtr[groups] & 0xff); | |
638 | // } | |
639 | // switch(t_ptr->val[0].bval[0]){//type | |
640 | // case(1): | |
641 | // if(t_ptr->comment)io_printf((char *)"%0dInfo:%s reg(%c%d)->val(0x%llx)\n", tf_gettime(), t_ptr->comment, str, | |
642 | // (t_ptr->val[0].aval.ival[0] & 7), val); | |
643 | // else io_printf((char *)"%0dInfo: reg(%c%d)->val(0x%llx)\n", tf_gettime(), str, | |
644 | // (t_ptr->val[0].aval.ival[0] & 7), val); | |
645 | // break; | |
646 | // case(2): | |
647 | // if(t_ptr->comment)io_printf((char *)"%0dInfo:%s reg(%c%d)->val(%lld)\n", tf_gettime(), t_ptr->comment, str, | |
648 | // (t_ptr->val[0].aval.ival[0] & 7), val); | |
649 | // else io_printf((char *)"%0dInfo: reg(%c%d)->val(%lld)\n", tf_gettime(), str, | |
650 | // (t_ptr->val[0].aval.ival[0] & 7), val); | |
651 | // break; | |
652 | // } | |
653 | // } |