1/***************************************************************************** 2 3 Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 more contributor license agreements. See the NOTICE file distributed 5 with this work for additional information regarding copyright ownership. 6 Accellera licenses this file to you under the Apache License, Version 2.0 7 (the "License"); you may not use this file except in compliance with the 8 License. You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12 Unless required by applicable law or agreed to in writing, software 13 distributed under the License is distributed on an "AS IS" BASIS, 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 implied. See the License for the specific language governing 16 permissions and limitations under the License. 17 18 *****************************************************************************/ 19 20/***************************************************************************** 21 22 sc_wif_trace.cpp - Implementation of WIF tracing. 23 24 Original Author - Abhijit Ghosh, Synopsys, Inc. 25 26 *****************************************************************************/ 27 28/***************************************************************************** 29 30 MODIFICATION LOG - modifiers, enter your name, affliation, date and 31 changes you are making here. 32 33 Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc. 34 Description of Modification: - Replaced 'width' of sc_(u)int with their 35 'bitwidth()'. 36 37 Name, Affiliation, Date: 38 Description of Modification: 39 40 *****************************************************************************/ 41 42/***************************************************************************** 43 44 Acknowledgement: The tracing mechanism is based on the tracing 45 mechanism developed at Infineon (formerly Siemens HL). Though this 46 code is somewhat different, and significantly enhanced, the basics 47 are identical to what was originally contributed by Infineon. The 48 contribution of Infineon in the development of this tracing 49 technology is hereby acknowledged. 50 51 *****************************************************************************/ 52 53/***************************************************************************** 54 55 Instead of creating the binary WIF format, we create the ASCII 56 WIF format which can be converted to the binary format using 57 a2wif (utility that comes with VSS from Synopsys). This way, 58 a user who does not have Synopsys VSS can still create WIF 59 files, but they can only be viewed by users who have VSS. 60 61 *****************************************************************************/ 62 63 64#include <cstdlib> 65#include <vector> 66 67#define SC_DISABLE_API_VERSION_CHECK // for in-library sc_ver.h inclusion 68 69#include "sysc/kernel/sc_simcontext.h" 70#include "sysc/kernel/sc_ver.h" 71#include "sysc/datatypes/bit/sc_bit.h" 72#include "sysc/datatypes/bit/sc_logic.h" 73#include "sysc/datatypes/bit/sc_lv_base.h" 74#include "sysc/datatypes/int/sc_signed.h" 75#include "sysc/datatypes/int/sc_unsigned.h" 76#include "sysc/datatypes/int/sc_int_base.h" 77#include "sysc/datatypes/int/sc_uint_base.h" 78#include "sysc/datatypes/fx/fx.h" 79#include "sysc/tracing/sc_wif_trace.h" 80 81namespace sc_core { 82 83// Forward declarations for functions that come later in the file 84static char map_sc_logic_state_to_wif_state(char in_char); 85 86const char* wif_names[wif_trace_file::WIF_LAST] = {"BIT","MVL","real"}; 87 88 89// ---------------------------------------------------------------------------- 90// CLASS : wif_trace 91// 92// Base class for WIF traces. 93// ---------------------------------------------------------------------------- 94 95class wif_trace 96{ 97public: 98 99 wif_trace(const std::string& name_, const std::string& wif_name_); 100 101 // Needs to be pure virtual as has to be defined by the particular 102 // type being traced 103 virtual void write(FILE* f) = 0; 104 105 virtual void set_width(); 106 107 // Comparison function needs to be pure virtual too 108 virtual bool changed() = 0; 109 110 // Got to declare this virtual as this will be overwritten 111 // by one base class 112 virtual void print_variable_declaration_line(FILE* f); 113 114 virtual ~wif_trace(); 115 116 const std::string name; // Name of the variable 117 const std::string wif_name; // Name of the variable in WIF file 118 const char* wif_type; // WIF data type 119 int bit_width; 120}; 121 122 123wif_trace::wif_trace(const std::string& name_, 124 const std::string& wif_name_) 125 : name(name_), wif_name(wif_name_), wif_type(0), bit_width(-1) 126{ 127 /* Intentionally blank */ 128} 129 130void 131wif_trace::print_variable_declaration_line( FILE* f ) 132{ 133 if( bit_width < 0 ) 134 { 135 std::stringstream ss; 136 ss << "'" << name << "' has < 0 bits"; 137 SC_REPORT_ERROR( SC_ID_TRACING_OBJECT_IGNORED_ 138 , ss.str().c_str() ); 139 return; 140 } 141 142 std::fprintf( f, "declare %s \"%s\" %s ", 143 wif_name.c_str(), name.c_str(), wif_type ); 144 145 if( bit_width > 0 ) { 146 std::fprintf( f, "0 %d ", bit_width - 1 ); 147 } 148 std::fprintf( f, "variable ;\n" ); 149 std::fprintf( f, "start_trace %s ;\n", wif_name.c_str() ); 150} 151 152void 153wif_trace::set_width() 154{ 155 /* Intentionally Blank, should be defined for each type separately */ 156} 157 158wif_trace::~wif_trace() 159{ 160 /* Intentionally Blank */ 161} 162 163// Classes for tracing individual data types 164 165/*****************************************************************************/ 166 167class wif_uint64_trace: public wif_trace { 168public: 169 wif_uint64_trace(const sc_dt::uint64& object_, 170 const std::string& name_, 171 const std::string& wif_name_, 172 int width_); 173 void write(FILE* f); 174 bool changed(); 175 176protected: 177 const sc_dt::uint64& object; 178 sc_dt::uint64 old_value; 179 sc_dt::uint64 mask; 180}; 181 182 183wif_uint64_trace::wif_uint64_trace(const sc_dt::uint64& object_, 184 const std::string& name_, 185 const std::string& wif_name_, 186 int width_) 187: wif_trace(name_, wif_name_), object(object_), old_value(object_), 188 mask(static_cast<sc_dt::uint64>(-1)) 189{ 190 bit_width = width_; 191 if (bit_width < (int)(sizeof(sc_dt::uint64)*BITS_PER_BYTE)) 192 mask = ~(mask << bit_width); 193 wif_type = "BIT"; 194} 195 196 197bool wif_uint64_trace::changed() 198{ 199 return object != old_value; 200} 201 202 203void wif_uint64_trace::write(FILE* f) 204{ 205 char buf[1000]; 206 int bitindex; 207 208 // Check for overflow 209 if ((object & mask) != object) 210 { 211 for (bitindex = 0; bitindex < bit_width; bitindex++) 212 { 213 buf[bitindex]='0'; 214 } 215 } 216 else 217 { 218 sc_dt::uint64 bit_mask = 1; 219 bit_mask = bit_mask << (bit_width-1); 220 for (bitindex = 0; bitindex < bit_width; bitindex++) 221 { 222 buf[bitindex] = (object & bit_mask)? '1' : '0'; 223 bit_mask = bit_mask >> 1; 224 } 225 } 226 buf[bitindex] = '\0'; 227 std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 228 old_value = object; 229} 230 231/*****************************************************************************/ 232 233class wif_int64_trace: public wif_trace { 234public: 235 wif_int64_trace(const sc_dt::int64& object_, 236 const std::string& name_, 237 const std::string& wif_name_, 238 int width_); 239 void write(FILE* f); 240 bool changed(); 241 242protected: 243 const sc_dt::int64& object; 244 sc_dt::int64 old_value; 245 sc_dt::uint64 mask; 246}; 247 248 249wif_int64_trace::wif_int64_trace(const sc_dt::int64& object_, 250 const std::string& name_, 251 const std::string& wif_name_, 252 int width_) 253: wif_trace(name_, wif_name_), object(object_), old_value(object_), 254 mask(static_cast<sc_dt::uint64>(-1)) 255{ 256 bit_width = width_; 257 if (bit_width < (int)(sizeof(sc_dt::int64)*BITS_PER_BYTE)) 258 mask = ~(mask << bit_width); 259 wif_type = "BIT"; 260} 261 262 263bool wif_int64_trace::changed() 264{ 265 return object != old_value; 266} 267 268 269void wif_int64_trace::write(FILE* f) 270{ 271 char buf[1000]; 272 int bitindex; 273 274 // Check for overflow 275 if ((object & mask) != (sc_dt::uint64)object) 276 { 277 for (bitindex = 0; bitindex < bit_width; bitindex++) 278 { 279 buf[bitindex]='0'; 280 } 281 } 282 else 283 { 284 sc_dt::uint64 bit_mask = 1; 285 bit_mask = bit_mask << (bit_width-1); 286 for (bitindex = 0; bitindex < bit_width; bitindex++) 287 { 288 buf[bitindex] = (object & bit_mask)? '1' : '0'; 289 bit_mask = bit_mask >> 1; 290 } 291 } 292 buf[bitindex] = '\0'; 293 std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 294 old_value = object; 295} 296 297/*****************************************************************************/ 298 299class wif_bool_trace 300: public wif_trace 301{ 302public: 303 304 wif_bool_trace( const bool& object_, 305 const std::string& name_, 306 const std::string& wif_name_ ); 307 void write( FILE* f ); 308 bool changed(); 309 310protected: 311 312 const bool& object; 313 bool old_value; 314}; 315 316wif_bool_trace::wif_bool_trace( const bool& object_, 317 const std::string& name_, 318 const std::string& wif_name_ ) 319: wif_trace( name_, wif_name_ ), object( object_ ), old_value( object_ ) 320{ 321 bit_width = 0; 322 wif_type = "BIT"; 323} 324 325bool 326wif_bool_trace::changed() 327{ 328 return object != old_value; 329} 330 331void 332wif_bool_trace::write( FILE* f ) 333{ 334 if( object == true ) { 335 std::fprintf( f, "assign %s \'1\' ;\n", wif_name.c_str() ); 336 } else { 337 std::fprintf( f, "assign %s \'0\' ;\n", wif_name.c_str() ); 338 } 339 old_value = object; 340} 341 342//***************************************************************************** 343 344class wif_sc_bit_trace : public wif_trace { 345public: 346 wif_sc_bit_trace(const sc_dt::sc_bit& object_, 347 const std::string& name_, 348 const std::string& wif_name_); 349 void write(FILE* f); 350 bool changed(); 351 352protected: 353 const sc_dt::sc_bit& object; 354 sc_dt::sc_bit old_value; 355}; 356 357wif_sc_bit_trace::wif_sc_bit_trace(const sc_dt::sc_bit& object_, 358 const std::string& name_, 359 const std::string& wif_name_) 360: wif_trace(name_, wif_name_), object(object_), old_value(object_) 361{ 362 bit_width = 0; 363 wif_type = "BIT"; 364} 365 366bool wif_sc_bit_trace::changed() 367{ 368 return object != old_value; 369} 370 371void wif_sc_bit_trace::write(FILE* f) 372{ 373 if (object == true) { 374 std::fprintf(f, "assign %s \'1\' ;\n", wif_name.c_str()); 375 } else { 376 std::fprintf(f, "assign %s \'0\' ;\n", wif_name.c_str()); 377 } 378 old_value = object; 379} 380 381/*****************************************************************************/ 382 383class wif_sc_logic_trace: public wif_trace { 384public: 385 wif_sc_logic_trace(const sc_dt::sc_logic& object_, 386 const std::string& name_, 387 const std::string& wif_name_); 388 void write(FILE* f); 389 bool changed(); 390 391protected: 392 const sc_dt::sc_logic& object; 393 sc_dt::sc_logic old_value; 394}; 395 396 397wif_sc_logic_trace::wif_sc_logic_trace(const sc_dt::sc_logic& object_, 398 const std::string& name_, 399 const std::string& wif_name_) 400: wif_trace(name_, wif_name_), object(object_), old_value(object_) 401{ 402 bit_width = 0; 403 wif_type = "MVL"; 404} 405 406 407bool wif_sc_logic_trace::changed() 408{ 409 return object != old_value; 410} 411 412 413void wif_sc_logic_trace::write(FILE* f) 414{ 415 char wif_char; 416 std::fprintf(f, "assign %s \'", wif_name.c_str()); 417 wif_char = map_sc_logic_state_to_wif_state(object.to_char()); 418 std::fputc(wif_char, f); 419 std::fprintf(f,"\' ;\n"); 420 old_value = object; 421} 422 423 424/*****************************************************************************/ 425 426class wif_sc_unsigned_trace: public wif_trace { 427public: 428 wif_sc_unsigned_trace(const sc_dt::sc_unsigned& object_, 429 const std::string& name_, 430 const std::string& wif_name_); 431 void write(FILE* f); 432 bool changed(); 433 void set_width(); 434 435protected: 436 const sc_dt::sc_unsigned& object; 437 sc_dt::sc_unsigned old_value; 438}; 439 440 441wif_sc_unsigned_trace::wif_sc_unsigned_trace(const sc_dt::sc_unsigned& object_, 442 const std::string& name_, 443 const std::string& wif_name_) 444: wif_trace(name_, wif_name_), object(object_), old_value(object_.length()) 445{ 446 old_value = object; 447 wif_type = "BIT"; 448} 449 450bool wif_sc_unsigned_trace::changed() 451{ 452 return object != old_value; 453} 454 455void wif_sc_unsigned_trace::write(FILE* f) 456{ 457 static std::vector<char> buf(1024); 458 typedef std::vector<char>::size_type size_t; 459 460 if ( buf.size() < (size_t)object.length() ) { 461 size_t sz = ( (size_t)object.length() + 4096 ) & (~(size_t)(4096-1)); 462 std::vector<char>( sz ).swap( buf ); // resize without copying values 463 } 464 char *buf_ptr = &buf[0]; 465 466 for(int bitindex = object.length() - 1; bitindex >= 0; --bitindex) { 467 *buf_ptr++ = "01"[object[bitindex].to_bool()]; 468 } 469 *buf_ptr = '\0'; 470 std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), &buf[0]); 471 old_value = object; 472} 473 474void wif_sc_unsigned_trace::set_width() 475{ 476 bit_width = object.length(); 477} 478 479 480/*****************************************************************************/ 481 482class wif_sc_signed_trace: public wif_trace { 483public: 484 wif_sc_signed_trace(const sc_dt::sc_signed& object_, 485 const std::string& name_, 486 const std::string& wif_name_); 487 void write(FILE* f); 488 bool changed(); 489 void set_width(); 490 491protected: 492 const sc_dt::sc_signed& object; 493 sc_dt::sc_signed old_value; 494}; 495 496 497wif_sc_signed_trace::wif_sc_signed_trace(const sc_dt::sc_signed& object_, 498 const std::string& name_, 499 const std::string& wif_name_) 500: wif_trace(name_, wif_name_), object(object_), old_value(object_.length()) 501{ 502 old_value = object; 503 wif_type = "BIT"; 504} 505 506bool wif_sc_signed_trace::changed() 507{ 508 return object != old_value; 509} 510 511void wif_sc_signed_trace::write(FILE* f) 512{ 513 static std::vector<char> buf(1024); 514 typedef std::vector<char>::size_type size_t; 515 516 if ( buf.size() < (size_t)object.length() ) { 517 size_t sz = ( (size_t)object.length() + 4096 ) & (~(size_t)(4096-1)); 518 std::vector<char>( sz ).swap( buf ); // resize without copying values 519 } 520 char *buf_ptr = &buf[0]; 521 522 for(int bitindex = object.length() - 1; bitindex >= 0; --bitindex) { 523 *buf_ptr++ = "01"[object[bitindex].to_bool()]; 524 } 525 *buf_ptr = '\0'; 526 527 std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), &buf[0]); 528 old_value = object; 529} 530 531void wif_sc_signed_trace::set_width() 532{ 533 bit_width = object.length(); 534} 535 536/*****************************************************************************/ 537 538class wif_sc_uint_base_trace: public wif_trace { 539public: 540 wif_sc_uint_base_trace(const sc_dt::sc_uint_base& object_, 541 const std::string& name_, 542 const std::string& wif_name_); 543 void write(FILE* f); 544 bool changed(); 545 void set_width(); 546 547protected: 548 const sc_dt::sc_uint_base& object; 549 sc_dt::sc_uint_base old_value; 550}; 551 552 553wif_sc_uint_base_trace::wif_sc_uint_base_trace( 554 const sc_dt::sc_uint_base& object_, 555 const std::string& name_, 556 const std::string& wif_name_) 557: wif_trace(name_, wif_name_), object(object_), old_value(object_.length()) 558{ 559 old_value = object; 560 wif_type = "BIT"; 561} 562 563bool wif_sc_uint_base_trace::changed() 564{ 565 return object != old_value; 566} 567 568void wif_sc_uint_base_trace::write(FILE* f) 569{ 570 char buf[1000], *buf_ptr = buf; 571 572 int bitindex; 573 for(bitindex = object.length() - 1; bitindex >= 0; --bitindex) { 574 *buf_ptr++ = "01"[object[bitindex].to_bool()]; 575 } 576 *buf_ptr = '\0'; 577 std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 578 old_value = object; 579} 580 581void wif_sc_uint_base_trace::set_width() 582{ 583 bit_width = object.length(); 584} 585 586 587/*****************************************************************************/ 588 589class wif_sc_int_base_trace: public wif_trace { 590public: 591 wif_sc_int_base_trace(const sc_dt::sc_int_base& object_, 592 const std::string& name_, 593 const std::string& wif_name_); 594 void write(FILE* f); 595 bool changed(); 596 void set_width(); 597 598protected: 599 const sc_dt::sc_int_base& object; 600 sc_dt::sc_int_base old_value; 601}; 602 603 604wif_sc_int_base_trace::wif_sc_int_base_trace(const sc_dt::sc_int_base& object_, 605 const std::string& name_, 606 const std::string& wif_name_) 607: wif_trace(name_, wif_name_), object(object_), old_value(object_.length()) 608{ 609 old_value = object; 610 wif_type = "BIT"; 611} 612 613bool wif_sc_int_base_trace::changed() 614{ 615 return object != old_value; 616} 617 618void wif_sc_int_base_trace::write(FILE* f) 619{ 620 char buf[1000], *buf_ptr = buf; 621 622 int bitindex; 623 for(bitindex = object.length() - 1; bitindex >= 0; --bitindex) { 624 *buf_ptr++ = "01"[object[bitindex].to_bool()]; 625 } 626 *buf_ptr = '\0'; 627 628 std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 629 old_value = object; 630} 631 632void wif_sc_int_base_trace::set_width() 633{ 634 bit_width = object.length(); 635} 636 637 638/*****************************************************************************/ 639 640class wif_sc_fxval_trace: public wif_trace 641{ 642public: 643 644 wif_sc_fxval_trace( const sc_dt::sc_fxval& object_, 645 const std::string& name_, 646 const std::string& wif_name_ ); 647 void write( FILE* f ); 648 bool changed(); 649 650protected: 651 652 const sc_dt::sc_fxval& object; 653 sc_dt::sc_fxval old_value; 654 655}; 656 657wif_sc_fxval_trace::wif_sc_fxval_trace( const sc_dt::sc_fxval& object_, 658 const std::string& name_, 659 const std::string& wif_name_ ) 660: wif_trace( name_, wif_name_ ), object( object_ ), old_value( object_ ) 661{ 662 bit_width = 0; 663 wif_type = "real"; 664} 665 666bool 667wif_sc_fxval_trace::changed() 668{ 669 return object != old_value; 670} 671 672void 673wif_sc_fxval_trace::write( FILE* f ) 674{ 675 std::fprintf( f, "assign %s %f ; \n", wif_name.c_str(), object.to_double() ); 676 old_value = object; 677} 678 679/*****************************************************************************/ 680 681class wif_sc_fxval_fast_trace: public wif_trace 682{ 683public: 684 685 wif_sc_fxval_fast_trace( const sc_dt::sc_fxval_fast& object_, 686 const std::string& name_, 687 const std::string& wif_name_ ); 688 void write( FILE* f ); 689 bool changed(); 690 691protected: 692 693 const sc_dt::sc_fxval_fast& object; 694 sc_dt::sc_fxval_fast old_value; 695 696}; 697 698wif_sc_fxval_fast_trace::wif_sc_fxval_fast_trace( 699 const sc_dt::sc_fxval_fast& object_, 700 const std::string& name_, 701 const std::string& wif_name_ ) 702: wif_trace(name_, wif_name_), object( object_ ), old_value( object_ ) 703{ 704 bit_width = 0; 705 wif_type = "real"; 706} 707 708bool 709wif_sc_fxval_fast_trace::changed() 710{ 711 return object != old_value; 712} 713 714void 715wif_sc_fxval_fast_trace::write( FILE* f ) 716{ 717 std::fprintf( f, "assign %s %f ; \n", wif_name.c_str(), object.to_double() ); 718 old_value = object; 719} 720 721/*****************************************************************************/ 722 723class wif_sc_fxnum_trace: public wif_trace 724{ 725public: 726 727 wif_sc_fxnum_trace( const sc_dt::sc_fxnum& object_, 728 const std::string& name_, 729 const std::string& wif_name_ ); 730 void write( FILE* f ); 731 bool changed(); 732 void set_width(); 733 734protected: 735 736 const sc_dt::sc_fxnum& object; 737 sc_dt::sc_fxnum old_value; 738 739}; 740 741wif_sc_fxnum_trace::wif_sc_fxnum_trace( const sc_dt::sc_fxnum& object_, 742 const std::string& name_, 743 const std::string& wif_name_ ) 744: wif_trace( name_, wif_name_ ), 745 object( object_ ), 746 old_value( object_.m_params.type_params(), 747 object_.m_params.enc(), 748 object_.m_params.cast_switch(), 749 0 ) 750{ 751 old_value = object; 752 wif_type = "BIT"; 753} 754 755bool 756wif_sc_fxnum_trace::changed() 757{ 758 return object != old_value; 759} 760 761void 762wif_sc_fxnum_trace::write( FILE* f ) 763{ 764 static std::vector<char> buf(1024); 765 typedef std::vector<char>::size_type size_t; 766 767 if ( buf.size() < (size_t)object.wl() ) { 768 size_t sz = ( (size_t)object.wl() + 4096 ) & (~(size_t)(4096-1)); 769 std::vector<char>( sz ).swap( buf ); // resize without copying values 770 } 771 char *buf_ptr = &buf[0]; 772 773 for(int bitindex = object.wl() - 1; bitindex >= 0; --bitindex) 774 { 775 *buf_ptr ++ = "01"[object[bitindex]]; 776 } 777 *buf_ptr = '\0'; 778 779 std::fprintf( f, "assign %s \"%s\" ;\n", wif_name.c_str(), &buf[0]); 780 old_value = object; 781} 782 783void 784wif_sc_fxnum_trace::set_width() 785{ 786 bit_width = object.wl(); 787} 788 789/*****************************************************************************/ 790 791class wif_sc_fxnum_fast_trace: public wif_trace 792{ 793public: 794 795 wif_sc_fxnum_fast_trace( const sc_dt::sc_fxnum_fast& object_, 796 const std::string& name_, 797 const std::string& wif_name_ ); 798 void write( FILE* f ); 799 bool changed(); 800 void set_width(); 801 802protected: 803 804 const sc_dt::sc_fxnum_fast& object; 805 sc_dt::sc_fxnum_fast old_value; 806 807}; 808 809wif_sc_fxnum_fast_trace::wif_sc_fxnum_fast_trace( 810 const sc_dt::sc_fxnum_fast& object_, 811 const std::string& name_, 812 const std::string& wif_name_ ) 813: wif_trace( name_, wif_name_ ), 814 object( object_ ), 815 old_value( object_.m_params.type_params(), 816 object_.m_params.enc(), 817 object_.m_params.cast_switch(), 818 0 ) 819{ 820 old_value = object; 821 wif_type = "BIT"; 822} 823 824bool 825wif_sc_fxnum_fast_trace::changed() 826{ 827 return object != old_value; 828} 829 830void 831wif_sc_fxnum_fast_trace::write( FILE* f ) 832{ 833 static std::vector<char> buf(1024); 834 typedef std::vector<char>::size_type size_t; 835 836 if ( buf.size() < (size_t)object.wl() ) { 837 size_t sz = ( (size_t)object.wl() + 4096 ) & (~(size_t)(4096-1)); 838 std::vector<char>( sz ).swap( buf ); // resize without copying values 839 } 840 char *buf_ptr = &buf[0]; 841 842 for(int bitindex = object.wl() - 1; bitindex >= 0; --bitindex) 843 { 844 *buf_ptr ++ = "01"[object[bitindex]]; 845 } 846 *buf_ptr = '\0'; 847 848 std::fprintf( f, "assign %s \"%s\" ;\n", wif_name.c_str(), &buf[0]); 849 old_value = object; 850} 851 852void 853wif_sc_fxnum_fast_trace::set_width() 854{ 855 bit_width = object.wl(); 856} 857 858 859/*****************************************************************************/ 860 861class wif_unsigned_int_trace: public wif_trace { 862public: 863 wif_unsigned_int_trace(const unsigned& object_, 864 const std::string& name_, 865 const std::string& wif_name_, int width_); 866 void write(FILE* f); 867 bool changed(); 868 869protected: 870 const unsigned& object; 871 unsigned old_value; 872 unsigned mask; 873}; 874 875 876wif_unsigned_int_trace::wif_unsigned_int_trace(const unsigned& object_, 877 const std::string& name_, 878 const std::string& wif_name_, 879 int width_) 880: wif_trace(name_, wif_name_), object(object_), old_value(object_), 881 mask(0xffffffff) 882{ 883 bit_width = width_; 884 if (bit_width < 32) { 885 mask = ~(-1 << bit_width); 886 } 887 888 wif_type = "BIT"; 889} 890 891 892bool wif_unsigned_int_trace::changed() 893{ 894 return object != old_value; 895} 896 897 898void wif_unsigned_int_trace::write(FILE* f) 899{ 900 char buf[1000]; 901 int bitindex; 902 903 // Check for overflow 904 if ((object & mask) != object) { 905 for (bitindex = 0; bitindex < bit_width; bitindex++){ 906 buf[bitindex] = '0'; 907 } 908 } 909 else{ 910 unsigned bit_mask = 1 << (bit_width-1); 911 for (bitindex = 0; bitindex < bit_width; bitindex++) { 912 buf[bitindex] = (object & bit_mask)? '1' : '0'; 913 bit_mask = bit_mask >> 1; 914 } 915 } 916 buf[bitindex] = '\0'; 917 std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 918 old_value = object; 919} 920 921 922/*****************************************************************************/ 923 924class wif_unsigned_short_trace: public wif_trace { 925public: 926 wif_unsigned_short_trace(const unsigned short& object_, 927 const std::string& name_, 928 const std::string& wif_name_, 929 int width_); 930 void write(FILE* f); 931 bool changed(); 932 933protected: 934 const unsigned short& object; 935 unsigned short old_value; 936 unsigned short mask; 937}; 938 939 940wif_unsigned_short_trace::wif_unsigned_short_trace( 941 const unsigned short& object_, 942 const std::string& name_, 943 const std::string& wif_name_, 944 int width_) 945: wif_trace(name_, wif_name_), object(object_), old_value(object_), mask(0xffff) 946{ 947 bit_width = width_; 948 if (bit_width < 16) { 949 mask = (unsigned short)~(-1 << bit_width); 950 } 951 952 wif_type = "BIT"; 953} 954 955 956bool wif_unsigned_short_trace::changed() 957{ 958 return object != old_value; 959} 960 961 962void wif_unsigned_short_trace::write(FILE* f) 963{ 964 char buf[1000]; 965 int bitindex; 966 967 // Check for overflow 968 if ((object & mask) != object) { 969 for (bitindex = 0; bitindex < bit_width; bitindex++){ 970 buf[bitindex]='0'; 971 } 972 } 973 else{ 974 unsigned bit_mask = 1 << (bit_width-1); 975 for (bitindex = 0; bitindex < bit_width; bitindex++) { 976 buf[bitindex] = (object & bit_mask)? '1' : '0'; 977 bit_mask = bit_mask >> 1; 978 } 979 } 980 buf[bitindex] = '\0'; 981 std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 982 old_value = object; 983} 984 985/*****************************************************************************/ 986 987class wif_unsigned_char_trace: public wif_trace { 988public: 989 wif_unsigned_char_trace(const unsigned char& object_, 990 const std::string& name_, 991 const std::string& wif_name_, 992 int width_); 993 void write(FILE* f); 994 bool changed(); 995 996protected: 997 const unsigned char& object; 998 unsigned char old_value; 999 unsigned char mask; 1000}; 1001 1002 1003wif_unsigned_char_trace::wif_unsigned_char_trace(const unsigned char& object_, 1004 const std::string& name_, 1005 const std::string& wif_name_, 1006 int width_) 1007: wif_trace(name_, wif_name_), object(object_), old_value(object_), mask(0xff) 1008{ 1009 bit_width = width_; 1010 if (bit_width < 8) { 1011 mask = (unsigned char)~(-1 << bit_width); 1012 } 1013 1014 wif_type = "BIT"; 1015} 1016 1017 1018bool wif_unsigned_char_trace::changed() 1019{ 1020 return object != old_value; 1021} 1022 1023 1024void wif_unsigned_char_trace::write(FILE* f) 1025{ 1026 char buf[1000]; 1027 int bitindex; 1028 1029 // Check for overflow 1030 if ((object & mask) != object) { 1031 for (bitindex = 0; bitindex < bit_width; bitindex++){ 1032 buf[bitindex]='0'; 1033 } 1034 } 1035 else{ 1036 unsigned bit_mask = 1 << (bit_width-1); 1037 for (bitindex = 0; bitindex < bit_width; bitindex++) { 1038 buf[bitindex] = (object & bit_mask)? '1' : '0'; 1039 bit_mask = bit_mask >> 1; 1040 } 1041 } 1042 buf[bitindex] = '\0'; 1043 std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 1044 old_value = object; 1045} 1046 1047/*****************************************************************************/ 1048 1049class wif_unsigned_long_trace: public wif_trace { 1050public: 1051 wif_unsigned_long_trace(const unsigned long& object_, 1052 const std::string& name_, 1053 const std::string& wif_name_, 1054 int width_); 1055 void write(FILE* f); 1056 bool changed(); 1057 1058protected: 1059 const unsigned long& object; 1060 unsigned long old_value; 1061 unsigned long mask; 1062}; 1063 1064 1065wif_unsigned_long_trace::wif_unsigned_long_trace(const unsigned long& object_, 1066 const std::string& name_, 1067 const std::string& wif_name_, 1068 int width_) 1069: wif_trace(name_, wif_name_), object(object_), old_value(object_), 1070 mask((unsigned long)-1L) 1071{ 1072 bit_width = width_; 1073 if (bit_width < (int)(sizeof(unsigned long)*BITS_PER_BYTE)) { 1074 mask = ~(-1L << bit_width); 1075 } 1076 1077 wif_type = "BIT"; 1078} 1079 1080 1081bool wif_unsigned_long_trace::changed() 1082{ 1083 return object != old_value; 1084} 1085 1086 1087void wif_unsigned_long_trace::write(FILE* f) 1088{ 1089 char buf[1000]; 1090 int bitindex; 1091 1092 // Check for overflow 1093 if ((object & mask) != object) { 1094 for (bitindex = 0; bitindex < bit_width; bitindex++){ 1095 buf[bitindex]='0'; 1096 } 1097 } 1098 else{ 1099 unsigned long bit_mask = 1ul << (bit_width-1); 1100 for (bitindex = 0; bitindex < bit_width; bitindex++) { 1101 buf[bitindex] = (object & bit_mask)? '1' : '0'; 1102 bit_mask = bit_mask >> 1; 1103 } 1104 } 1105 buf[bitindex] = '\0'; 1106 std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 1107 old_value = object; 1108} 1109 1110/*****************************************************************************/ 1111 1112class wif_signed_int_trace: public wif_trace { 1113public: 1114 wif_signed_int_trace(const int& object_, 1115 const std::string& name_, 1116 const std::string& wif_name_, 1117 int width_); 1118 void write(FILE* f); 1119 bool changed(); 1120 1121protected: 1122 const int& object; 1123 int old_value; 1124 unsigned mask; 1125}; 1126 1127 1128wif_signed_int_trace::wif_signed_int_trace(const signed& object_, 1129 const std::string& name_, 1130 const std::string& wif_name_, 1131 int width_) 1132: wif_trace(name_, wif_name_), object(object_), old_value(object_), 1133 mask(0xffffffff) 1134{ 1135 bit_width = width_; 1136 if (bit_width < 32) { 1137 mask = ~(-1 << bit_width); 1138 } 1139 1140 wif_type = "BIT"; 1141} 1142 1143 1144bool wif_signed_int_trace::changed() 1145{ 1146 return object != old_value; 1147} 1148 1149 1150void wif_signed_int_trace::write(FILE* f) 1151{ 1152 char buf[1000]; 1153 int bitindex; 1154 1155 // Check for overflow 1156 if (((unsigned) object & mask) != (unsigned) object) { 1157 for (bitindex = 0; bitindex < bit_width; bitindex++){ 1158 buf[bitindex]='0'; 1159 } 1160 } 1161 else{ 1162 unsigned bit_mask = 1 << (bit_width-1); 1163 for (bitindex = 0; bitindex < bit_width; bitindex++) { 1164 buf[bitindex] = (object & bit_mask)? '1' : '0'; 1165 bit_mask = bit_mask >> 1; 1166 } 1167 } 1168 buf[bitindex] = '\0'; 1169 std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 1170 old_value = object; 1171} 1172 1173/*****************************************************************************/ 1174 1175class wif_signed_short_trace: public wif_trace { 1176public: 1177 wif_signed_short_trace(const short& object_, 1178 const std::string& name_, 1179 const std::string& wif_name_, 1180 int width_); 1181 void write(FILE* f); 1182 bool changed(); 1183 1184protected: 1185 const short& object; 1186 short old_value; 1187 unsigned short mask; 1188}; 1189 1190 1191wif_signed_short_trace::wif_signed_short_trace(const short& object_, 1192 const std::string& name_, 1193 const std::string& wif_name_, 1194 int width_) 1195: wif_trace(name_, wif_name_), object(object_), old_value(object_), mask(0xffff) 1196{ 1197 bit_width = width_; 1198 if (bit_width < 16) { 1199 mask = (unsigned short)~(-1 << bit_width); 1200 } 1201 1202 wif_type = "BIT"; 1203} 1204 1205 1206bool wif_signed_short_trace::changed() 1207{ 1208 return object != old_value; 1209} 1210 1211 1212void wif_signed_short_trace::write(FILE* f) 1213{ 1214 char buf[1000]; 1215 int bitindex; 1216 1217 // Check for overflow 1218 if (((unsigned short) object & mask) != (unsigned short) object) { 1219 for (bitindex = 0; bitindex < bit_width; bitindex++){ 1220 buf[bitindex]='0'; 1221 } 1222 } 1223 else{ 1224 unsigned bit_mask = 1 << (bit_width-1); 1225 for (bitindex = 0; bitindex < bit_width; bitindex++) { 1226 buf[bitindex] = (object & bit_mask)? '1' : '0'; 1227 bit_mask = bit_mask >> 1; 1228 } 1229 } 1230 buf[bitindex] = '\0'; 1231 std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 1232 old_value = object; 1233} 1234 1235/*****************************************************************************/ 1236 1237class wif_signed_char_trace: public wif_trace { 1238public: 1239 wif_signed_char_trace(const char& object_, 1240 const std::string& name_, 1241 const std::string& wif_name_, 1242 int width_); 1243 void write(FILE* f); 1244 bool changed(); 1245 1246protected: 1247 const char& object; 1248 char old_value; 1249 unsigned char mask; 1250}; 1251 1252 1253wif_signed_char_trace::wif_signed_char_trace(const char& object_, 1254 const std::string& name_, 1255 const std::string& wif_name_, 1256 int width_) 1257: wif_trace(name_, wif_name_), object(object_), old_value(object_), mask(0xff) 1258{ 1259 bit_width = width_; 1260 if (bit_width < 8) { 1261 mask = (unsigned char)~(-1 << bit_width); 1262 } 1263 1264 wif_type = "BIT"; 1265} 1266 1267 1268bool wif_signed_char_trace::changed() 1269{ 1270 return object != old_value; 1271} 1272 1273 1274void wif_signed_char_trace::write(FILE* f) 1275{ 1276 char buf[1000]; 1277 int bitindex; 1278 1279 // Check for overflow 1280 if (((unsigned char) object & mask) != (unsigned char) object) { 1281 for (bitindex = 0; bitindex < bit_width; bitindex++){ 1282 buf[bitindex]='0'; 1283 } 1284 } 1285 else{ 1286 unsigned bit_mask = 1 << (bit_width-1); 1287 for (bitindex = 0; bitindex < bit_width; bitindex++) { 1288 buf[bitindex] = (object & bit_mask)? '1' : '0'; 1289 bit_mask = bit_mask >> 1; 1290 } 1291 } 1292 buf[bitindex] = '\0'; 1293 std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 1294 old_value = object; 1295} 1296 1297/*****************************************************************************/ 1298 1299class wif_signed_long_trace: public wif_trace { 1300public: 1301 wif_signed_long_trace(const long& object_, 1302 const std::string& name_, 1303 const std::string& wif_name_, 1304 int width_); 1305 void write(FILE* f); 1306 bool changed(); 1307 1308protected: 1309 const long& object; 1310 long old_value; 1311 unsigned long mask; 1312}; 1313 1314 1315wif_signed_long_trace::wif_signed_long_trace(const long& object_, 1316 const std::string& name_, 1317 const std::string& wif_name_, 1318 int width_) 1319: wif_trace(name_, wif_name_), object(object_), old_value(object_), 1320 mask((unsigned long)-1L) 1321{ 1322 bit_width = width_; 1323 if (bit_width < (int)(sizeof(long)*BITS_PER_BYTE)) { 1324 mask = ~(-1L << bit_width); 1325 } 1326 1327 wif_type = "BIT"; 1328} 1329 1330 1331bool wif_signed_long_trace::changed() 1332{ 1333 return object != old_value; 1334} 1335 1336 1337void wif_signed_long_trace::write(FILE* f) 1338{ 1339 char buf[1000]; 1340 int bitindex; 1341 1342 // Check for overflow 1343 if (((unsigned long) object & mask) != (unsigned long) object) { 1344 for (bitindex = 0; bitindex < bit_width; bitindex++){ 1345 buf[bitindex]='0'; 1346 } 1347 } else { 1348 unsigned long bit_mask = 1ul << (bit_width-1); 1349 for (bitindex = 0; bitindex < bit_width; bitindex++) { 1350 buf[bitindex] = (object & bit_mask)? '1' : '0'; 1351 bit_mask = bit_mask >> 1; 1352 } 1353 } 1354 buf[bitindex] = '\0'; 1355 std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 1356 old_value = object; 1357} 1358 1359 1360/*****************************************************************************/ 1361 1362class wif_float_trace: public wif_trace { 1363public: 1364 wif_float_trace(const float& object_, 1365 const std::string& name_, 1366 const std::string& wif_name_); 1367 void write(FILE* f); 1368 bool changed(); 1369 1370protected: 1371 const float& object; 1372 float old_value; 1373}; 1374 1375wif_float_trace::wif_float_trace(const float& object_, 1376 const std::string& name_, 1377 const std::string& wif_name_) 1378: wif_trace(name_, wif_name_), object(object_), old_value(object_) 1379{ 1380 bit_width = 0; 1381 wif_type = "real"; 1382} 1383 1384bool wif_float_trace::changed() 1385{ 1386 return object != old_value; 1387} 1388 1389void wif_float_trace::write(FILE* f) 1390{ 1391 std::fprintf(f,"assign %s %f ; \n", wif_name.c_str(), object); 1392 old_value = object; 1393} 1394 1395/*****************************************************************************/ 1396 1397class wif_double_trace: public wif_trace { 1398public: 1399 wif_double_trace(const double& object_, 1400 const std::string& name_, 1401 const std::string& wif_name_); 1402 void write(FILE* f); 1403 bool changed(); 1404 1405protected: 1406 const double& object; 1407 double old_value; 1408}; 1409 1410wif_double_trace::wif_double_trace(const double& object_, 1411 const std::string& name_, 1412 const std::string& wif_name_) 1413: wif_trace(name_, wif_name_), object(object_), old_value(object_) 1414{ 1415 bit_width = 0; 1416 wif_type = "real"; 1417} 1418 1419bool wif_double_trace::changed() 1420{ 1421 return object != old_value; 1422} 1423 1424void wif_double_trace::write(FILE* f) 1425{ 1426 std::fprintf(f,"assign %s %f ; \n", wif_name.c_str(), object); 1427 old_value = object; 1428} 1429 1430 1431/*****************************************************************************/ 1432 1433class wif_enum_trace : public wif_trace { 1434public: 1435 wif_enum_trace(const unsigned& object_, 1436 const std::string& name_, 1437 const std::string& wif_name_, 1438 const char** enum_literals); 1439 void write(FILE* f); 1440 bool changed(); 1441 // Hides the definition of the same (virtual) function in wif_trace 1442 void print_variable_declaration_line(FILE* f); 1443 1444protected: 1445 const unsigned& object; 1446 unsigned old_value; 1447 1448 const char** literals; 1449 unsigned nliterals; 1450 std::string type_name; 1451 1452 ~wif_enum_trace(); 1453}; 1454 1455 1456wif_enum_trace::wif_enum_trace(const unsigned& object_, 1457 const std::string& name_, 1458 const std::string& wif_name_, 1459 const char** enum_literals_) 1460: wif_trace(name_, wif_name_), object(object_), old_value(object_), 1461 literals(enum_literals_), nliterals(0), type_name(name_ + "__type__") 1462{ 1463 // find number of enumeration literals - counting loop 1464 for (nliterals = 0; enum_literals_[nliterals]; nliterals++) continue; 1465 1466 bit_width = 0; 1467 wif_type = type_name.c_str(); 1468} 1469 1470void wif_enum_trace::print_variable_declaration_line(FILE* f) 1471{ 1472 std::fprintf(f, "type scalar \"%s\" enum ", wif_type); 1473 1474 for (unsigned i = 0; i < nliterals; i++) 1475 std::fprintf(f, "\"%s\", ", literals[i]); 1476 std::fprintf(f, "\"SC_WIF_UNDEF\" ;\n"); 1477 1478 std::fprintf(f, "declare %s \"%s\" \"%s\" ", 1479 wif_name.c_str(), name.c_str(), wif_type); 1480 std::fprintf(f, "variable ;\n"); 1481 std::fprintf(f, "start_trace %s ;\n", wif_name.c_str()); 1482} 1483 1484bool wif_enum_trace::changed() 1485{ 1486 return object != old_value; 1487} 1488 1489void wif_enum_trace::write(FILE* f) 1490{ 1491 static bool warning_issued = false; 1492 const char* lit; 1493 1494 if (object >= nliterals) { // Note unsigned value is always greater than 0 1495 if (!warning_issued) { 1496 SC_REPORT_WARNING( SC_ID_TRACING_INVALID_ENUM_VALUE_ 1497 , name.c_str() ); 1498 warning_issued = true; 1499 } 1500 lit = "SC_WIF_UNDEF"; 1501 } 1502 else 1503 { 1504 lit = literals[object]; 1505 } 1506 std::fprintf( f, "assign %s \"%s\" ;\n", wif_name.c_str(), lit ); 1507 old_value = object; 1508} 1509 1510wif_enum_trace::~wif_enum_trace() 1511{ 1512 /* Intentionally blank */ 1513} 1514 1515 1516template <class T> 1517class wif_T_trace 1518: public wif_trace 1519{ 1520public: 1521 1522 wif_T_trace( const T& object_, 1523 const std::string& name_, 1524 const std::string& wif_name_, 1525 wif_trace_file::wif_enum type_ ) 1526 : wif_trace( name_, wif_name_), 1527 object( object_ ), 1528 old_value( object_ ) 1529 { wif_type = wif_names[type_]; } 1530 1531 void write( FILE* f ) 1532 { 1533 std::fprintf( f, 1534 "assign %s \"%s\" ;\n", 1535 wif_name.c_str(), 1536 object.to_string().c_str() ); 1537 old_value = object; 1538 } 1539 1540 bool changed() 1541 { return !(object == old_value); } 1542 1543 void set_width() 1544 { bit_width = object.length(); } 1545 1546protected: 1547 1548 const T& object; 1549 T old_value; 1550}; 1551 1552typedef wif_T_trace<sc_dt::sc_bv_base> wif_sc_bv_trace; 1553typedef wif_T_trace<sc_dt::sc_lv_base> wif_sc_lv_trace; 1554 1555 1556//*********************************************************************** 1557// wif_trace_file functions 1558//*********************************************************************** 1559 1560 1561wif_trace_file::wif_trace_file(const char * name) 1562 : sc_trace_file_base( name, "awif" ) 1563 , wif_name_index(0) 1564 , previous_time_units_low(0) 1565 , previous_time_units_high(0) 1566 , previous_time(0.0) 1567 , traces() 1568{} 1569 1570 1571void wif_trace_file::do_initialize() 1572{ 1573 char buf[2000]; 1574 1575 // init 1576 std::fprintf(fp, "init ;\n\n"); 1577 1578 //timescale: 1579 if (timescale_unit == 1e-15) std::sprintf(buf,"0"); 1580 else if(timescale_unit == 1e-14) std::sprintf(buf,"1"); 1581 else if(timescale_unit == 1e-13) std::sprintf(buf,"2"); 1582 else if(timescale_unit == 1e-12) std::sprintf(buf,"3"); 1583 else if(timescale_unit == 1e-11) std::sprintf(buf,"4"); 1584 else if(timescale_unit == 1e-10) std::sprintf(buf,"5"); 1585 else if(timescale_unit == 1e-9) std::sprintf(buf,"6"); 1586 else if(timescale_unit == 1e-8) std::sprintf(buf,"7"); 1587 else if(timescale_unit == 1e-7) std::sprintf(buf,"8"); 1588 else if(timescale_unit == 1e-6) std::sprintf(buf,"9"); 1589 else if(timescale_unit == 1e-5) std::sprintf(buf,"10"); 1590 else if(timescale_unit == 1e-4) std::sprintf(buf,"11"); 1591 else if(timescale_unit == 1e-3) std::sprintf(buf,"12"); 1592 else if(timescale_unit == 1e-2) std::sprintf(buf,"13"); 1593 else if(timescale_unit == 1e-1) std::sprintf(buf,"14"); 1594 else if(timescale_unit == 1e0) std::sprintf(buf,"15"); 1595 else if(timescale_unit == 1e1) std::sprintf(buf,"16"); 1596 else if(timescale_unit == 1e2) std::sprintf(buf,"17"); 1597 std::fprintf(fp,"header %s \"%s\" ;\n\n", buf, sc_version()); 1598 1599 std::fprintf(fp, "comment \"ASCII WIF file produced on date: %s\" ;\n" 1600 , localtime_string().c_str()); 1601 1602 //version: 1603 std::fprintf(fp, "comment \"Created by %s\" ;\n", sc_version()); 1604 //conversion info 1605 std::fprintf(fp, "comment \"Convert this file to binary WIF format using a2wif\" ;\n\n"); 1606 1607 // Define the two types we need to represent bool and sc_logic 1608 std::fprintf(fp, "type scalar \"BIT\" enum '0', '1' ;\n"); 1609 std::fprintf(fp, "type scalar \"MVL\" enum '0', '1', 'X', 'Z', '?' ;\n"); 1610 std::fprintf(fp, "\n"); 1611 1612 //variable definitions: 1613 int i; 1614 for (i = 0; i < (int)traces.size(); i++) { 1615 wif_trace* t = traces[i]; 1616 t->set_width(); //needed for all vectors 1617 t->print_variable_declaration_line(fp); 1618 } 1619 1620 double inittime = sc_time_stamp().to_seconds(); 1621 previous_time = inittime/timescale_unit; 1622 1623 // Dump all values at initial time 1624 std::sprintf(buf, 1625 "All initial values are dumped below at time " 1626 "%g sec = %g timescale units.", 1627 inittime, 1628 inittime/timescale_unit 1629 ); 1630 write_comment(buf); 1631 1632 double_to_special_int64(inittime/timescale_unit, 1633 &previous_time_units_high, 1634 &previous_time_units_low ); 1635 1636 for (i = 0; i < (int)traces.size(); i++) { 1637 wif_trace* t = traces[i]; 1638 t->write(fp); 1639 } 1640} 1641 1642// ---------------------------------------------------------------------------- 1643 1644#define DEFN_TRACE_METHOD(tp) \ 1645void \ 1646wif_trace_file::trace( const tp& object_, const std::string& name_ ) \ 1647{ \ 1648 if( add_trace_check(name_) ) \ 1649 traces.push_back( new wif_ ## tp ## _trace( object_, \ 1650 name_, \ 1651 obtain_name() ) ); \ 1652} 1653 1654DEFN_TRACE_METHOD(bool) 1655DEFN_TRACE_METHOD(float) 1656DEFN_TRACE_METHOD(double) 1657 1658#undef DEFN_TRACE_METHOD 1659#define DEFN_TRACE_METHOD(tp) \ 1660void \ 1661wif_trace_file::trace(const sc_dt::tp& object_, const std::string& name_) \ 1662{ \ 1663 if( add_trace_check(name_) ) \ 1664 traces.push_back( new wif_ ## tp ## _trace( object_, \ 1665 name_, \ 1666 obtain_name() ) ); \ 1667} 1668 1669DEFN_TRACE_METHOD(sc_bit) 1670DEFN_TRACE_METHOD(sc_logic) 1671 1672DEFN_TRACE_METHOD(sc_signed) 1673DEFN_TRACE_METHOD(sc_unsigned) 1674DEFN_TRACE_METHOD(sc_int_base) 1675DEFN_TRACE_METHOD(sc_uint_base) 1676 1677DEFN_TRACE_METHOD(sc_fxval) 1678DEFN_TRACE_METHOD(sc_fxval_fast) 1679DEFN_TRACE_METHOD(sc_fxnum) 1680DEFN_TRACE_METHOD(sc_fxnum_fast) 1681 1682#undef DEFN_TRACE_METHOD 1683 1684 1685#define DEFN_TRACE_METHOD_SIGNED(tp) \ 1686void \ 1687wif_trace_file::trace( const tp& object_, \ 1688 const std::string& name_, \ 1689 int width_ ) \ 1690{ \ 1691 if( add_trace_check(name_) ) \ 1692 traces.push_back( new wif_signed_ ## tp ## _trace( object_, \ 1693 name_, \ 1694 obtain_name(), \ 1695 width_ ) ); \ 1696} 1697 1698#define DEFN_TRACE_METHOD_UNSIGNED(tp) \ 1699void \ 1700wif_trace_file::trace( const unsigned tp& object_, \ 1701 const std::string& name_, \ 1702 int width_ ) \ 1703{ \ 1704 if( add_trace_check(name_) ) \ 1705 traces.push_back( new wif_unsigned_ ## tp ## _trace( object_, \ 1706 name_, \ 1707 obtain_name(), \ 1708 width_ ) ); \ 1709} 1710 1711DEFN_TRACE_METHOD_SIGNED(char) 1712DEFN_TRACE_METHOD_SIGNED(short) 1713DEFN_TRACE_METHOD_SIGNED(int) 1714DEFN_TRACE_METHOD_SIGNED(long) 1715 1716DEFN_TRACE_METHOD_UNSIGNED(char) 1717DEFN_TRACE_METHOD_UNSIGNED(short) 1718DEFN_TRACE_METHOD_UNSIGNED(int) 1719DEFN_TRACE_METHOD_UNSIGNED(long) 1720 1721#undef DEFN_TRACE_METHOD_SIGNED 1722#undef DEFN_TRACE_METHOD_UNSIGNED 1723 1724 1725#define DEFN_TRACE_METHOD_LONG_LONG(tp) \ 1726void \ 1727wif_trace_file::trace( const sc_dt::tp& object_, \ 1728 const std::string& name_, \ 1729 int width_ ) \ 1730{ \ 1731 if( add_trace_check(name_) ) \ 1732 traces.push_back( new wif_ ## tp ## _trace( object_, \ 1733 name_, \ 1734 obtain_name(), \ 1735 width_ ) ); \ 1736} 1737 1738DEFN_TRACE_METHOD_LONG_LONG(int64) 1739DEFN_TRACE_METHOD_LONG_LONG(uint64) 1740#undef DEFN_TRACE_METHOD_LONG_LONG 1741 1742void 1743wif_trace_file::trace( const unsigned& object_, 1744 const std::string& name_, 1745 const char** enum_literals_ ) 1746{ 1747 if( add_trace_check(name_) ) 1748 traces.push_back( new wif_enum_trace( object_, 1749 name_, 1750 obtain_name(), 1751 enum_literals_ ) ); 1752} 1753 1754void 1755wif_trace_file::trace( const sc_dt::sc_bv_base& object_, 1756 const std::string& name_ ) 1757{ 1758 traceT( object_, name_, WIF_BIT ); 1759} 1760 1761void 1762wif_trace_file::trace( const sc_dt::sc_lv_base& object_, 1763 const std::string& name_ ) 1764{ 1765 traceT( object_, name_, WIF_MVL ); 1766} 1767 1768 1769void 1770wif_trace_file::write_comment(const std::string& comment) 1771{ 1772 if(!fp) open_fp(); 1773 //no newline in comments allowed 1774 std::fprintf(fp, "comment \"%s\" ;\n", comment.c_str()); 1775} 1776 1777 1778void 1779wif_trace_file::cycle(bool this_is_a_delta_cycle) 1780{ 1781 unsigned now_units_high, now_units_low; 1782 1783 // Trace delta cycles only when enabled 1784 if (!delta_cycles() && this_is_a_delta_cycle) return; 1785 1786 // Check for initialization 1787 if( initialize() ) { 1788 return; 1789 }; 1790 1791 // double now_units = sc_simulation_time() / timescale_unit; 1792 double now_units = sc_time_stamp().to_seconds() / timescale_unit; 1793 1794 double_to_special_int64(now_units, &now_units_high, &now_units_low ); 1795 1796 // Now do the real stuff 1797 unsigned delta_units_high, delta_units_low; 1798 double diff_time; 1799 diff_time = now_units - previous_time; 1800 double_to_special_int64(diff_time, &delta_units_high, &delta_units_low); 1801 if (this_is_a_delta_cycle && (diff_time == 0.0)) 1802 delta_units_low++; // Increment time for delta cycle simulation 1803 // Note that in the last statement above, we are assuming no more 1804 // than 2^32 delta cycles - seems realistic 1805 1806 bool time_printed = false; 1807 wif_trace* const* const l_traces = &traces[0]; 1808 for (int i = 0; i < (int)traces.size(); i++) { 1809 wif_trace* t = l_traces[i]; 1810 if(t->changed()){ 1811 if(time_printed == false){ 1812 if(delta_units_high){ 1813 std::fprintf(fp, "delta_time %u%09u ;\n", delta_units_high, 1814 delta_units_low); 1815 } 1816 else{ 1817 std::fprintf(fp, "delta_time %u ;\n", delta_units_low); 1818 } 1819 time_printed = true; 1820 } 1821 1822 // Write the variable 1823 t->write(fp); 1824 } 1825 } 1826 1827 if(time_printed) { 1828 std::fprintf(fp, "\n"); // Put another newline 1829 // We update previous_time_units only when we print time because 1830 // this field stores the previous time that was printed, not the 1831 // previous time this function was called 1832 previous_time_units_high = now_units_high; 1833 previous_time_units_low = now_units_low; 1834 previous_time = now_units; 1835 } 1836} 1837 1838#if 0 1839void 1840wif_trace_file::create_wif_name(std::string* ptr_to_str) 1841{ 1842 obtain_name().swap(*ptr_to_str); 1843} 1844#endif 1845 1846// Create a WIF name for a variable 1847std::string 1848wif_trace_file::obtain_name() 1849{ 1850 char buf[32]; 1851 std::sprintf( buf, "O%d", wif_name_index ++ ); 1852 return buf; 1853} 1854 1855wif_trace_file::~wif_trace_file() 1856{ 1857 for( int i = 0; i < (int)traces.size(); i++ ) { 1858 wif_trace* t = traces[i]; 1859 delete t; 1860 } 1861} 1862 1863// Map sc_logic values to values understandable by WIF 1864static char 1865map_sc_logic_state_to_wif_state(char in_char) 1866{ 1867 char out_char; 1868 1869 switch(in_char){ 1870 case 'U': 1871 case 'X': 1872 case 'W': 1873 case 'D': 1874 out_char = 'X'; 1875 break; 1876 case '0': 1877 case 'L': 1878 out_char = '0'; 1879 break; 1880 case '1': 1881 case 'H': 1882 out_char = '1'; 1883 break; 1884 case 'Z': 1885 out_char = 'Z'; 1886 break; 1887 default: 1888 out_char = '?'; 1889 } 1890 return out_char; 1891} 1892 1893// ---------------------------------------------------------------------------- 1894 1895// Create the trace file 1896sc_trace_file* 1897sc_create_wif_trace_file(const char * name) 1898{ 1899 sc_trace_file *tf = new wif_trace_file(name); 1900 return tf; 1901} 1902 1903 1904void 1905sc_close_wif_trace_file( sc_trace_file* tf ) 1906{ 1907 wif_trace_file* wif_tf = static_cast<wif_trace_file*>(tf); 1908 delete wif_tf; 1909} 1910 1911} // namespace sc_core 1912