Changeset 52 for sources/src/sc_trace.cc
- Timestamp:
- Jan 22, 2013, 4:23:22 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sources/src/sc_trace.cc
r32 r52 35 35 */ 36 36 37 #include <cassert> 38 #include <list> 39 #include <cstdio> 40 #include <iostream> 41 #include <cstring> //strlen 42 37 43 #include "sc_port.h" 38 44 #include "sc_clock.h" … … 42 48 #include "hex2string.h" 43 49 44 #include <cassert>45 #include <list>46 #include <cstdio>47 #include <iostream>48 #include <cstring> //strlen49 50 50 #ifdef HAVE_CONFIG_H 51 51 #include "config.h" 52 52 #endif 53 53 54 54 55 //----------------------------------------- 55 56 … … 63 64 } 64 65 65 //#include "malloc.h" // NO LONGER SUPPORTED66 66 #include <cstdlib> 67 67 #include <cstdio> … … 70 70 //----------------------------------------- 71 71 72 72 73 namespace sc_core { 73 74 74 75 vector<sc_trace_file *> trace_file_list; 75 uint64 cpt = 0; 76 uint64 trace_start = 0; 77 78 //----------------------------------------- 79 #if 0 80 static ostream& operator << (ostream &, const signal2trace &); 81 #endif 82 83 //----------------------------------------- 84 85 /* 86 typedef list<signal2trace> signal2trace_list; 87 88 template <typename T> 89 static 90 void make_list_from_vector (const vector<T>& v, list<T>& l) 91 { 92 l.clear (); 93 typename vector<T>::const_iterator i; 94 for (i = v.begin (); i != v.end (); ++i) 95 l.push_back (*i); 96 } 97 98 template <typename T> 99 static 100 void make_vector_from_list (const list<T>& l, vector<T>& v) 101 { 102 v.clear (); 103 typename list<T>::const_iterator i; 104 for (i = l.begin (); i != l.end (); ++i) 105 v.push_back (*i); 106 } 107 108 static 109 int operator<(const signal2trace &e1, const signal2trace &e2) 110 { 111 return (e1.bit_size < e2.bit_size); 112 } 113 114 static void 115 init (sc_trace_file *tf) 116 { 117 signal2trace_list lsig; 118 make_list_from_vector (tf->sig_list, lsig); 119 lsig.reverse(); //sort (); 120 make_vector_from_list (lsig, tf->sig_list); 121 } 122 */ 123 124 static 125 void 126 init (sc_trace_file &tf) 127 { 128 if (dump_stage) 129 cerr << "Initializing trace functions : Looking for clocks..."; 130 131 vector<signal2trace>::iterator i; 132 i = (tf.sig_list).begin(); 133 while (i!=(tf.sig_list).end()) { 134 if (is_clock( *(i->inter) ) ) { 135 tf.clk_list.push_back(*i); 136 i = tf.sig_list.erase(i); 137 } 138 else ++i; 139 } 140 if (dump_stage) 141 cerr << "Done\n"; 142 } 143 144 static 145 void 146 vcd_print_cycle_number (FILE *f,long long unsigned int num) 147 { 148 string cycle; 149 150 //------------------------------------------------------------------------------------ 151 // affichage des cycles (#500 ou #2500 etc...) 152 fprintf(f,"\n#%llu00\n", num * 5);//cycle de simulation 153 } 76 uint64 cpt = 0; 77 uint64 trace_start = 0; 78 79 80 static void init(sc_trace_file & tf) { 81 if (dump_stage) { 82 cerr << "Initializing trace functions : Looking for clocks..."; 83 } 84 85 vector<signal2trace>::iterator i; 86 i = (tf.sig_list).begin(); 87 while (i != (tf.sig_list).end()) { 88 if (is_clock(*(i->inter))) { 89 tf.clk_list.push_back(*i); 90 i = tf.sig_list.erase(i); 91 } 92 else { 93 ++i; 94 } 95 } 96 if (dump_stage) { 97 cerr << "Done\n"; 98 } 99 } 100 101 102 static void vcd_print_cycle_number(FILE * f,long long unsigned int num) { 103 string cycle; 104 105 // affichage des cycles (#500 ou #2500 etc...) 106 fprintf(f,"\n#%llu00\n", num * 5);//cycle de simulation 107 } 108 109 154 110 155 111 //-------------------------------------------------------------------------------------- 156 112 // trace function 157 113 // Called each end of cycle to dump in trace files 158 159 void 160 trace_all (bool part) 161 { 162 if (trace_file_list.empty ()) 163 return; 164 165 if (cpt >= trace_start) 166 { 167 vector<sc_trace_file*>::const_iterator ptf; 168 for (ptf = trace_file_list.begin (); ptf != trace_file_list.end(); ++ptf) 169 { 170 sc_trace_file *tf = *ptf; 171 assert(tf != NULL); 172 trace (*tf, part); 173 } 174 } 175 176 cpt++; 177 } 114 void trace_all(bool part) { 115 if (trace_file_list.empty()) { 116 return; 117 } 118 119 if (cpt >= trace_start) { 120 vector<sc_trace_file *>::const_iterator ptf; 121 for (ptf = trace_file_list.begin(); ptf != trace_file_list.end(); ++ptf) { 122 sc_trace_file * tf = *ptf; 123 assert(tf != NULL); 124 trace(*tf, part); 125 } 126 } 127 128 cpt++; 129 } 130 178 131 179 132 #ifdef CONFIG_PAT_TRACE_FORMAT 180 static void 181 pat_set_value (char *buf, const signal2trace &s) 182 { 183 if ( ( s.bit_size % 4 ) == 0 ) 184 { 185 buf[1] = 'x'; 186 hex2string( buf+2, s.inter->get_pointer() , s.bit_size ); 187 } 188 else 189 { 190 buf[1] = 'b'; 191 bit2string( buf+2, s.inter->get_pointer() , s.bit_size ); 192 } 193 } 194 195 inline 196 static 197 void 198 affect (const char *cur, 199 const char *nomSig, 200 const char *buf) 201 { 133 static void pat_set_value(char * buf, const signal2trace & s) { 134 if ((s.bit_size % 4) == 0) { 135 buf[1] = 'x'; 136 hex2string(buf + 2, s.inter->get_pointer(), s.bit_size); 137 } 138 else { 139 buf[1] = 'b'; 140 bit2string(buf + 2, s.inter->get_pointer(), s.bit_size); 141 } 142 } 143 144 145 inline static void affect(const char * cur, const char * nomSig, const char * buf) { 146 AFFECT ((char*)cur, (char*)nomSig, (char*)buf ); 147 } 148 149 150 151 inline static void pat_trace( 152 sc_trace_file & tf, 153 const signal2trace & s2t, 154 const ostringstream & cur1, 155 const ostringstream & cur2) { 156 static char buf[50] = "0\0"; 157 //cout << "Nom du signal: " << s->nomSig; 158 pat_set_value(buf, s2t); 159 affect(cur1.str().c_str(), s2t.nomSig.c_str(), buf); 160 affect(cur2.str().c_str(), s2t.nomSig.c_str(), buf); 161 } 162 163 164 inline static void pat_trace_clocks( 165 sc_trace_file & tf, 166 const ostringstream & cur1, 167 const ostringstream & cur2) { 168 vector<signal2trace>::const_iterator s; 169 for (s = (tf.clk_list).begin(); s != (tf.clk_list).end(); s++) { 170 const signal2trace & s2t = *s; 171 char * name = (char *) ((s2t.nomSig).c_str()); 172 const sc_interface * inter = s2t.inter; 173 const sc_clock * clk = (const sc_clock *) inter; 174 bool posedge_first = clk->posedge_first; 175 char * a, * b; 176 if (posedge_first) { 177 a = "0B1"; 178 b = "0B0"; 179 } 180 else { 181 a = "0B0"; 182 b = "0B1"; 183 } 184 affect(cur1.str().c_str(), name, a); 185 affect(cur2.str().c_str(), name, b); 186 } 187 } 188 189 190 static void pat_trace_init(sc_trace_file & tf) { 191 init(tf); 192 } 193 194 195 static void pat_trace(sc_trace_file & tf, bool part) { 196 if (part) { 197 return; 198 } 199 200 if (cpt == trace_start) { 201 pat_trace_init(tf); 202 } 203 204 // time counters 205 ostringstream cur1, cur2; 206 long long unsigned int buf = cpt * 5; 207 cur1 << buf << "00"; 208 cur2 << buf + 5 << "00"; 209 210 // affect each signal 211 vector<signal2trace>::iterator s; 212 for (s = (tf.sig_list).begin(); s != (tf.sig_list).end(); s++) { 213 pat_trace(tf, *s, cur1, cur2); 214 } 215 pat_trace_clocks(tf, cur1, cur2); 216 } 217 218 #else 219 void pat_trace (sc_trace_file & tf, bool part) {} 220 #endif // CONFIG_PAT_TRACE_FORMAT 221 222 223 static bool is_modified(const signal2trace & s2t) { 224 unsigned int bit_size = s2t.bit_size; 225 if (bit_size > 32) { 226 const uint64 * const pointer_saved = (const uint64 *) s2t.pointer; 227 const uint64 * const pointer_current = (const uint64 *) s2t.inter->get_pointer(); 228 return (*pointer_saved != *pointer_current); 229 } 230 else if (bit_size > 16) { 231 const uint32 * const pointer_saved = (const uint32 *) s2t.pointer; 232 const uint32 * const pointer_current = (const uint32 *) s2t.inter->get_pointer(); 233 return (*pointer_saved != *pointer_current); 234 } 235 else { 236 const uint16 * const pointer_saved = (const uint16 *) s2t.pointer; 237 const uint16 * const pointer_current = (const uint16 *) s2t.inter->get_pointer(); 238 return (*pointer_saved != *pointer_current); 239 } 240 } 241 242 243 static bool save_modification(signal2trace & s2t) { 244 *(s2t.pointer) = *(s2t.inter->get_pointer()); 245 } 246 247 248 static inline void print(sc_trace_file & tf, signal2trace & s2t) { 249 char buf[100]; 250 bit2string(buf + 1, s2t.inter->get_pointer() , s2t.bit_size); 251 252 char * buf2 = strip(buf + 1); 253 int len = strlen(buf2); 254 if (s2t.bit_size != 1) { 255 --buf2; 256 buf2[0] = 'b'; 257 sprintf(buf2 + len + 1, " %s\n", s2t.alias); 258 } 259 else { 260 sprintf(buf2 + len, "%s\n", s2t.alias); 261 } 262 263 // ecriture liste[i] dans le fichier VCD: 264 if ((fprintf(tf.pfic,buf2)) == 0) { 265 cerr << "erreur ecriture du couple Valeur/Nom du signal dans le VCD\n"; 266 exit(16); 267 } 268 } 269 270 271 static inline void vcd_trace(sc_trace_file & tf, signal2trace & s2t, bool skip = true) { 272 if ((skip) && (!is_modified(s2t))) { 273 return; 274 } 275 save_modification(s2t); 276 print(tf, s2t); 277 } 278 279 280 static void vcd_trace_clocks(const sc_trace_file & tf, bool v) { 281 vector<signal2trace>::const_iterator i; 282 for (i = (tf.clk_list).begin(); i != (tf.clk_list).end(); i++) { 283 const signal2trace & s2t = *i; 284 const sc_interface * inter = s2t.inter; 285 const sc_clock * clk = (const sc_clock *) inter; 286 bool posedge_first = clk->posedge_first; 287 fprintf(tf.pfic, "%c%s\n",(v^posedge_first)?'0':'1', i->alias); 288 } 289 } 290 291 292 static tab_t * vcd_signal_table = NULL; 293 294 295 static int vcd_get_size(const signal2trace & s2t) { 202 296 #if 0 203 printf ("AFFECT (\"%s\", \"%s\", \"%s\");\n", 204 cur, 205 nomSig, 206 buf); 297 cerr << "alias : " << s2t.alias << "\n"; 298 cerr << "bit_size : " << s2t.bit_size << "\n"; 299 cerr << "=> #tab_t : " << ((s2t.bit_size - 1) / (sizeof (tab_t)*8)) + 1 << "\n"; 207 300 #endif 208 AFFECT ((char*)cur, (char*)nomSig, (char*)buf ); 209 } 210 211 inline 212 static 213 void 214 pat_trace (sc_trace_file &tf, 215 const signal2trace &s2t, 216 const ostringstream &cur1, 217 const ostringstream &cur2) 218 { 219 static char buf[50] = "0\0"; 220 //cout << "Nom du signal: " << s->nomSig; 221 pat_set_value (buf, s2t); 222 affect (cur1.str().c_str(), s2t.nomSig.c_str(), buf); 223 affect (cur2.str().c_str(), s2t.nomSig.c_str(), buf); 224 } 225 226 inline 227 static 228 void 229 pat_trace_clocks (sc_trace_file &tf, 230 const ostringstream &cur1, 231 const ostringstream &cur2) 232 { 233 vector<signal2trace>::const_iterator s; 234 for(s=(tf.clk_list).begin();s!=(tf.clk_list).end();s++) 235 { 236 const signal2trace &s2t = *s; 237 char *name = (char*)((s2t.nomSig).c_str()); 238 const sc_interface *inter = s2t.inter; 239 const sc_clock *clk = (const sc_clock *) inter; 240 bool posedge_first = clk->posedge_first; 241 char *a, *b; 242 if (posedge_first) 243 { 244 a = "0B1"; b = "0B0"; 245 } else { 246 a = "0B0"; b = "0B1"; 247 } 248 affect (cur1.str().c_str(), name, a); 249 affect (cur2.str().c_str(), name, b); 250 } 251 } 252 253 static 254 void 255 pat_trace_init (sc_trace_file &tf) 256 { 257 init (tf); 258 } 259 260 static 261 void 262 pat_trace (sc_trace_file &tf, 263 bool part) 264 { 265 if (part) 266 return; 267 if (cpt==trace_start) { 268 pat_trace_init (tf); 269 } 270 // time counters 271 ostringstream cur1,cur2; 272 long long unsigned int buf = cpt * 5; 273 cur1 << buf << "00"; 274 cur2 << buf + 5 << "00"; 275 // affect each signal 276 vector<signal2trace>::iterator s; 277 for(s=(tf.sig_list).begin();s!=(tf.sig_list).end();s++) 278 { 279 pat_trace (tf, *s, cur1, cur2); 280 } 281 pat_trace_clocks (tf, cur1, cur2); 282 } 283 #else 284 void 285 pat_trace (sc_trace_file &tf, 286 bool part) 287 { 288 } 301 return ((s2t.bit_size - 1) / (sizeof(tab_t) * 8)) + 1; 302 } 303 304 305 static int vcd_get_signal_table_size(const sc_trace_file & tf) { 306 int total_size = 0; 307 vector<signal2trace>::const_iterator i; 308 for (i = (tf.sig_list).begin(); i != (tf.sig_list).end(); i++) { 309 const signal2trace & s2t = *i; 310 total_size += vcd_get_size(s2t); 311 } 312 return total_size; 313 } 314 315 316 static void vcd_alloc_signal_table(int size) { 317 if (size == 0) { 318 vcd_signal_table = NULL; 319 } 320 else { 321 vcd_signal_table = (tab_t *) malloc(sizeof(tab_t) * size); 322 } 323 #ifdef CONFIG_DEBUG 324 if (vcd_signal_table == NULL) { 325 cerr << "Internal error : Unable to allocate memory for signal table to trace.\n"; 326 exit(24032005); 327 } 328 #endif 329 } 330 331 332 static void vcd_bind_to_signal_table(sc_trace_file & tf) { 333 tab_t * cur = vcd_signal_table; 334 vector<signal2trace>::iterator i; 335 for (i = (tf.sig_list).begin(); i != (tf.sig_list).end(); i++) { 336 signal2trace & s2t = *i; 337 s2t.pointer = cur; 338 cur += vcd_get_size(s2t); 339 #if 0 340 std::cout << s2t 341 << "\nget_pointer () => " << hex << s2t.inter->get_pointer () 342 << "\nvcd pointer () => " << hex << s2t.pointer 343 << "\nvcd_get_size () => " << vcd_get_size (s2t) 344 << "\n"; 345 #endif 346 } 347 } 348 349 350 static void vcd_build_signal_table(sc_trace_file & tf) { 351 int s = vcd_get_signal_table_size(tf); 352 vcd_alloc_signal_table(s); 353 vcd_bind_to_signal_table(tf); 354 } 355 356 357 static void vcd_trace_init(sc_trace_file & tf) { 358 init(tf); 359 fprintf(tf.pfic,"$upscope $end\n$enddefinitions $end\n\n$comment\nAll initial values are dumped below at time 0 sec = 0 timescale units.\n$end\n\n$dumpvars\n"); 360 vcd_build_signal_table(tf); 361 362 // dump all var 363 vector<signal2trace>::iterator i; 364 for(i = (tf.sig_list).begin() ; i != (tf.sig_list).end(); i++) { 365 vcd_trace(tf, *i, false); 366 }//fin de la liste des signal2trace 367 368 // clocks to trace 369 vcd_trace_clocks(tf, true); 370 371 if (cpt == trace_start) { 372 fprintf(tf.pfic, "$end\n"); //fin du $dumpvars 373 } 374 } 375 376 377 static void vcd_trace(sc_trace_file & tf, bool part) { 378 if (sc_core::cpt == sc_core::trace_start) { 379 if (part == false) { 380 vcd_trace_init (tf); 381 } 382 } 383 else { 384 #if defined(CONFIG_DEBUG) 385 if (vcd_signal_table == NULL) { 386 cerr << "Internal Error : VCD signal table is not yet allocated.\n"; 387 exit(1042005); 388 } 389 #endif 390 vcd_print_cycle_number(tf.pfic,sc_core::cpt); 391 // signals to trace 392 if (part == false) { 393 vector<signal2trace>::iterator i; 394 for (i = tf.sig_list.begin(); i != tf.sig_list.end(); i++) { 395 vcd_trace(tf, *i); 396 }//fin de la liste des signal2trace 397 } 398 // clocks to trace 399 vcd_trace_clocks(tf, !part); 400 } 401 } 402 403 404 void trace(sc_trace_file & tf, bool part) { 405 switch (tf.flag) { 406 // fonction trace() pour VCD: 407 case VCD_FORMAT: 408 vcd_trace(tf, part); 409 break; 410 //fin de la fonction trace() pour VCD 411 412 /*------------------------------------------------------------------------------------*/ 413 414 // fonction trace() pour PAT: 415 case PAT_FORMAT: 416 pat_trace(tf, part); 417 break; 418 //fin de la fonction trace() pour PAT 419 } 420 // fin du switch format pour trace() 421 422 } 423 424 425 /*------------------------------------------------------------------------------------*/ 426 427 428 static void vcd_sc_trace(sc_trace_file * tf, const signal2trace & t, const std::string & name) { 429 //déclaration du signal dans l'en-tête du fichier VCD: 430 // exemple de déclarations : 431 // $var wire 1 aaa clk $end 432 // $var wire 1 aab resetn $end 433 // $var wire 1 aac _mips0_IT_5 $end 434 435 std::string declaration; 436 std::ostringstream buf; 437 // begin 438 declaration = "$var wire "; 439 buf.width(4); 440 buf << t.bit_size; 441 declaration += buf.str(); 442 declaration += " "; 443 declaration += t.alias; 444 declaration += " "; 445 declaration += name; 446 // bit range 447 if (t.bit_size != 1) { 448 declaration += " ["; 449 std::ostringstream bit_size; 450 bit_size << t.bit_size - 1; 451 declaration += bit_size.str(); 452 declaration += ":0]"; 453 } 454 // end 455 declaration += " $end\n"; 456 457 if ((fprintf(tf->pfic,declaration.c_str())) == 0) { 458 cerr << "erreur ecriture de declaration du signal sc_signal\n"; 459 exit(3); 460 } 461 } 462 463 464 static void pat_sc_trace(sc_trace_file * tf, const signal2trace & t, const std::string & name) { 465 #ifdef CONFIG_PAT_TRACE_FORMAT 466 //exemple: 467 //DECLAR ("a", ":2", "X", IN, "3 downto 0", "" ); 468 //DECLAR ("b", ":2", "X", IN, "3 downto 0", "" ); 469 //DECLAR ("vdd", ":2", "B", IN, "", "" ); 470 471 std::string downto; 472 const sc_object * obj = (const sc_object *) t.inter; 473 const char * obj_kind = obj->kind(); 474 char * format; 475 char * dir; 476 477 if (strstr(obj_kind, "inout")) 478 dir = OUT; // Direction is OUT instead of INOUT 479 // because port behavior is only seen as an output port. 480 else if (strstr (obj_kind, "in")) { 481 dir = IN; 482 } 483 else if (strstr (obj_kind, "out")) { 484 dir = OUT; 485 } 486 else if (obj_kind == sc_clock::kind_string) { 487 dir = SIGNAL; 488 } 489 else if (obj_kind == sc_signal_base::kind_string) { 490 dir = REGISTER; 491 } 492 // to do : dir = REGISTER; 493 // dir = SIGNAL; 494 495 if (t.bit_size % 4 == 0) { 496 format = "x"; 497 } 498 else { 499 format = "b"; 500 } 501 502 if (t.bit_size == 1) { 503 downto = ""; 504 } 505 else { 506 std::ostringstream nbits; 507 nbits << t.bit_size - 1; 508 downto = nbits.str(); 509 downto += " downto 0"; 510 } 511 512 #if 0 513 printf ("DECLAR (\"%s\", \":1\", \"%s\", %s, \"%s\", \"\" );\n", 514 name.c_str (), 515 format, 516 dir, 517 downto.c_str()); 518 #endif 519 DECLAR ((char *) (name.c_str()), ":1", format, dir, (char *) downto.c_str(), ""); 289 520 #endif // CONFIG_PAT_TRACE_FORMAT 290 291 static 292 bool 293 is_modified (const signal2trace &s2t) 294 { 295 unsigned int bit_size = s2t.bit_size; 296 if (bit_size > 32) 297 { 298 const uint64 *const pointer_saved = (const uint64 *)s2t.pointer; 299 const uint64 *const pointer_current = (const uint64 *)s2t.inter->get_pointer (); 300 return (*pointer_saved != *pointer_current); 301 } else if (bit_size > 16) { 302 const uint32 *const pointer_saved = (const uint32*)s2t.pointer; 303 const uint32 *const pointer_current = (const uint32*)s2t.inter->get_pointer (); 304 return (*pointer_saved != *pointer_current); 305 } else { 306 const uint16 *const pointer_saved = (const uint16 *)s2t.pointer; 307 const uint16 *const pointer_current = (const uint16 *)s2t.inter->get_pointer (); 308 return (*pointer_saved != *pointer_current); 309 } 310 } 311 312 static 313 bool 314 save_modification (signal2trace &s2t) 315 { 316 *(s2t.pointer) = *(s2t.inter->get_pointer ()); 317 } 318 319 static 320 inline 321 void 322 print (sc_trace_file &tf, signal2trace &s2t) 323 { 324 char buf[100]; 325 bit2string( buf+1, s2t.inter->get_pointer() , s2t.bit_size ); 326 327 char *buf2 = strip(buf+1); 328 int len = strlen (buf2); 329 if (s2t.bit_size != 1) 330 { 331 --buf2; 332 buf2[0] = 'b'; 333 sprintf (buf2 + len + 1, " %s\n", s2t.alias); 334 } else { 335 sprintf (buf2 + len, "%s\n", s2t.alias); 336 } 337 /* 338 char *buf2 = strip(buf); 339 char buf3[128]; 340 341 if (s2t.bit_size != 1) 342 sprintf (buf3, "b%s %s\n", buf2, s2t.alias); 343 else 344 sprintf (buf3, "%s%s\n", buf2, s2t.alias); 345 */ 346 // ecriture liste[i] dans le fichier VCD: 347 if ((fprintf(tf.pfic,buf2))==0) 348 { 349 cerr << "erreur ecriture du couple Valeur/Nom du signal dans le VCD\n"; 350 exit(16); 351 } 352 } 353 354 static 355 inline 356 void 357 vcd_trace (sc_trace_file &tf, 358 signal2trace &s2t, 359 bool skip = true) 360 { 361 if ((skip) && (!is_modified (s2t))) 362 return; 363 save_modification (s2t); 364 print (tf, s2t); 365 } 366 367 static 368 void 369 vcd_trace_clocks (const sc_trace_file &tf, 370 bool v) 371 { 372 vector<signal2trace>::const_iterator i; 373 for(i=(tf.clk_list).begin();i!=(tf.clk_list).end();i++) 374 { 375 const signal2trace &s2t = *i; 376 const sc_interface *inter = s2t.inter; 377 const sc_clock *clk = (const sc_clock *) inter; 378 bool posedge_first = clk->posedge_first; 379 fprintf(tf.pfic, "%c%s\n",(v^posedge_first)?'0':'1', i->alias); 380 } 381 } 382 383 static tab_t *vcd_signal_table = NULL; 384 385 386 static 387 int 388 vcd_get_size (const signal2trace &s2t) 389 { 390 #if 0 391 cerr << "alias : " << s2t.alias << "\n"; 392 cerr << "bit_size : " << s2t.bit_size << "\n"; 393 cerr << "=> #tab_t : " << ((s2t.bit_size - 1) / (sizeof (tab_t)*8)) + 1 << "\n"; 394 #endif 395 return ((s2t.bit_size - 1) / (sizeof (tab_t)*8)) + 1; 396 } 397 398 static 399 int 400 vcd_get_signal_table_size (const sc_trace_file &tf) 401 { 402 int total_size = 0; 403 vector<signal2trace>::const_iterator i; 404 for(i=(tf.sig_list).begin();i!=(tf.sig_list).end();i++) 405 { 406 const signal2trace &s2t = *i; 407 total_size += vcd_get_size (s2t); 408 } 409 return total_size; 410 } 411 412 static 413 void 414 vcd_alloc_signal_table (int size) 415 { 416 if (size == 0) 417 vcd_signal_table = NULL; 418 else 419 vcd_signal_table = (tab_t*) malloc (sizeof (tab_t) * size); 420 #ifdef CONFIG_DEBUG 421 if (vcd_signal_table == NULL) 422 { 423 cerr << "Internal error : Unable to allocate memory for signal table to trace.\n"; 424 exit (24032005); 425 } 426 #endif 427 } 428 429 static 430 void 431 vcd_bind_to_signal_table (sc_trace_file &tf) 432 { 433 tab_t *cur = vcd_signal_table; 434 vector<signal2trace>::iterator i; 435 for(i=(tf.sig_list).begin();i!=(tf.sig_list).end();i++) 436 { 437 signal2trace &s2t = *i; 438 s2t.pointer = cur; 439 cur += vcd_get_size (s2t); 440 #if 0 441 std::cout << s2t 442 << "\nget_pointer () => " << hex << s2t.inter->get_pointer () 443 << "\nvcd pointer () => " << hex << s2t.pointer 444 << "\nvcd_get_size () => " << vcd_get_size (s2t) 445 << "\n"; 446 #endif 447 } 448 } 449 450 static 451 void 452 vcd_build_signal_table (sc_trace_file &tf) 453 { 454 int s = vcd_get_signal_table_size (tf); 455 456 vcd_alloc_signal_table (s); 457 458 vcd_bind_to_signal_table (tf); 459 } 460 461 static 462 void 463 vcd_trace_init (sc_trace_file &tf) 464 { 465 init (tf); 466 fprintf (tf.pfic,"$upscope $end\n$enddefinitions $end\n\n$comment\nAll initial values are dumped below at time 0 sec = 0 timescale units.\n$end\n\n$dumpvars\n"); 467 vcd_build_signal_table (tf); 468 469 // dump all var 470 vector<signal2trace>::iterator i; 471 for(i=(tf.sig_list).begin();i!=(tf.sig_list).end();i++) 472 { 473 vcd_trace (tf, *i, false); 474 }//fin de la liste des signal2trace 475 476 // clocks to trace 477 vcd_trace_clocks (tf, true); 478 479 if (cpt==trace_start) 480 fprintf(tf.pfic,"$end\n"); //fin du $dumpvars 481 } 482 483 static 484 void 485 vcd_trace (sc_trace_file &tf, 486 bool part) 487 { 488 if (sc_core::cpt==sc_core::trace_start) { 489 if (part == false) 490 vcd_trace_init (tf); 491 } else { 492 #if defined(CONFIG_DEBUG) 493 if (vcd_signal_table == NULL) 494 { 495 cerr << "Internal Error : VCD signal table is not yet allocated.\n"; 496 exit (1042005); 497 } 498 #endif 499 vcd_print_cycle_number (tf.pfic,sc_core::cpt); 500 // signals to trace 501 if (part == false) 502 { 503 // vector<signal2trace> &sig_list = (part == false)?to_update_on_pos:to_update_on_neg; 504 vector<signal2trace>::iterator i; 505 for(i=tf.sig_list.begin();i!=tf.sig_list.end();i++) 506 { 507 vcd_trace (tf, *i); 508 }//fin de la liste des signal2trace 509 } 510 // clocks to trace 511 vcd_trace_clocks (tf, !part); 512 } 513 } 514 515 void 516 trace (sc_trace_file &tf, bool part) 517 { 518 /*------------------------------------------------------------------------------------*/ 519 520 switch (tf.flag){ 521 522 // fonction trace() pour VCD: 523 case VCD_FORMAT: 524 vcd_trace (tf, part); 525 break;//fin de la fonction trace() pour VCD 526 527 /*------------------------------------------------------------------------------------*/ 528 529 // fonction trace() pour PAT: 530 case PAT_FORMAT : 531 pat_trace (tf, part); 532 break;//fin de la fonction trace() pour PAT 533 }// fin du switch format pour trace() 534 535 } 536 537 /*------------------------------------------------------------------------------------*/ 538 539 static 540 void 541 vcd_sc_trace (sc_trace_file *tf, const signal2trace &t, const std::string 542 &name) 543 { 544 //déclaration du signal dans l'en-tête du fichier VCD: 545 // exemple de déclarations : 546 // $var wire 1 aaa clk $end 547 // $var wire 1 aab resetn $end 548 // $var wire 1 aac _mips0_IT_5 $end 549 550 std::string declaration; 551 std::ostringstream buf; 552 // begin 553 declaration = "$var wire "; 554 buf.width (4); 555 buf << t.bit_size; 556 declaration += buf.str(); 557 declaration += " "; 558 declaration += t.alias; 559 declaration += " "; 560 declaration += name; 561 // bit range 562 if (t.bit_size != 1) 563 { 564 declaration += " ["; 565 std::ostringstream bit_size; 566 bit_size << t.bit_size - 1; 567 declaration += bit_size.str(); 568 declaration += ":0]"; 569 } 570 // end 571 declaration += " $end\n"; 572 //declaration += " $end\n"; 573 574 if ((fprintf(tf->pfic,declaration.c_str()))==0) 575 { 576 cerr << "erreur ecriture de declaration du signal sc_signal\n"; 577 exit(3); 578 } 579 } 580 581 static 582 void 583 pat_sc_trace (sc_trace_file *tf, const signal2trace &t, const std::string 584 &name) 585 { 586 #ifdef CONFIG_PAT_TRACE_FORMAT 587 //exemple: 588 //DECLAR ("a", ":2", "X", IN, "3 downto 0", "" ); 589 //DECLAR ("b", ":2", "X", IN, "3 downto 0", "" ); 590 //DECLAR ("vdd", ":2", "B", IN, "", "" ); 591 592 std::string downto; 593 const sc_object *obj = (const sc_object *) t.inter; 594 const char *obj_kind = obj->kind (); 595 char *format; 596 char *dir; 597 598 if (strstr (obj_kind,"inout")) 599 dir = OUT; // Direction is OUT instead of INOUT 600 // because port behavior is only seen as an output port. 601 else if (strstr (obj_kind,"in")) 602 dir = IN; 603 else if (strstr (obj_kind,"out")) 604 dir = OUT; 605 else if (obj_kind == sc_clock::kind_string) 606 dir = SIGNAL; 607 else if (obj_kind == sc_signal_base::kind_string) 608 dir = REGISTER; 609 // to do : dir = REGISTER; 610 // dir = SIGNAL; 611 612 if ( t.bit_size % 4 == 0) 613 format = "x"; 614 else 615 format = "b"; 616 617 if ( t.bit_size == 1) { 618 downto = ""; 619 } 620 else 621 { 622 std::ostringstream nbits; 623 nbits << t.bit_size-1; 624 downto = nbits.str(); 625 downto += " downto 0"; 626 } 627 628 #if 0 629 printf ("DECLAR (\"%s\", \":1\", \"%s\", %s, \"%s\", \"\" );\n", 630 name.c_str (), 631 format, 632 dir, 633 downto.c_str()); 634 #endif 635 DECLAR ((char*)(name.c_str ()), ":1", format, dir,(char *) downto.c_str(), "" ); 636 #endif // CONFIG_PAT_TRACE_FORMAT 637 } 638 639 void 640 sc_trace( sc_trace_file* tf, const signal2trace &t, const std::string &name ) 641 { 642 if (tf == NULL) 643 return; 644 if (t.bit_size > 64) 645 cerr << "Warning : tracing functions do not support data types larger than 64 bits.\n"; 646 if (already_initialized) 647 cerr << "Warning : please call tracing functions BEFORE sc_initialize.\n"; 648 //ajout du signal dans la liste des signaux à tracer: 649 (tf->sig_list).push_back (t); 650 651 switch (tf->flag) { 652 case VCD_FORMAT : 653 vcd_sc_trace (tf, t, name); 654 break; 655 656 case PAT_FORMAT : 657 pat_sc_trace (tf, t, name); 658 break; 659 default : 660 { 661 cerr << "Unknown trace format.\n"; 662 exit (1); 663 } 664 }// fin switch format pour sc_trace 665 666 } 521 } 522 523 524 void sc_trace(sc_trace_file * tf, const signal2trace & t, const std::string & name) { 525 if (tf == NULL) { 526 return; 527 } 528 if (t.bit_size > 64) { 529 cerr << "Warning : tracing functions do not support data types larger than 64 bits.\n"; 530 } 531 if (already_initialized) { 532 cerr << "Warning : please call tracing functions BEFORE sc_initialize.\n"; 533 } 534 //ajout du signal dans la liste des signaux à tracer: 535 (tf->sig_list).push_back(t); 536 537 switch (tf->flag) { 538 case VCD_FORMAT : 539 vcd_sc_trace(tf, t, name); 540 break; 541 542 case PAT_FORMAT : 543 pat_sc_trace(tf, t, name); 544 break; 545 default : 546 { 547 cerr << "Unknown trace format.\n"; 548 exit(1); 549 } 550 }// fin switch format pour sc_trace 551 552 } 553 554 //---------------------------------------------------------------------------- 555 556 #define DEF_SC_TRACE(T) /*inline \*/ \ 557 void \ 558 sc_trace (sc_trace_file* tf, const T& object, const std::string & name) \ 559 { \ 560 signal2trace t; \ 561 sc_interface * inter = new sc_localvar< T > (object); \ 562 t.inter = inter; \ 563 t.alias = alias(); \ 564 t.bit_size = get_bits_number(object); \ 565 t.nomSig = name; \ 566 sc_trace (tf, t, name); \ 567 } 568 569 570 DEF_SC_TRACE(bool) 571 DEF_SC_TRACE(float) 572 DEF_SC_TRACE(double) 573 DEF_SC_TRACE(unsigned char) 574 DEF_SC_TRACE(unsigned short) 575 DEF_SC_TRACE(unsigned int) 576 DEF_SC_TRACE(unsigned long) 577 DEF_SC_TRACE(char) 578 DEF_SC_TRACE(short) 579 DEF_SC_TRACE(int) 580 DEF_SC_TRACE(long) 581 DEF_SC_TRACE(uint64) 582 DEF_SC_TRACE(int64) 583 584 #undef DEF_SC_TRACE 667 585 668 586 //--------------------------------------------------------------------------- 669 587 670 #if 0671 static672 ostream&673 operator << (ostream &o,674 const signal2trace &s2t)675 {676 o << "signal2trace {"677 << "inter = " << hex << s2t.inter678 << ",alias = '" << s2t.alias << "'"679 << ",bitsize = " << dec << s2t.bit_size680 << ",pointer = " << hex << s2t.pointer681 << ",nomSig = " << s2t.nomSig << "}";682 return o;683 }684 #endif685 686 //----------------------------------------------------------------------------687 688 #define DEF_SC_TRACE(T) /*inline \*/ \689 void \690 sc_trace (sc_trace_file* tf, const T& object, const std::string &name) \691 { \692 signal2trace t; \693 sc_interface *inter = new sc_localvar<T> (object); \694 t.inter = inter; \695 t.alias = alias(); \696 t.bit_size = get_bits_number(object); \697 t.nomSig = name; \698 sc_trace (tf, t, name); \699 } \700 701 DEF_SC_TRACE(bool)702 DEF_SC_TRACE(float)703 DEF_SC_TRACE(double)704 DEF_SC_TRACE(unsigned char)705 DEF_SC_TRACE(unsigned short)706 DEF_SC_TRACE(unsigned int)707 DEF_SC_TRACE(unsigned long)708 DEF_SC_TRACE(char)709 DEF_SC_TRACE(short)710 DEF_SC_TRACE(int)711 DEF_SC_TRACE(long)712 DEF_SC_TRACE(uint64)713 DEF_SC_TRACE(int64)714 715 #undef DEF_SC_TRACE716 717 //---------------------------------------------------------------------------718 588 } // end of sc_core namespace 719 589 590 591 /* 592 # Local Variables: 593 # tab-width: 4; 594 # c-basic-offset: 4; 595 # c-file-offsets:((innamespace . 0)(inline-open . 0)); 596 # indent-tabs-mode: nil; 597 # End: 598 # 599 # vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 600 */ 601
Note: See TracChangeset
for help on using the changeset viewer.