sensitivity.hh revision 13262:ef4b783f84f7
1/* 2 * Copyright 2018 Google, Inc. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer; 8 * redistributions in binary form must reproduce the above copyright 9 * notice, this list of conditions and the following disclaimer in the 10 * documentation and/or other materials provided with the distribution; 11 * neither the name of the copyright holders nor the names of its 12 * contributors may be used to endorse or promote products derived from 13 * this software without specific prior written permission. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 * Authors: Gabe Black 28 */ 29 30#ifndef __SYSTEMC_CORE_SENSITIVITY_HH__ 31#define __SYSTEMC_CORE_SENSITIVITY_HH__ 32 33#include <set> 34#include <vector> 35 36#include "sim/eventq.hh" 37#include "systemc/core/sched_event.hh" 38#include "systemc/ext/core/sc_module.hh" 39#include "systemc/ext/core/sc_port.hh" 40 41namespace sc_core 42{ 43 44class sc_event; 45class sc_event_and_list; 46class sc_event_or_list; 47class sc_event_finder; 48class sc_export_base; 49class sc_interface; 50class sc_port_base; 51 52} // namespace sc_core 53 54namespace sc_gem5 55{ 56 57class Process; 58class Event; 59 60/* 61 * Common sensitivity interface. 62 */ 63 64class Sensitivity 65{ 66 protected: 67 Process *process; 68 69 Sensitivity(Process *p) : process(p) {} 70 virtual ~Sensitivity() {} 71 72 virtual void addToEvent(const ::sc_core::sc_event *e) = 0; 73 virtual void delFromEvent(const ::sc_core::sc_event *e) = 0; 74 75 public: 76 virtual void clear() = 0; 77 78 void satisfy(); 79 virtual bool notify(Event *e); 80 81 enum Category 82 { 83 Static, 84 Dynamic, 85 Reset 86 }; 87 88 virtual Category category() = 0; 89 90 bool ofMethod(); 91}; 92 93 94/* 95 * Dynamic vs. static vs. reset sensitivity. 96 */ 97 98class DynamicSensitivity : virtual public Sensitivity 99{ 100 protected: 101 DynamicSensitivity(Process *p) : Sensitivity(p) {} 102 103 void addToEvent(const ::sc_core::sc_event *e) override; 104 void delFromEvent(const ::sc_core::sc_event *e) override; 105 106 public: 107 Category category() override { return Dynamic; } 108}; 109 110typedef std::vector<DynamicSensitivity *> DynamicSensitivities; 111 112 113class StaticSensitivity : virtual public Sensitivity 114{ 115 protected: 116 StaticSensitivity(Process *p) : Sensitivity(p) {} 117 118 void addToEvent(const ::sc_core::sc_event *e) override; 119 void delFromEvent(const ::sc_core::sc_event *e) override; 120 121 public: 122 Category category() override { return Static; } 123}; 124 125typedef std::vector<StaticSensitivity *> StaticSensitivities; 126 127class ResetSensitivity : virtual public Sensitivity 128{ 129 private: 130 bool _val; 131 bool _sync; 132 133 protected: 134 ResetSensitivity(Process *p, bool _val, bool _sync) : 135 Sensitivity(p), _val(_val), _sync(_sync) 136 {} 137 138 void addToEvent(const ::sc_core::sc_event *e) override; 139 void delFromEvent(const ::sc_core::sc_event *e) override; 140 141 bool val() { return _val; } 142 bool sync() { return _sync; } 143 144 public: 145 Category category() override { return Reset; } 146}; 147 148typedef std::vector<ResetSensitivity *> ResetSensitivities; 149 150 151/* 152 * Sensitivity to an event or events, which can be static or dynamic. 153 */ 154 155class SensitivityEvent : virtual public Sensitivity 156{ 157 protected: 158 const ::sc_core::sc_event *event; 159 160 SensitivityEvent(Process *p, const ::sc_core::sc_event *e=nullptr) : 161 Sensitivity(p), event(e) 162 {} 163 164 public: 165 void clear() override { delFromEvent(event); } 166}; 167 168class SensitivityEvents : virtual public Sensitivity 169{ 170 protected: 171 std::set<const ::sc_core::sc_event *> events; 172 173 SensitivityEvents(Process *p) : Sensitivity(p) {} 174 SensitivityEvents( 175 Process *p, const std::set<const ::sc_core::sc_event *> &s) : 176 Sensitivity(p), events(s) 177 {} 178 179 public: 180 void 181 clear() override 182 { 183 for (auto event: events) 184 delFromEvent(event); 185 } 186 187 void 188 addEvent(const ::sc_core::sc_event *event) 189 { 190 events.insert(event); 191 addToEvent(event); 192 } 193}; 194 195 196/* 197 * Static sensitivities. 198 */ 199 200void newStaticSensitivityEvent(Process *p, const sc_core::sc_event *e); 201void newStaticSensitivityInterface(Process *p, const sc_core::sc_interface *i); 202void newStaticSensitivityPort(Process *p, const sc_core::sc_port_base *pb); 203void newStaticSensitivityExport( 204 Process *p, const sc_core::sc_export_base *exp); 205void newStaticSensitivityFinder( 206 Process *p, const sc_core::sc_event_finder *f); 207 208 209class StaticSensitivityEvent : 210 public StaticSensitivity, public SensitivityEvent 211{ 212 friend void newStaticSensitivityEvent( 213 Process *p, const sc_core::sc_event *e); 214 215 protected: 216 StaticSensitivityEvent(Process *p, const sc_core::sc_event *e) : 217 Sensitivity(p), StaticSensitivity(p), SensitivityEvent(p, e) 218 {} 219}; 220 221class StaticSensitivityInterface : 222 public StaticSensitivity, public SensitivityEvent 223{ 224 friend void newStaticSensitivityInterface( 225 Process *p, const sc_core::sc_interface *i); 226 protected: 227 StaticSensitivityInterface(Process *p, const sc_core::sc_interface *i); 228}; 229 230class StaticSensitivityPort : 231 public StaticSensitivity, public SensitivityEvents 232{ 233 friend void newStaticSensitivityPort( 234 Process *p, const sc_core::sc_port_base *pb); 235 236 protected: 237 StaticSensitivityPort(Process *p) : 238 Sensitivity(p), StaticSensitivity(p), SensitivityEvents(p) 239 {} 240}; 241 242class StaticSensitivityExport : 243 public StaticSensitivity, public SensitivityEvent 244{ 245 private: 246 friend void newStaticSensitivityExport( 247 Process *p, const sc_core::sc_export_base *exp); 248 249 StaticSensitivityExport(Process *p, const sc_core::sc_export_base *exp); 250}; 251 252 253class StaticSensitivityFinder : 254 public StaticSensitivity, public SensitivityEvents 255{ 256 private: 257 const sc_core::sc_event_finder *finder; 258 259 friend void newStaticSensitivityFinder( 260 Process *p, const sc_core::sc_event_finder *f); 261 262 StaticSensitivityFinder(Process *p, const sc_core::sc_event_finder *f) : 263 Sensitivity(p), StaticSensitivity(p), SensitivityEvents(p), finder(f) 264 {} 265 266 public: 267 const ::sc_core::sc_event &find(::sc_core::sc_interface *i); 268}; 269 270 271/* 272 * Dynamic sensitivities. 273 */ 274 275void newDynamicSensitivityEvent(Process *p, const sc_core::sc_event *e); 276void newDynamicSensitivityEventOrList( 277 Process *p, const sc_core::sc_event_or_list *eol); 278void newDynamicSensitivityEventAndList( 279 Process *p, const sc_core::sc_event_and_list *eal); 280 281class DynamicSensitivityEvent : 282 public DynamicSensitivity, public SensitivityEvent 283{ 284 private: 285 friend void newDynamicSensitivityEvent( 286 Process *p, const sc_core::sc_event *e); 287 288 DynamicSensitivityEvent(Process *p, const sc_core::sc_event *e) : 289 Sensitivity(p), DynamicSensitivity(p), SensitivityEvent(p, e) 290 {} 291}; 292 293class DynamicSensitivityEventOrList : 294 public DynamicSensitivity, public SensitivityEvents 295{ 296 private: 297 friend void newDynamicSensitivityEventOrList( 298 Process *p, const sc_core::sc_event_or_list *eol); 299 300 DynamicSensitivityEventOrList( 301 Process *p, const sc_core::sc_event_or_list *eol); 302 303 bool notify(Event *e) override; 304}; 305 306//XXX This sensitivity can't be reused. To reset it, it has to be deleted and 307//recreated. That works for dynamic sensitivities, but not for static. 308//Fortunately processes can't be statically sensitive to sc_event_and_lists. 309class DynamicSensitivityEventAndList : 310 public DynamicSensitivity, public SensitivityEvents 311{ 312 private: 313 friend void newDynamicSensitivityEventAndList( 314 Process *p, const sc_core::sc_event_and_list *eal); 315 316 DynamicSensitivityEventAndList( 317 Process *p, const sc_core::sc_event_and_list *eal); 318 319 bool notify(Event *e) override; 320}; 321 322/* 323 * Reset sensitivities. 324 */ 325 326void newResetSensitivitySignal( 327 Process *p, const sc_core::sc_signal_in_if<bool> *signal, 328 bool val, bool sync); 329 330void newResetSensitivityPort( 331 Process *p, const sc_core::sc_in<bool> *port, bool val, bool sync); 332void newResetSensitivityPort( 333 Process *p, const sc_core::sc_inout<bool> *port, bool val, bool sync); 334void newResetSensitivityPort( 335 Process *p, const sc_core::sc_out<bool> *port, bool val, bool sync); 336 337class ResetSensitivitySignal : 338 public ResetSensitivity, public SensitivityEvent 339{ 340 protected: 341 const sc_core::sc_signal_in_if<bool> *_signal; 342 343 friend void newResetSensitivitySignal( 344 Process *p, const sc_core::sc_signal_in_if<bool> *signal, 345 bool val, bool sync); 346 347 ResetSensitivitySignal( 348 Process *p, const sc_core::sc_signal_in_if<bool> *signal, 349 bool _val, bool _sync); 350 351 bool notify(Event *e) override; 352}; 353 354class ResetSensitivityPort : public ResetSensitivitySignal 355{ 356 private: 357 friend void newResetSensitivityPort( 358 Process *p, const sc_core::sc_in<bool> *port, bool val, bool sync); 359 friend void newResetSensitivityPort( 360 Process *p, const sc_core::sc_inout<bool> *port, 361 bool val, bool sync); 362 friend void newResetSensitivityPort( 363 Process *p, const sc_core::sc_out<bool> *port, 364 bool val, bool sync); 365 366 ResetSensitivityPort( 367 Process *p, const sc_core::sc_port_base *port, 368 bool _val, bool _sync) : 369 Sensitivity(p), ResetSensitivitySignal(p, nullptr, _val, _sync) 370 {} 371 372 public: 373 void setSignal(const ::sc_core::sc_signal_in_if<bool> *signal); 374}; 375 376} // namespace sc_gem5 377 378#endif //__SYSTEMC_CORE_SENSITIVITY_HH__ 379