summaryrefslogtreecommitdiff
path: root/src/systemc/tests/systemc/1666-2011-compliance/sc_writer_policy/sc_writer_policy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/systemc/tests/systemc/1666-2011-compliance/sc_writer_policy/sc_writer_policy.cpp')
-rw-r--r--src/systemc/tests/systemc/1666-2011-compliance/sc_writer_policy/sc_writer_policy.cpp321
1 files changed, 321 insertions, 0 deletions
diff --git a/src/systemc/tests/systemc/1666-2011-compliance/sc_writer_policy/sc_writer_policy.cpp b/src/systemc/tests/systemc/1666-2011-compliance/sc_writer_policy/sc_writer_policy.cpp
new file mode 100644
index 000000000..fccd8fa60
--- /dev/null
+++ b/src/systemc/tests/systemc/1666-2011-compliance/sc_writer_policy/sc_writer_policy.cpp
@@ -0,0 +1,321 @@
+/*****************************************************************************
+
+ 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_writer_policy.cpp -- test for
+//
+// Original Author: John Aynsley, Doulos, Inc.
+//
+// MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+//
+// $Log: sc_writer_policy.cpp,v $
+// Revision 1.2 2011/05/08 19:18:46 acg
+// Andy Goodrich: remove extraneous + prefixes from git diff.
+//
+
+// sc_writer_policy template argument of class sc_signal
+
+#define SC_INCLUDE_DYNAMIC_PROCESSES
+#include <systemc>
+
+using namespace sc_core;
+using namespace sc_dt;
+using std::cout;
+using std::endl;
+using std::string;
+
+
+struct M: sc_module
+{
+ sc_inout<bool> port;
+
+ sc_time delay;
+ sc_signal<int> one_sig;
+ sc_signal<int, SC_MANY_WRITERS> many_sig;
+
+ bool first_run;
+ int g0, g1, g2, g3;
+
+ M(sc_module_name _name, sc_time _delay)
+ : port("port")
+ , delay(_delay)
+ , first_run(true)
+ {
+ sc_assert( one_sig.get_writer_policy() == SC_ONE_WRITER );
+ sc_assert( many_sig.get_writer_policy() == SC_MANY_WRITERS );
+
+ SC_THREAD(T);
+ SC_METHOD(method_process_1);
+ SC_METHOD(method_process_2);
+
+ one_sig.write(-1);
+ many_sig.write(-1);
+
+ g0 = g1 = g2 = g3 = 0;
+ }
+
+ void end_of_elaboration()
+ {
+ sc_assert( port->get_writer_policy() == SC_MANY_WRITERS );
+ one_sig.write(1);
+ many_sig.write(1);
+ g0 = 1;
+ }
+
+ void start_of_simulation()
+ {
+ one_sig.write(2);
+ many_sig.write(2);
+ g1 = 1;
+ }
+
+ void T()
+ {
+ wait(delay);
+ port.write(true);
+ g2 = 1;
+ }
+
+ void method_process_1()
+ {
+ one_sig.write(3);
+ many_sig.write(3);
+ }
+
+ void method_process_2()
+ {
+ if (first_run)
+ {
+ first_run = false;
+ next_trigger(SC_ZERO_TIME);
+ }
+ else
+ {
+ try {
+ one_sig = 4;
+ }
+ catch (const std::exception& e) {
+ g3 = 1;
+ }
+ many_sig.write(4);
+ }
+ }
+
+ SC_HAS_PROCESS(M);
+};
+
+struct Top: sc_module
+{
+ M *m1;
+ M *m2;
+
+ sc_signal<bool,SC_MANY_WRITERS> many_sig_1;
+ sc_signal<int,SC_MANY_WRITERS> many_sig_2;
+ sc_signal<int,SC_ONE_WRITER> one_sig_1;
+ sc_signal<int> one_sig_2;
+
+ sc_buffer<sc_logic, SC_MANY_WRITERS> buffy;
+
+ sc_signal_resolved resolved;
+ sc_signal_rv<2> rv;
+
+ Top(sc_module_name _name)
+ : many_sig_1("many_sig_1")
+ , many_sig_2("many_sig_2")
+ , one_sig_1("one_sig_1")
+ , buffy("buffy")
+ , resolved("resolved")
+ , rv("rv")
+ {
+ m1 = new M("m1", sc_time(1, SC_PS));
+ m2 = new M("m2", sc_time(2, SC_PS));
+
+ m1->port.bind(many_sig_1);
+ m2->port.bind(many_sig_1);
+
+ SC_THREAD(T1);
+ SC_THREAD(T2);
+ sc_spawn(sc_bind(&Top::T3, this));
+
+ sc_assert( many_sig_1.get_writer_policy() == SC_MANY_WRITERS );
+ sc_assert( many_sig_2.get_writer_policy() == SC_MANY_WRITERS );
+ sc_assert( one_sig_1 .get_writer_policy() == SC_ONE_WRITER );
+ sc_assert( one_sig_2 .get_writer_policy() == SC_ONE_WRITER );
+ sc_assert( buffy .get_writer_policy() == SC_MANY_WRITERS );
+ sc_assert( resolved .get_writer_policy() == SC_MANY_WRITERS );
+ sc_assert( rv .get_writer_policy() == SC_MANY_WRITERS );
+
+ one_sig_1 = 0;
+ buffy = SC_LOGIC_X;
+ resolved = SC_LOGIC_Z;
+ rv = sc_lv<2>("ZZ");
+
+ // Writes outside of a process should not count as manyple writers
+ many_sig_1.write(true);
+ many_sig_2.write(0);
+ one_sig_1.write(0);
+ one_sig_2.write(0);
+ buffy.write(SC_LOGIC_0);
+
+ f0 = f1 = f2 = f3 = f4 = f5 = 0;
+
+ }
+
+ int f0, f1, f2, f3, f4, f5;
+
+ void T1()
+ {
+ resolved = SC_LOGIC_0;
+ rv = sc_lv<2>("01");
+
+ // Attempt to write SC_ONE_WRITER signal from >1 process should fail
+ try {
+ one_sig_1 = 1;
+ }
+ catch (const std::exception& e) {
+ f3 = 1;
+ }
+
+ try {
+ one_sig_2 = 1;
+ }
+ catch (const std::exception& e) {
+ f4 = 1;
+ }
+ wait(1, SC_PS);
+
+ // Attempt to write SC_MANY_WRITER signal from >1 process IN SAME DELTA should fail
+ try {
+ many_sig_2.write(3);
+ }
+ catch (const std::exception& e) {
+ f5 = 1;
+ }
+ wait(3, SC_PS);
+
+ many_sig_2.write(6);
+ buffy = SC_LOGIC_0;
+
+ wait(many_sig_2.default_event());
+ f0 = 1;
+ }
+
+ void T2()
+ {
+ resolved = SC_LOGIC_1;
+ rv = sc_lv<2>("10");
+
+ try {
+ one_sig_1 = 2;
+ }
+ catch (const std::exception& e) {
+ f3 = 1;
+ }
+
+ try {
+ one_sig_2 = 2;
+ }
+ catch (const std::exception& e) {
+ f4 = 1;
+ }
+ wait(1, SC_PS);
+
+ try {
+ many_sig_2.write(4);
+ }
+ catch (const std::exception& e) {
+ f5 = 1;
+ }
+ wait(4, SC_PS);
+
+ many_sig_2.write(7);
+ buffy = SC_LOGIC_1;
+
+ wait(many_sig_2.default_event());
+ f1 = 1;
+ }
+
+ void T3()
+ {
+ resolved = SC_LOGIC_Z;
+ rv = sc_lv<2>("ZZ");
+
+ try {
+ one_sig_1 = 3;
+ }
+ catch (const std::exception& e) {
+ f3 = 1;
+ }
+
+ try {
+ one_sig_2 = 3;
+ }
+ catch (const std::exception& e) {
+ f4 = 1;
+ }
+ wait(1, SC_PS);
+
+ try {
+ many_sig_2.write(5);
+ }
+ catch (const std::exception& e) {
+ f5 = 1;
+ }
+ wait(5, SC_PS);
+
+ many_sig_2.write(8);
+ buffy = SC_LOGIC_0;
+
+ wait(many_sig_2.default_event());
+ f2 = 1;
+
+ sc_assert( resolved.read() == SC_LOGIC_X );
+ sc_assert( rv.read() == sc_lv<2>("XX") );
+ sc_assert( many_sig_2.read() == 8 );
+ sc_assert( buffy.read() == SC_LOGIC_0 );
+ }
+
+ SC_HAS_PROCESS(Top);
+};
+
+
+int sc_main(int argc, char* argv[])
+{
+ Top top("top");
+ sc_start();
+
+ sc_assert( top.f0 );
+ sc_assert( top.f1 );
+ sc_assert( top.f2 );
+ sc_assert( top.f3 );
+ sc_assert( top.f4 );
+ sc_assert( top.f5 );
+
+ sc_assert( top.m1->g0 );
+ sc_assert( top.m2->g0 );
+ sc_assert( top.m1->g1 );
+ sc_assert( top.m2->g1 );
+ sc_assert( top.m1->g2 );
+ sc_assert( top.m2->g2 );
+ sc_assert( top.m1->g3 );
+ sc_assert( top.m2->g3 );
+
+ cout << endl << "Success" << endl;
+ return 0;
+}
+