Changeset 52 for sources/src/sc_port.cc
- Timestamp:
- Jan 22, 2013, 4:23:22 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sources/src/sc_port.cc
r47 r52 51 51 52 52 extern "C" { 53 54 char unstable = 0; // not in sc_core namespace because dynamic link support C linkage only55 int32_t pending_write_vector_nb = 0;53 extern char unstable; 54 char unstable = 0; // not in sc_core namespace because dynamic link support C linkage only 55 int32_t pending_write_vector_nb = 0; 56 56 } 57 57 … … 60 60 namespace sc_core { 61 61 62 const char * const sc_port_base::kind_string = "sc_port";63 const char * const sc_signal_base::kind_string = "sc_signal";62 const char * const sc_port_base::kind_string = "sc_port"; 63 const char * const sc_signal_base::kind_string = "sc_signal"; 64 64 65 65 unsigned int pending_write_vector_capacity = 512; … … 67 67 extern equi_list_t equi_list; 68 68 69 const char* get_module_name (const tab_t *pointer) 70 { 71 const equi_t &eq = get_equi (pointer); 72 return get_module_name (eq); 73 } 74 75 //typedef std::map<const sc_port_base*, const sc_module*> port2module_t; 69 const char * get_module_name (const tab_t * pointer) { 70 const equi_t & eq = get_equi (pointer); 71 return get_module_name (eq); 72 } 73 76 74 port2module_t port2module; 77 75 … … 80 78 const char * const sc_in_string = "sc_in"; 81 79 const char * const sc_out_string = "sc_out"; 80 82 81 83 82 // ---------------------------------------------------------------------------- … … 87 86 // ---------------------------------------------------------------------------- 88 87 89 sc_port_base::sc_port_base() 90 { 88 sc_port_base::sc_port_base() { 91 89 init (); 92 90 } 93 91 94 sc_port_base::sc_port_base(const char* name_) : sc_object(name_) 95 { 96 init (); 97 } 98 99 sc_port_base::sc_port_base(const sc_port_base& parent_) : sc_object (parent_.name ()) 100 { 101 init (); 102 } 103 104 void 105 sc_port_base::init () 106 { 92 93 sc_port_base::sc_port_base(const char * name_) : sc_object(name_) { 94 init (); 95 } 96 97 98 sc_port_base::sc_port_base(const sc_port_base & parent_) : sc_object (parent_.name ()) { 99 init (); 100 } 101 102 103 void sc_port_base::init() { 107 104 #ifdef CONFIG_DEBUG 108 if (modules_stack.empty ()) { 109 cerr << "Internal error : modules stack empty\n"; 110 exit (9); 111 } 112 #endif 113 const sc_module *last_module = sc_core::modules_stack.top (); 114 port2module[this] = last_module; 115 set_kind (kind_string); 116 } 117 118 const sc_module & 119 sc_port_base::get_module () const 120 { 121 port2module_t::iterator i = port2module.find ((sc_port_base*)this); 122 if (i == port2module.end ()) { 123 cerr << "Internal error : Modules contain ports. " 105 if (modules_stack.empty()) { 106 cerr << "Internal error : modules stack empty\n"; 107 exit (9); 108 } 109 #endif 110 const sc_module * last_module = sc_core::modules_stack.top(); 111 port2module[this] = last_module; 112 set_kind(kind_string); 113 } 114 115 116 const sc_module & sc_port_base::get_module() const { 117 port2module_t::iterator i = port2module.find ((sc_port_base *) this); 118 if (i == port2module.end()) { 119 cerr << "Internal error : Modules contain ports. " 124 120 "SystemCASS needs to identify the module that contains the following port : '" 125 << name() 126 << "'\n"; 127 exit (17); 128 } 129 const sc_module *m = i->second; 130 return *m; 131 } 121 << name() 122 << "'\n"; 123 exit (17); 124 } 125 const sc_module * m = i->second; 126 return *m; 127 } 128 132 129 133 130 static bool check_multiwriting2port_error_message = true; 134 void 135 sc_port_base::check_multiwriting2port () const 136 { 137 static std::map<sc_port_base*, double> s; 138 double t = sc_simulation_time (); 139 if (t == 0) 140 return; 141 sc_port_base *port = (sc_port_base*)this; 142 if ((s[port] == t) && (check_multiwriting2port_error_message)) 143 { 144 check_multiwriting2port_error_message = 0; 145 if (use_port_dependency) 146 { 147 std::cerr << "Error at cycle #" << t << " : " 148 "SystemCASS allows only 1 writing for each ports/signals.\n" 131 132 void sc_port_base::check_multiwriting2port() const { 133 static std::map<sc_port_base *, double> s; 134 double t = sc_simulation_time(); 135 if (t == 0) { 136 return; 137 } 138 sc_port_base * port = (sc_port_base *) this; 139 if ((s[port] == t) && (check_multiwriting2port_error_message)) { 140 check_multiwriting2port_error_message = 0; 141 if (use_port_dependency) { 142 std::cerr << "Error at cycle #" << t << " : " 143 "SystemCASS allows only 1 writing for each ports/signals.\n" 149 144 << "Functions write several times into '" << name () << "'.\n"; 150 } else { 151 std::cerr << "Error : " 152 "Multiwriting to port assertion works only " 153 "when SystemCASS uses port dependency information " 154 "(--p parameter).\n"; 155 } 156 sc_core::sc_stop (); 157 exit (31072006); // 6 158 } else 159 s[port] = t; 160 } 161 162 std::ostream& 163 operator << (std::ostream &o, const sc_port_base &p) 164 { 165 return o << p.name (); 166 } 145 } 146 else { 147 std::cerr << "Error : " 148 "Multiwriting to port assertion works only " 149 "when SystemCASS uses port dependency information " 150 "(--p parameter).\n"; 151 } 152 sc_core::sc_stop(); 153 exit (31072006); // 6 154 } 155 else { 156 s[port] = t; 157 } 158 } 159 160 161 std::ostream & operator << (std::ostream & o, const sc_port_base & p) { 162 return o << p.name(); 163 } 164 165 167 166 // ---------------------------------------------------------------------------- 168 167 // CLASS : sc_signal_base … … 170 169 // The sc_signal<T> primitive channel class. 171 170 // ---------------------------------------------------------------------------- 172 173 void 174 sc_signal_base::init () 175 { 176 set_kind (kind_string); 177 bind (*this); 178 } 171 void sc_signal_base::init() { 172 set_kind(kind_string); 173 bind(*this); 174 } 175 179 176 180 177 sc_signal_base::sc_signal_base() { 181 init (); 182 } 183 184 sc_signal_base::sc_signal_base(const char* name_) : sc_object(name_) { 185 init (); 186 } 187 188 sc_signal_base::sc_signal_base(const char* name_, void*) : sc_object(name_) { 189 // this overload is only used for SC_BIND_PROXY_NIL constant. 190 // this signal should not be added to the signal list. 191 } 192 193 sc_signal_base::~sc_signal_base() { 194 } 178 init(); 179 } 180 181 182 sc_signal_base::sc_signal_base(const char * name_) : sc_object(name_) { 183 init (); 184 } 185 186 187 sc_signal_base::sc_signal_base(const char * name_, void *) : sc_object(name_) { 188 // this overload is only used for SC_BIND_PROXY_NIL constant. 189 // this signal should not be added to the signal list. 190 } 191 192 193 sc_signal_base::~sc_signal_base() {} 194 195 195 196 196 /* … … 199 199 200 200 #ifdef DUMP_SIGNAL_STATS 201 typedef map<tab_t *,long long int> counter_t;202 static counter_t 201 typedef map<tab_t *, long long int> counter_t; 202 static counter_t counter; 203 203 long long int unnecessary = 0; 204 204 long long int total_assig = 0; … … 207 207 } // end of sc_core namespace 208 208 209 209 210 extern "C" { 210 void 211 update () 212 { 211 212 void update() { 213 213 #if defined(DUMP_STAGE) 214 cerr << "Updating... "; 215 #endif 216 // stl vectors are too slow 217 // memcopy is not better 218 // signal table sorting doesn't give any better performance 219 #if 0 220 cerr << pending_write_vector_nb << " " << pending_write_vector_capacity << endl; 221 #endif 214 cerr << "Updating... "; 215 #endif 216 // stl vectors are too slow 217 // memcopy is not better 218 // signal table sorting doesn't give any better performance 222 219 #if defined(DUMP_STAGE) 223 cerr << "(" << pending_write_vector_nb 224 << " internal pending writings) "; 225 #endif 226 unsigned int i; 227 for (i = 0; i < pending_write_vector_nb; ++i) { 228 #if 0 229 cerr << "pending_write[" << i << "] : " << pending_write_vector[i]; 230 #endif 220 cerr << "(" << pending_write_vector_nb 221 << " internal pending writings) "; 222 #endif 223 unsigned int i; 224 for (i = 0; i < pending_write_vector_nb; ++i) { 231 225 #define iter (sc_core::pending_write_vector[i]) 232 226 #ifdef CONFIG_DEBUG 233 234 235 236 227 if (iter.pointer == NULL) { 228 cerr << "Internal error : trying to apply a posted write from an unassigned signal/port\n"; 229 exit (8); 230 } 237 231 #endif 238 232 #ifdef DUMP_SIGNAL_STATS 239 if (*(iter.pointer) == iter.value) 240 unnecessary++; 241 counter[iter.pointer]++; 242 #endif 243 *(iter.pointer) = iter.value; 233 if (*(iter.pointer) == iter.value) { 234 unnecessary++; 235 } 236 counter[iter.pointer]++; 237 #endif 238 *(iter.pointer) = iter.value; 244 239 #undef iter 245 }240 } 246 241 #ifdef DUMP_SIGNAL_STATS 247 248 #endif 249 242 total_assig += pending_write_vector_nb; 243 #endif 244 pending_write_vector_nb = 0; 250 245 251 246 #if defined(DUMP_STAGE) 252 cerr << "done.\n";253 #endif 254 }247 cerr << "done.\n"; 248 #endif 249 } 255 250 256 251 } // end of extern "C" … … 258 253 namespace sc_core { 259 254 260 void 261 print_registers_writing_stats (ostream &o) 262 { 255 void print_registers_writing_stats (ostream & o) { 263 256 #ifdef DUMP_SIGNAL_STATS 264 o << "signal index / name / usage (>1%)\n"; 265 o << setprecision (2); 266 double t = sc_simulation_time (); 267 if (t == 0) { 268 o << "Warning : simulation too short.\n"; 269 t = 0.01; 270 } 271 if (total_assig == 0) 272 return; 273 counter_t::iterator k; 274 for (k = counter.begin (); k != counter.end (); ++k) { 275 double usage = k->second / t * 100; 276 if (usage <= 1) 277 continue; 278 o << k->first 279 << " " << get_name (k->first) 280 << " " << usage << "%\n"; 281 } 282 typedef map<string,int> counter_module_t; 283 counter_module_t counter_by_module; 284 for (k = counter.begin (); k != counter.end (); ++k) { 285 string module_name = get_module_name (k->first); 286 counter_by_module[module_name] += k->second; 287 } 288 o << "module name / usage\n"; 289 counter_module_t::iterator i; 290 for (i = counter_by_module.begin (); i != counter_by_module.end (); ++i) { 291 o << i->first 292 << " " << (i->second * 100 / total_assig) << "%\n"; 293 } 294 cerr << "average of assignment number per cycle " << (total_assig / t) << "\n"; 295 cerr << (unnecessary * 100 / total_assig) << "% of assignment are unecessary\n"; 257 o << "signal index / name / usage (>1%)\n"; 258 o << setprecision(2); 259 double t = sc_simulation_time(); 260 if (t == 0) { 261 o << "Warning : simulation too short.\n"; 262 t = 0.01; 263 } 264 if (total_assig == 0) { 265 return; 266 } 267 counter_t::iterator k; 268 for (k = counter.begin(); k != counter.end(); ++k) { 269 double usage = k->second / t * 100; 270 if (usage <= 1) { 271 continue; 272 } 273 o << k->first << " " << get_name (k->first) << " " << usage << "%\n"; 274 } 275 typedef map<string, int> counter_module_t; 276 counter_module_t counter_by_module; 277 for (k = counter.begin(); k != counter.end(); ++k) { 278 string module_name = get_module_name (k->first); 279 counter_by_module[module_name] += k->second; 280 } 281 o << "module name / usage\n"; 282 counter_module_t::iterator i; 283 for (i = counter_by_module.begin(); i != counter_by_module.end(); ++i) { 284 o << i->first << " " << (i->second * 100 / total_assig) << "%\n"; 285 } 286 cerr << "average of assignment number per cycle " << (total_assig / t) << "\n"; 287 cerr << (unnecessary * 100 / total_assig) << "% of assignment are unecessary\n"; 296 288 #else 297 cerr << "Register usage not available.\n"; 298 #endif 299 } 300 301 static 302 bool 303 is_bound (/*const*/ sc_port_base &port) 304 { 305 const tab_t *pointer = port.get_pointer (); 306 //assert(pointer != NULL); 307 if (pointer == NULL) 308 return false; // case : sc_in not bound 309 /* 310 equi_t &e = get_equi (pointer); 311 if (e.size () == 1) 312 return true; // case : sc_out not bound 313 */ 314 return has_equi (port); 315 } 316 317 static 318 void 319 check_port (/*const*/ sc_port_base &port) 320 { 321 if (!is_bound (port)) 322 { 323 cerr << "Error : '" << port.name () << "' port" 289 cerr << "Register usage not available.\n"; 290 #endif 291 } 292 293 static bool is_bound(/*const*/ sc_port_base & port) { 294 const tab_t * pointer = port.get_pointer(); 295 //assert(pointer != NULL); 296 if (pointer == NULL) { 297 return false; // case : sc_in not bound 298 } 299 return has_equi (port); 300 } 301 302 static void check_port(/*const*/ sc_port_base & port) { 303 if (!is_bound (port)) { 304 cerr << "Error : '" << port.name() << "' port" 324 305 " (" << port.kind() << ")" 325 306 " is not bound.\n"; 326 exit (29); 327 } 328 } 329 330 void 331 check_all_ports () 332 { 333 if (dump_stage) 334 cerr << "checking ports..."; 335 port2module_t::/*const_*/iterator i; 336 for (i = port2module.begin (); i != port2module.end (); ++i) 337 { 338 /*const*/ sc_port_base *port = i->first; 339 assert(port != NULL); 340 check_port (*port); 341 } 342 if (dump_stage) 343 cerr << " done."; 344 } 307 exit (29); 308 } 309 } 310 311 312 void check_all_ports() { 313 if (dump_stage) { 314 cerr << "checking ports..."; 315 } 316 port2module_t::/*const_*/iterator i; 317 for (i = port2module.begin(); i != port2module.end(); ++i) { 318 /*const*/ sc_port_base *port = i->first; 319 assert(port != NULL); 320 check_port(*port); 321 } 322 if (dump_stage) { 323 cerr << " done."; 324 } 325 } 326 345 327 346 328 } // end of sc_core namespace 347 329 348 330 331 /* 332 # Local Variables: 333 # tab-width: 4; 334 # c-basic-offset: 4; 335 # c-file-offsets:((innamespace . 0)(inline-open . 0)); 336 # indent-tabs-mode: nil; 337 # End: 338 # 339 # vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 340 */ 341
Note: See TracChangeset
for help on using the changeset viewer.