summaryrefslogtreecommitdiff
path: root/src/systemc/tests/systemc/1666-2011-compliance/sc_pause/sc_pause.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/systemc/tests/systemc/1666-2011-compliance/sc_pause/sc_pause.cpp')
-rw-r--r--src/systemc/tests/systemc/1666-2011-compliance/sc_pause/sc_pause.cpp348
1 files changed, 348 insertions, 0 deletions
diff --git a/src/systemc/tests/systemc/1666-2011-compliance/sc_pause/sc_pause.cpp b/src/systemc/tests/systemc/1666-2011-compliance/sc_pause/sc_pause.cpp
new file mode 100644
index 000000000..2f7ebd930
--- /dev/null
+++ b/src/systemc/tests/systemc/1666-2011-compliance/sc_pause/sc_pause.cpp
@@ -0,0 +1,348 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+// sc_pause.cpp -- test for
+//
+// Original Author: John Aynsley, Doulos, Inc.
+//
+// MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+//
+// $Log: sc_pause.cpp,v $
+// Revision 1.2 2011/05/08 19:18:46 acg
+// Andy Goodrich: remove extraneous + prefixes from git diff.
+//
+
+// sc_pause, sc_get_status, sc_is_running
+
+#define SC_INCLUDE_DYNAMIC_PROCESSES
+
+#include <systemc>
+using namespace sc_core;
+using std::cout;
+using std::endl;
+using std::hex;
+
+struct my_interface: virtual sc_interface
+{
+ virtual void schedule_events_while_paused() = 0;
+};
+
+struct M: sc_module, private my_interface
+{
+ sc_export<my_interface> xport;
+
+ SC_CTOR(M)
+ {
+ cout << "sc_get_status() == " << hex << sc_get_status() << " CTOR in " << name() << endl;
+ sc_assert( sc_get_status() == SC_BEFORE_END_OF_ELABORATION );
+ sc_assert( sc_is_running() == false );
+
+ xport.bind(*this);
+
+ sc_spawn(sc_bind(&M::T, this));
+
+ SC_THREAD(on_immed_event);
+ SC_THREAD(on_delta_event);
+ SC_THREAD(on_timed_event);
+ }
+
+ sc_signal<int> sig1, sig2, sig3, sig4;
+ sc_event immed_event;
+ sc_event delta_event;
+ sc_event timed_event;
+
+ void before_end_of_elaboration()
+ {
+ cout << "sc_get_status() == " << hex << sc_get_status() << " before_end_of_elaboration in " << name() << endl;
+ sc_assert( sc_get_status() == SC_BEFORE_END_OF_ELABORATION );
+ sc_assert( sc_is_running() == false );
+ sig1.write(1);
+ timed_event.notify(1234, SC_NS);
+ sc_pause(); // Should be ignored
+ }
+
+ void end_of_elaboration()
+ {
+ cout << "sc_get_status() == " << hex << sc_get_status() << " end_of_elaboration in " << name() << endl;
+ sc_assert( sc_get_status() == SC_END_OF_ELABORATION );
+ sc_assert( sc_is_running() == false );
+ sig2.write(2);
+ sc_pause(); // Should be ignored
+ }
+
+ void start_of_simulation()
+ {
+ cout << "sc_get_status() == " << hex << sc_get_status() << " start_of_simulation in " << name() << endl;
+ sc_assert( sc_get_status() == SC_START_OF_SIMULATION );
+ sc_assert( sc_is_running() == false );
+ sig3.write(3);
+ sig4.write(0);
+ sc_pause(); // Should be ignored
+ }
+
+ void end_of_simulation()
+ {
+ cout << "sc_get_status() == " << hex << sc_get_status() << " end_of_simulation in " << name() << endl;;
+ sc_assert( sc_get_status() == SC_END_OF_SIMULATION );
+ sc_assert( sc_is_running() == false );
+ }
+
+ void T()
+ {
+ sc_assert( sig1.read() == 1 );
+ sc_assert( sig2.read() == 2 );
+ sc_assert( sig3.read() == 3 );
+ }
+
+ void on_immed_event()
+ {
+ wait(immed_event);
+ cout << "on_immed_event() awoke\n";
+
+ // Should run in 1st eval phase after pause
+ sc_assert( sig4.read() == 0 );
+ }
+
+ void on_delta_event()
+ {
+ wait(delta_event);
+ cout << "on_delta_event() awoke\n";
+
+ // Should run in 2nd eval phase after pause
+ sc_assert( sig4.read() == 4 );
+ }
+
+ void on_timed_event()
+ {
+ wait(timed_event);
+ cout << "on_timed_event() awoke\n";
+
+ sc_assert( sig1.read() == 1 );
+ sc_assert( sig2.read() == 2 );
+ sc_assert( sig3.read() == 3 );
+ sc_assert( sig4.read() == 0 );
+ sc_assert( sc_time_stamp() == sc_time(1234, SC_NS) );
+ }
+
+private:
+
+ void schedule_events_while_paused()
+ {
+ sig4.write(4);
+ immed_event.notify();
+ delta_event.notify(SC_ZERO_TIME);
+
+ // Should be able to instantiate an sc_object while paused
+ mut = new sc_mutex("mut");
+ sem = new sc_semaphore("sem", 1);
+ }
+
+ sc_mutex* mut;
+ sc_semaphore* sem;
+};
+
+SC_MODULE(Top)
+{
+ SC_CTOR(Top)
+ {
+ cout << "sc_get_status() == " << hex << sc_get_status() << " CTOR in " << name() << endl;
+ sc_assert( sc_get_status() == SC_ELABORATION );
+ sc_assert( sc_is_running() == false );
+ SC_THREAD(T);
+
+ sc_spawn_options opt;
+ opt.spawn_method();
+ opt.set_sensitivity( &timed_ev );
+ opt.set_sensitivity( &delta_ev );
+ opt.dont_initialize();
+ sc_spawn(sc_bind(&Top::ev_handler, this), "ev_handler", &opt);
+
+ SC_METHOD(immed_ev_handler);
+ sensitive << immed_ev;
+ dont_initialize();
+
+ immed_ev_delta = 0;
+ sc_assert( sc_delta_count() == 0 );
+ }
+
+ ~Top()
+ {
+ sc_assert( sc_get_status() == SC_STOPPED );
+ sc_assert( sc_is_running() == false );
+ }
+
+ M* m;
+ sc_event timed_ev;
+ sc_event delta_ev;
+ sc_event immed_ev;
+ unsigned immed_ev_delta;
+ sc_signal<int> sig;
+
+ void before_end_of_elaboration()
+ {
+ cout << "sc_get_status() == " << hex << sc_get_status() << " before_end_of_elaboration in " << name() << endl;
+ sc_assert( sc_get_status() == SC_BEFORE_END_OF_ELABORATION );
+ sc_assert( sc_is_running() == false );
+
+ m = new M("m");
+ }
+
+ void end_of_elaboration()
+ {
+ cout << "sc_get_status() == " << hex << sc_get_status() << " end_of_elaboration in " << name() << endl;
+ sc_assert( sc_get_status() == SC_END_OF_ELABORATION );
+ sc_assert( sc_is_running() == false );
+ }
+
+ void start_of_simulation()
+ {
+ cout << "sc_get_status() == " << hex << sc_get_status() << " start_of_simulation in " << name() << endl;
+ sc_assert( sc_get_status() == SC_START_OF_SIMULATION );
+ sc_assert( sc_is_running() == false );
+ }
+
+ void end_of_simulation()
+ {
+ cout << "sc_get_status() == " << hex << sc_get_status() << " end_of_simulation in " << name() << endl;
+ sc_assert( sc_get_status() == SC_END_OF_SIMULATION );
+ sc_assert( sc_is_running() == false );
+ sc_assert( immed_ev_delta == 999 );
+ }
+
+ void T()
+ {
+ cout << "sc_get_status() == " << hex << sc_get_status() << " PROCESS in " << name() << endl;
+ sc_assert( sc_delta_count() == 0 );
+ sc_assert( sig.read() == 42 );
+ sc_assert( sc_get_status() == SC_RUNNING );
+ sc_assert( sc_is_running() == true );
+ wait(timed_ev);
+ sc_assert( sc_time_stamp() == sc_time(42, SC_US) );
+ sc_assert( sc_get_status() == SC_RUNNING );
+ sc_assert( sc_is_running() == true );
+
+ sc_pause();
+ cout << "sc_get_status() == " << hex << sc_get_status() << " PROCESS after sc_pause in " << name() << endl;
+ sc_assert( sc_time_stamp() == sc_time(42, SC_US) );
+ sc_assert( sc_get_status() == SC_RUNNING );
+ sc_assert( sc_is_running() == true );
+ wait(SC_ZERO_TIME);
+ sc_assert( sc_get_status() == SC_RUNNING );
+ sc_assert( sc_is_running() == true );
+
+ sc_pause();
+ cout << "sc_get_status() == " << hex << sc_get_status() << " PROCESS after sc_pause in " << name() << endl;
+ sc_assert( sc_time_stamp() == sc_time(42, SC_US) );
+ sc_assert( sc_get_status() == SC_RUNNING );
+ sc_assert( sc_is_running() == true );
+ wait(2, SC_US);
+ sc_assert( sc_time_stamp() == sc_time(44, SC_US) );
+ sc_assert( sc_get_status() == SC_RUNNING );
+ sc_assert( sc_is_running() == true );
+
+ sc_stop();
+ cout << "sc_get_status() == " << hex << sc_get_status() << " PROCESS after sc_stop() in " << name() << endl;;
+ sc_assert( sc_time_stamp() == sc_time(44, SC_US) );
+ sc_assert( sc_get_status() == SC_RUNNING );
+ sc_assert( sc_is_running() == true );
+
+ sc_pause();
+ sc_assert( sc_get_status() == SC_RUNNING );
+ }
+
+ void ev_handler()
+ {
+ cout << "sc_get_status() == " << hex << sc_get_status() << " METHOD in " << name() << endl;
+ sc_assert( sc_get_status() == SC_RUNNING );
+ sc_assert( sig.read() == 42 );
+
+ static bool first = true;
+ if (first)
+ {
+ sc_assert( sc_time_stamp() == SC_ZERO_TIME );
+ first = false;
+ }
+ else
+ sc_assert( sc_time_stamp() == sc_time(42, SC_US) );
+ }
+
+ void immed_ev_handler()
+ {
+ sc_assert( sc_time_stamp() == sc_time(42, SC_US) );
+ sc_assert( sc_delta_count() == immed_ev_delta );
+ immed_ev_delta = 999;
+ }
+};
+
+void spawned_while_paused()
+{
+ cout << "spawned_while_paused() awoke" << endl;
+ sc_assert( sc_time_stamp() == sc_time(42, SC_US) );
+ sc_assert( sc_get_status() == SC_RUNNING );
+ sc_assert( sc_pending_activity() == true );
+}
+
+int sc_main(int argc, char* argv[])
+{
+ sc_assert( sc_delta_count() == 0 );
+ cout << "sc_get_status() == " << hex << sc_get_status() << " ELAB" << endl;
+ sc_assert( sc_get_status() == SC_ELABORATION );
+ sc_assert( sc_is_running() == false );
+ Top top("top");
+
+ sc_pause(); // Should be ignored
+
+ // Schedule some update requests and events
+ top.sig.write(42);
+ top.timed_ev.notify(42, SC_US);
+ top.delta_ev.notify(SC_ZERO_TIME);
+ sc_assert( sc_get_status() == SC_ELABORATION );
+ sc_assert( sc_delta_count() == 0 );
+
+ sc_start();
+ cout << "sc_get_status() == " << hex << sc_get_status() << " PAUSED" << endl;
+ sc_assert( sc_get_status() == SC_PAUSED );
+ sc_assert( sc_is_running() == true );
+ sc_assert( sc_time_stamp() == sc_time(42, SC_US) );
+
+ sc_start(1, SC_US);
+ cout << "sc_get_status() == " << hex << sc_get_status() << " PAUSED" << endl;
+ sc_assert( sc_get_status() == SC_PAUSED );
+ sc_assert( sc_is_running() == true );
+ sc_assert( sc_time_stamp() == sc_time(42, SC_US) );
+
+ // Schedule an immediate notification
+ top.immed_ev.notify();
+ top.immed_ev_delta = sc_delta_count();
+
+ // IMC while paused
+ top.m->xport->schedule_events_while_paused();
+
+ sc_process_handle h = sc_spawn(&spawned_while_paused);
+ sc_assert( h.valid() );
+
+ sc_start();
+ cout << "sc_get_status() == " << hex << sc_get_status() << " STOPPED" << endl;
+ sc_assert( sc_get_status() == SC_STOPPED );
+ sc_assert( sc_is_running() == false );
+ sc_assert( sc_time_stamp() == sc_time(44, SC_US) );
+
+ cout << endl << "Success" << endl;
+ return 0;
+}