test15.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 test15.cpp -- sc_writer_policy: check conflicts within an evaluation phase 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 = 4; 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); 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-2-1-2 in the same delta cycle" << std::endl; 101 trigger(1); 102 trigger(2); // error expected 103 trigger(1); // NO error expected (original process) 104 trigger(2); // error expected 105 wait(SC_ZERO_TIME); 106 log(); 107 108 wait(1, SC_NS); 109 std::cout << "\n*** trigger 2-1 in the same delta cycle" << std::endl; 110 trigger(2); 111 trigger(1); // error expected 112 wait(SC_ZERO_TIME); 113 log(); 114 115 wait(1, SC_NS); 116 std::cout << "\n*** trigger 1-3 in the same delta cycle" << std::endl; 117 trigger(1); 118 trigger(3); // error expected 119 wait(SC_ZERO_TIME); 120 log(); 121 122 wait(1, SC_NS); 123 std::cout << "\n*** trigger 1-4-1 in the same delta cycle" << std::endl; 124 trigger(1); 125 trigger(4); // error expected? (same value) 126 trigger(1); // NO error expected (original process) 127 wait(SC_ZERO_TIME); 128 log(); 129 130 wait(1, SC_NS); 131 std::cout << "\n*** trigger 4-1 in the same delta cycle" << std::endl; 132 trigger(4); 133 trigger(1); // error expected? (same value) 134 wait(SC_ZERO_TIME); 135 log(); 136 } 137 138 void trigger(int id) { 139 sc_assert( id > 0 && id <= num_drivers ); 140 ev[id-1].notify(); 141 wait(ev_schedule); 142 } 143 144 void driver(int value) { 145 log(value); 146 try { 147 sig.write(value); 148 } catch (const sc_core::sc_report& msg ) { 149 std::cout << "\n" << msg.what() << "\n" << std::endl; 150 } 151 ev_schedule.notify(); 152 } 153 154 void log(int value = -1) { 155 std::cout 156 << std::setw(8) << sc_core::sc_get_current_process_handle().name() << ": " 157 << std::setw(5) << sc_core::sc_time_stamp() 158 << " @ " << std::setw(2) << sc_core::sc_delta_count() << ": " 159 << ( (value!=-1) ? "writing " : "reading " ) 160 << sig.name() << " = " 161 << ( (value!=-1) ? value : sig.read() ) 162 << std::endl; 163 } 164 165 sc_core::sc_signal<int, sc_core::SC_MANY_WRITERS> sig; 166 sc_core::sc_event ev_schedule, ev[num_drivers]; 167}; 168 169int sc_main( int, char*[] ) 170{ 171 dut top("dut"); 172 sc_core::sc_start(); 173 std::cout << "\nProgram completed" << std::endl; 174 return 0; 175} 176