test16.cpp revision 12855:588919e0e4aa
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 test16.cpp -- sc_writer_policy: test SC_SIGNAL_WRITE_CHECK=CONFLICT 23 24 Original Author: Philipp A. Hartmann, Intel, 2017-05-12 25 26 *****************************************************************************/ 27 28// see https://github.com/OSCI-WG/systemc/issues/222 29 30#define SC_INCLUDE_DYNAMIC_PROCESSES 31#include <systemc> 32#include <iomanip> 33#include <sstream> 34 35using sc_core::SC_NS; 36using sc_core::SC_ZERO_TIME; 37 38SC_MODULE(dut) 39{ 40 static const int num_drivers = 3; 41 42 SC_CTOR(dut) 43 : sig("sig") 44 { 45 SC_THREAD(run); 46 for(int id=1; id <= num_drivers; ++id) { 47 // first and last driver write the same values 48 spawn_driver( id, (id-1) % (num_drivers-1) + 1 ); 49 } 50 } 51 52private: 53 void spawn_driver(int id, int value) { 54 sc_assert( id > 0 && id <= num_drivers ); 55 sc_core::sc_spawn_options sp; 56 sp.set_sensitivity(&ev[id-1]); 57 sp.spawn_method(); 58 sp.dont_initialize(); 59 60 std::stringstream nm; 61 nm << "p" << id; 62 sc_spawn( sc_bind(&dut::driver, this, value), nm.str().c_str(), &sp ); 63 } 64 65 void run() { 66 wait(1, SC_NS); 67 68 std::cout << "\n*** trigger each driver in individual delta cycles" << std::endl; 69 for(int id=1; id <= num_drivers; ++id) { 70 trigger(id); // NO error expected (environment override) 71 wait(SC_ZERO_TIME); 72 log(); 73 } 74 75 wait(1, SC_NS); 76 std::cout << "\n*** trigger 1-2-3 in the same delta cycle" << std::endl; 77 trigger(1); 78 trigger(2); // error expected 79 trigger(3); // error expected 80 wait(SC_ZERO_TIME); 81 log(); 82 83 wait(1, SC_NS); 84 std::cout << "\n*** trigger 2-3-1 in the same delta cycle" << std::endl; 85 trigger(2); 86 trigger(3); // error expected 87 trigger(1); // error expected 88 wait(SC_ZERO_TIME); 89 log(); 90 91 wait(1, SC_NS); 92 std::cout << "\n*** trigger 3-1-2 in the same delta cycle" << std::endl; 93 trigger(3); 94 trigger(1); // error expected 95 trigger(2); // error expected 96 wait(SC_ZERO_TIME); 97 log(); 98 99 wait(1, SC_NS); 100 std::cout << "\n*** trigger 1-1-2-2 in the same delta cycle" << std::endl; 101 trigger(1); 102 trigger(1); // NO error expected (current process) 103 trigger(2); // error expected 104 trigger(2); // NO error expected (current process) 105 wait(SC_ZERO_TIME); 106 log(); 107 } 108 109 void trigger(int id) { 110 sc_assert( id > 0 && id <= num_drivers ); 111 ev[id-1].notify(); 112 wait(ev_schedule); 113 } 114 115 void driver(int value) { 116 log(value); 117 sig.write(value); // errors suppressed via report handler below 118 ev_schedule.notify(); 119 } 120 121 void log(int value = -1) { 122 std::cout 123 << "\n" 124 << std::setw(8) << sc_core::sc_get_current_process_handle().name() << ": " 125 << std::setw(5) << sc_core::sc_time_stamp() 126 << " @ " << std::setw(2) << sc_core::sc_delta_count() << ": " 127 << ( (value!=-1) ? "writing " : "reading " ) 128 << sig.name() << " = " 129 << ( (value!=-1) ? value : sig.read() ) 130 << std::endl; 131 } 132 133 sc_core::sc_signal<int, sc_core::SC_ONE_WRITER> sig; // use single-writer signal 134 sc_core::sc_event ev_schedule, ev[num_drivers]; 135}; 136 137#ifdef _WIN32 138#define putenv _putenv // Windows deprecates putenv 139#endif 140 141int sc_main( int, char*[] ) 142{ 143 // prepare environment variable (takes a char*) 144 putenv(const_cast<char*>("SC_SIGNAL_WRITE_CHECK=CONFLICT")); 145 // and reset simulation context to pick it up (non-standard) 146 sc_core::sc_get_curr_simcontext()->reset(); 147 148 // report multiple writer errors as warnings 149 sc_core::sc_report_handler::set_actions( 150 sc_core::SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_ 151 , sc_core::SC_DEFAULT_WARNING_ACTIONS 152 ); 153 154 dut top("dut"); 155 sc_core::sc_start(); 156 std::cout << "\nProgram completed" << std::endl; 157 return 0; 158} 159