void thread_loop() { struct local_ { ~local_(){ std::cout << sc_get_current_process_handle().name() << " local deleted " << "(" << sc_time_stamp() << " @ " << sc_delta_count() << ")" << std::endl; } } l; l=l; unsigned rounds = 5; while( rounds --> 0 ) { wait(); std::cout << sc_get_current_process_handle().name() << " triggered " << "(" << sc_time_stamp() << " @ " << sc_delta_count() << ")" << std::endl; } std::cout << sc_get_current_process_handle().name() << " ended " << "(" << sc_time_stamp() << " @ " << sc_delta_count() << ")" << std::endl; }
void process_a() { m_a = sc_get_current_process_handle(); sc_process_handle b; sc_process_handle c = sc_get_current_process_handle(); // TEST COMPARISONS: if ( m_a == b ) { cout << __FILE__ << " " << __LINE__ << " non-null process handle == null process handle" << endl; } if ( m_a != c ) { cout << __FILE__ << " " << __LINE__ << " process handles for same process not equal" << endl; } wait(1); // TEST RETURN VALUES: const std::vector<sc_object*>& objects = m_a.get_child_objects(); if ( objects.size() != 0 ) { cout << __FILE__ << " " << __LINE__ << "get_child_objects() returned non-null vector" << endl; } if ( m_a.get_parent_object() == 0 ) { cout << __FILE__ << " " << __LINE__ << " get_parent_object() returned null value" << endl; } if ( !strcmp( m_a.name(), "") ) { cout << __FILE__ << " " << __LINE__ << "name() returned empty string" << endl; } if ( m_a.proc_kind() != SC_CTHREAD_PROC_ ) { cout << __FILE__ << " " << __LINE__ << "proc_kind() returned " << m_a.proc_kind() << " not " << SC_CTHREAD_PROC_ << endl; } if ( m_a.terminated() ) { cout << __FILE__ << " " << __LINE__ << "terminated() returned true" << endl; } if ( !m_a.valid() ) { cout << __FILE__ << " " << __LINE__ << "valid() returned false" << endl; } }
//------------------------------------------------------------------------------ //"sc_reset_signal_is" // //------------------------------------------------------------------------------ void sc_reset::reset_signal_is( const sc_in<bool>& port, bool level ) { const sc_signal_in_if<bool>* iface_p; sc_process_b* process_p; process_p = (sc_process_b*)sc_get_current_process_handle(); assert( process_p ); switch ( process_p->proc_kind() ) { case SC_THREAD_PROC_: case SC_METHOD_PROC_: SC_REPORT_ERROR(SC_ID_RESET_SIGNAL_IS_NOT_ALLOWED_,""); break; case SC_CTHREAD_PROC_: process_p->m_reset_level = level; iface_p = DCAST<const sc_signal_in_if<bool>*>(port.get_interface()); if ( iface_p ) reset_signal_is( *iface_p, level ); else { new sc_reset_finder( &port, level, process_p ); } break; default: SC_REPORT_ERROR(SC_ID_UNKNOWN_PROCESS_TYPE_, process_p->name()); break; } }
~local_(){ std::cout << sc_get_current_process_handle().name() << " local deleted " << "(" << sc_time_stamp() << " @ " << sc_delta_count() << ")" << std::endl; }
void sc_reset::reset_signal_is( bool async, const sc_out<bool>& port, bool level ) { const sc_signal_in_if<bool>* iface_p; sc_process_b* process_p; process_p = (sc_process_b*)sc_get_current_process_handle(); assert( process_p ); process_p->m_has_reset_signal = true; switch ( process_p->proc_kind() ) { case SC_THREAD_PROC_: case SC_METHOD_PROC_: case SC_CTHREAD_PROC_: iface_p = DCAST<const sc_signal_in_if<bool>*>(port.get_interface()); if ( iface_p ) reset_signal_is( async, *iface_p, level ); else new sc_reset_finder( async, &port, level, process_p ); break; default: SC_REPORT_ERROR(SC_ID_UNKNOWN_PROCESS_TYPE_, process_p->name()); break; } }
void proc_tree( unsigned depth, unsigned width, bool as_method, bool spawn_only ) { unsigned w = width; if (sc_time_stamp() == SC_ZERO_TIME || spawn_only ) while( depth && w --> 0 ) { sc_spawn_options sp; sp.set_sensitivity( &clk.pos() ); if(as_method) // we are spawned as method, spawn a thread { sc_spawn( sc_bind( &top::proc_tree, this, depth-1, width, !as_method, false ) , sc_gen_unique_name("thread"), &sp ); } else // we are spawned as thread, spawn a method { sp.spawn_method(); sc_spawn( sc_bind( &top::proc_tree, this, depth-1, width, !as_method, false ) , sc_gen_unique_name("method"), &sp ); } } if(spawn_only) return; std::cout << sc_get_current_process_handle().name() << " triggered " << "(" << sc_time_stamp() << " @ " << sc_delta_count() << ")" << std::endl; // start thread if( !as_method ) thread_loop(); }
int function_method(double d) { cout << endl << sc_time_stamp() << ", " << sc_get_current_process_handle().name() << ": function_method sees " << d << endl; return int(d); }
void thread() { for (;;) { wait(); sc_process_handle handle = sc_get_current_process_handle(); cout << handle.name() << " " << handle.proc_kind() << endl; } }
void cthread() { m_cthread = sc_get_current_process_handle(); for (;;) { wait(); cout << sc_time_stamp() << ": cthread (" << __LINE__ << ")" << endl; } }
void parent() { proc_tree( 3, 1, true , true ); proc_tree( 3, 1, false, true ); wait(); // copy children (needed, since children may get reordered) std::vector< sc_object* > children = sc_get_current_process_handle().get_child_objects(); std::vector< sc_object* >::const_iterator it = children.begin(); while( it != children.end() ) { sc_process_handle h( *it++ ); sc_assert( h.valid() ); std::cout << h.name() << " " << "kill requested " << "(" << h.get_process_object()->kind() << ") " << "(" << sc_time_stamp() << " @ " << sc_delta_count() << ")" << std::endl; h.kill( SC_INCLUDE_DESCENDANTS ); } wait(); std::cout << sc_get_current_process_handle().name() << " ended " << "(" << sc_time_stamp() << " @ " << sc_delta_count() << ")" << std::endl; wait(); sc_stop(); while(true) wait(); }
void dynamic_method() { static int state = 0; switch ( state ) { case 0: m_dynamic_method = sc_get_current_process_handle(); next_trigger( m_clk.posedge_event() ); cout << sc_time_stamp() << ": dynamic method (" << __LINE__ << "," << state << ") initialization call " << endl; break; case 1: next_trigger( m_clk.posedge_event() ); cout << sc_time_stamp() << ": dynamic method (" << __LINE__ << "," << state << ") after wait on m_clk.posedge_event() " << endl; break; case 2: next_trigger( m_clk.negedge_event() ); cout << sc_time_stamp() << ": dynamic method (" << __LINE__ << "," << state << ") after wait on m_clk.posedge_event() " << endl; break; case 3: next_trigger( m_event1 & m_event2 ); cout << sc_time_stamp() << ": dynamic method (" << __LINE__ << "," << state << ") after wait on m_clk.negedge() " << endl; break; case 4: next_trigger( m_clk.posedge_event() ); cout << sc_time_stamp() << ": dynamic method (" << __LINE__ << "," << state << ") after wait on m_event1 & m_event2 " << endl; break; default: next_trigger( m_clk.posedge_event() ); cout << sc_time_stamp() << ": dynamic method (" << __LINE__ << "," << state << ") after wait on m_clk.posedge_event() " << endl; break; } state = state + 1; if ( state == 5 ) state = 1; }
void monitor() { m_monitor_handle = sc_get_current_process_handle(); for (;;) { try { wait(m_never_event); } catch (my_exception& except) { cout << sc_time_stamp() << " caught my exception " << endl; } catch (your_exception& except) { cout << sc_time_stamp() << " caught your exception " << endl; } } }
void sc_module::set_stack_size( std::size_t size ) { sc_process_handle proc_h( sc_is_running() ? sc_get_current_process_handle() : sc_get_last_created_process_handle() ); sc_thread_handle thread_h; // Current process as thread. thread_h = (sc_thread_handle)proc_h; if ( thread_h ) { thread_h->set_stack_size( size ); } else { SC_REPORT_WARNING( SC_ID_SET_STACK_SIZE_, 0 ); } }
void dynamic_thread() { m_dynamic_thread = sc_get_current_process_handle(); cout << sc_time_stamp() << ": dynamic thread (" << __LINE__ << ")" << " initialization call " << endl; wait(m_clk.posedge_event()); for (;;) { cout << sc_time_stamp() << ": dynamic thread (" << __LINE__ << ") after wait on m_clk.posedge_event() " << endl; wait(m_clk.posedge_event()); cout << sc_time_stamp() << ": dynamic thread (" << __LINE__ << ") after wait on m_clk.posedge_event() " << endl; wait(m_clk.negedge_event()); cout << sc_time_stamp() << ": dynamic thread (" << __LINE__ << ") after wait on m_clk.negedge_event() " << endl; wait(m_event1 & m_event2 ); cout << sc_time_stamp() << ": dynamic thread (" << __LINE__ << ") after wait on m_event1 & m_event2 " << endl; wait(m_clk.posedge_event()); } }
void process_b() { wait(1); sc_process_handle b = sc_get_current_process_handle(); if ( m_a == b ) { cout << __FILE__ << " " << __LINE__ << " process handles for two different processes were equal" << endl; } if ( b.get_parent_object() == 0 ) { cout << __FILE__ << " " << __LINE__ << " get_parent_object() returned null value" << endl; } if ( b.proc_kind() != SC_THREAD_PROC_ ) { cout << __FILE__ << " " << __LINE__ << "proc_kind() returned " << b.proc_kind() << " not " << SC_THREAD_PROC_ << endl; } wait(2); if ( m_a.valid() ) { if ( !m_a.terminated() ) { cout << __FILE__ << " " << __LINE__ << "terminated() returned false" << endl; } } else { if ( m_a.terminated() ) { cout << __FILE__ << " " << __LINE__ << "terminated() returned true" << endl; } } }
void wait(registered_event &re) { sc_process_handle current_task; task_info_t *current_task_info; current_task=sc_get_current_process_handle(); current_task_info = task_info_by_phandle[current_task]; current_task_info->finished_flag = false; // to avoid it to be considered completion of the task current_task_info->waiting_comm_sync_signal.write(true); // wait( re ); // This would not work! because it would be a recursive call! re.wait(); // Calls to the wait method of the memoryless_event object (wich is the inherited one from the sc_event) current_task_info->waiting_comm_sync_signal.write(false); current_task_info->finished_flag = true; // guard to let the user task go on executing after relelase only if the scheduler has granted it a processor if(current_task_info->active_signal.read()==false) wait(current_task_info->active_signal.posedge_event()); }
void thread_target() { m_thread_handle = sc_get_current_process_handle(); wait(); }
int semaphore::wait() { sc_process_handle current_task; task_info_t *current_task_info; int ret_value; current_task=sc_get_current_process_handle(); current_task_info = task_info_by_phandle[current_task]; current_task_info->finished_flag = false; // to avoid it to be considered completion of the task current_task_info->waiting_comm_sync_signal.write(true); ret_value=(*this).sc_semaphore::wait(); // calls to the sc_semaphore wait method // be aware that the following would not work //static_cast<sc_semaphore&>(*this).wait(); //static_cast<sc_core::sc_semaphore*>(this)->wait(); current_task_info->waiting_comm_sync_signal.write(false); current_task_info->finished_flag = true; // guard to let the user task go on executing after release only if the scheduler has granted it a processor if(current_task_info->active_signal.read()==false) sc_core::wait(current_task_info->active_signal.posedge_event()); // ALTERNATIVE TO SAVE TIME // Notice that in a real software implementation it is not valid // since once entered in the second branch (size semaphore>0) // the code could be preempted under a preemptive scheduling, // and other task empty the semaphore. // Then, the task would block without accounting that time. // Since the SsytemC implementation has not "consumes", nor this // code can be preempted it is valid to save time /* if(static_cast<sc_semaphore&>(*this).get_value()==0) { // in this case, the accesing tasks is going to go to waiting state due to synchronization sc_process_handle current_task; task_info_t *current_task_info; current_task=sc_get_current_process_handle(); current_task_info = task_info_by_phandle[current_task]; current_task_info->finished_flag = false; // to avoid it to be considered completion of the task current_task_info->waiting_comm_sync_signal.write(true); static_cast<sc_semaphore&>(*this).wait(); // calls to the sc_semaphore wait method current_task_info->waiting_comm_sync_signal.write(false); current_task_info->finished_flag = true; // guard to let the user task go on executing after release only if the scheduler has granted it a processor if(current_task_info->active_signal.read()==false) wait(current_task_info->active_signal.posedge_event()); } // else, there is no need to wait, not even to notify the KisTA kernel or change the // finished flag else { // we do the call, but in principle it will it should not be necessary, here we now it will not block static_cast<sc_semaphore&>(*this).wait(); // calls to the sc_semaphore wait method } */ return ret_value; }
void static_method() { m_static_method = sc_get_current_process_handle(); cout << sc_time_stamp() << ": static method (" << __LINE__ << ")" << endl; }