sc_writer_policy.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// sc_writer_policy.cpp -- test for 21// 22// Original Author: John Aynsley, Doulos, Inc. 23// 24// MODIFICATION LOG - modifiers, enter your name, affiliation, date and 25// 26// $Log: sc_writer_policy.cpp,v $ 27// Revision 1.2 2011/05/08 19:18:46 acg 28// Andy Goodrich: remove extraneous + prefixes from git diff. 29// 30 31// sc_writer_policy template argument of class sc_signal 32 33#define SC_INCLUDE_DYNAMIC_PROCESSES 34#include <systemc> 35 36using namespace sc_core; 37using namespace sc_dt; 38using std::cout; 39using std::endl; 40using std::string; 41 42 43struct M: sc_module 44{ 45 sc_inout<bool> port; 46 47 sc_time delay; 48 sc_signal<int> one_sig; 49 sc_signal<int, SC_MANY_WRITERS> many_sig; 50 51 bool first_run; 52 int g0, g1, g2, g3; 53 54 M(sc_module_name _name, sc_time _delay) 55 : port("port") 56 , delay(_delay) 57 , first_run(true) 58 { 59 sc_assert( one_sig.get_writer_policy() == SC_ONE_WRITER ); 60 sc_assert( many_sig.get_writer_policy() == SC_MANY_WRITERS ); 61 62 SC_THREAD(T); 63 SC_METHOD(method_process_1); 64 SC_METHOD(method_process_2); 65 66 one_sig.write(-1); 67 many_sig.write(-1); 68 69 g0 = g1 = g2 = g3 = 0; 70 } 71 72 void end_of_elaboration() 73 { 74 sc_assert( port->get_writer_policy() == SC_MANY_WRITERS ); 75 one_sig.write(1); 76 many_sig.write(1); 77 g0 = 1; 78 } 79 80 void start_of_simulation() 81 { 82 one_sig.write(2); 83 many_sig.write(2); 84 g1 = 1; 85 } 86 87 void T() 88 { 89 wait(delay); 90 port.write(true); 91 g2 = 1; 92 } 93 94 void method_process_1() 95 { 96 one_sig.write(3); 97 many_sig.write(3); 98 } 99 100 void method_process_2() 101 { 102 if (first_run) 103 { 104 first_run = false; 105 next_trigger(SC_ZERO_TIME); 106 } 107 else 108 { 109 try { 110 one_sig = 4; 111 } 112 catch (const std::exception& e) { 113 g3 = 1; 114 } 115 many_sig.write(4); 116 } 117 } 118 119 SC_HAS_PROCESS(M); 120}; 121 122struct Top: sc_module 123{ 124 M *m1; 125 M *m2; 126 127 sc_signal<bool,SC_MANY_WRITERS> many_sig_1; 128 sc_signal<int,SC_MANY_WRITERS> many_sig_2; 129 sc_signal<int,SC_ONE_WRITER> one_sig_1; 130 sc_signal<int> one_sig_2; 131 132 sc_buffer<sc_logic, SC_MANY_WRITERS> buffy; 133 134 sc_signal_resolved resolved; 135 sc_signal_rv<2> rv; 136 137 Top(sc_module_name _name) 138 : many_sig_1("many_sig_1") 139 , many_sig_2("many_sig_2") 140 , one_sig_1("one_sig_1") 141 , buffy("buffy") 142 , resolved("resolved") 143 , rv("rv") 144 { 145 m1 = new M("m1", sc_time(1, SC_PS)); 146 m2 = new M("m2", sc_time(2, SC_PS)); 147 148 m1->port.bind(many_sig_1); 149 m2->port.bind(many_sig_1); 150 151 SC_THREAD(T1); 152 SC_THREAD(T2); 153 sc_spawn(sc_bind(&Top::T3, this)); 154 155 sc_assert( many_sig_1.get_writer_policy() == SC_MANY_WRITERS ); 156 sc_assert( many_sig_2.get_writer_policy() == SC_MANY_WRITERS ); 157 sc_assert( one_sig_1 .get_writer_policy() == SC_ONE_WRITER ); 158 sc_assert( one_sig_2 .get_writer_policy() == SC_ONE_WRITER ); 159 sc_assert( buffy .get_writer_policy() == SC_MANY_WRITERS ); 160 sc_assert( resolved .get_writer_policy() == SC_MANY_WRITERS ); 161 sc_assert( rv .get_writer_policy() == SC_MANY_WRITERS ); 162 163 one_sig_1 = 0; 164 buffy = SC_LOGIC_X; 165 resolved = SC_LOGIC_Z; 166 rv = sc_lv<2>("ZZ"); 167 168 // Writes outside of a process should not count as manyple writers 169 many_sig_1.write(true); 170 many_sig_2.write(0); 171 one_sig_1.write(0); 172 one_sig_2.write(0); 173 buffy.write(SC_LOGIC_0); 174 175 f0 = f1 = f2 = f3 = f4 = f5 = 0; 176 177 } 178 179 int f0, f1, f2, f3, f4, f5; 180 181 void T1() 182 { 183 resolved = SC_LOGIC_0; 184 rv = sc_lv<2>("01"); 185 186 // Attempt to write SC_ONE_WRITER signal from >1 process should fail 187 try { 188 one_sig_1 = 1; 189 } 190 catch (const std::exception& e) { 191 f3 = 1; 192 } 193 194 try { 195 one_sig_2 = 1; 196 } 197 catch (const std::exception& e) { 198 f4 = 1; 199 } 200 wait(1, SC_PS); 201 202 // Attempt to write SC_MANY_WRITER signal from >1 process IN SAME DELTA should fail 203 try { 204 many_sig_2.write(3); 205 } 206 catch (const std::exception& e) { 207 f5 = 1; 208 } 209 wait(3, SC_PS); 210 211 many_sig_2.write(6); 212 buffy = SC_LOGIC_0; 213 214 wait(many_sig_2.default_event()); 215 f0 = 1; 216 } 217 218 void T2() 219 { 220 resolved = SC_LOGIC_1; 221 rv = sc_lv<2>("10"); 222 223 try { 224 one_sig_1 = 2; 225 } 226 catch (const std::exception& e) { 227 f3 = 1; 228 } 229 230 try { 231 one_sig_2 = 2; 232 } 233 catch (const std::exception& e) { 234 f4 = 1; 235 } 236 wait(1, SC_PS); 237 238 try { 239 many_sig_2.write(4); 240 } 241 catch (const std::exception& e) { 242 f5 = 1; 243 } 244 wait(4, SC_PS); 245 246 many_sig_2.write(7); 247 buffy = SC_LOGIC_1; 248 249 wait(many_sig_2.default_event()); 250 f1 = 1; 251 } 252 253 void T3() 254 { 255 resolved = SC_LOGIC_Z; 256 rv = sc_lv<2>("ZZ"); 257 258 try { 259 one_sig_1 = 3; 260 } 261 catch (const std::exception& e) { 262 f3 = 1; 263 } 264 265 try { 266 one_sig_2 = 3; 267 } 268 catch (const std::exception& e) { 269 f4 = 1; 270 } 271 wait(1, SC_PS); 272 273 try { 274 many_sig_2.write(5); 275 } 276 catch (const std::exception& e) { 277 f5 = 1; 278 } 279 wait(5, SC_PS); 280 281 many_sig_2.write(8); 282 buffy = SC_LOGIC_0; 283 284 wait(many_sig_2.default_event()); 285 f2 = 1; 286 287 sc_assert( resolved.read() == SC_LOGIC_X ); 288 sc_assert( rv.read() == sc_lv<2>("XX") ); 289 sc_assert( many_sig_2.read() == 8 ); 290 sc_assert( buffy.read() == SC_LOGIC_0 ); 291 } 292 293 SC_HAS_PROCESS(Top); 294}; 295 296 297int sc_main(int argc, char* argv[]) 298{ 299 Top top("top"); 300 sc_start(); 301 302 sc_assert( top.f0 ); 303 sc_assert( top.f1 ); 304 sc_assert( top.f2 ); 305 sc_assert( top.f3 ); 306 sc_assert( top.f4 ); 307 sc_assert( top.f5 ); 308 309 sc_assert( top.m1->g0 ); 310 sc_assert( top.m2->g0 ); 311 sc_assert( top.m1->g1 ); 312 sc_assert( top.m2->g1 ); 313 sc_assert( top.m1->g2 ); 314 sc_assert( top.m2->g2 ); 315 sc_assert( top.m1->g3 ); 316 sc_assert( top.m2->g3 ); 317 318 cout << endl << "Success" << endl; 319 return 0; 320} 321 322