sensitivity.hh revision 13260
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 virtual bool 76 notifyWork(Event *e) 77 { 78 satisfy(); 79 return true; 80 } 81 82 public: 83 virtual void clear() = 0; 84 85 void satisfy(); 86 bool notify(Event *e); 87 88 enum Category 89 { 90 Static, 91 Dynamic, 92 Reset 93 }; 94 95 virtual Category category() = 0; 96 97 bool ofMethod(); 98}; 99 100 101/* 102 * Dynamic vs. static vs. reset sensitivity. 103 */ 104 105class DynamicSensitivity : virtual public Sensitivity 106{ 107 protected: 108 DynamicSensitivity(Process *p) : Sensitivity(p) {} 109 110 void addToEvent(const ::sc_core::sc_event *e) override; 111 void delFromEvent(const ::sc_core::sc_event *e) override; 112 113 public: 114 Category category() override { return Dynamic; } 115}; 116 117typedef std::vector<DynamicSensitivity *> DynamicSensitivities; 118 119 120class StaticSensitivity : virtual public Sensitivity 121{ 122 protected: 123 StaticSensitivity(Process *p) : Sensitivity(p) {} 124 125 void addToEvent(const ::sc_core::sc_event *e) override; 126 void delFromEvent(const ::sc_core::sc_event *e) override; 127 128 public: 129 Category category() override { return Static; } 130}; 131 132typedef std::vector<StaticSensitivity *> StaticSensitivities; 133 134class ResetSensitivity : virtual public Sensitivity 135{ 136 private: 137 bool _val; 138 bool _sync; 139 140 protected: 141 ResetSensitivity(Process *p, bool _val, bool _sync) : 142 Sensitivity(p), _val(_val), _sync(_sync) 143 {} 144 145 void addToEvent(const ::sc_core::sc_event *e) override; 146 void delFromEvent(const ::sc_core::sc_event *e) override; 147 148 bool val() { return _val; } 149 bool sync() { return _sync; } 150 151 public: 152 Category category() override { return Reset; } 153}; 154 155typedef std::vector<ResetSensitivity *> ResetSensitivities; 156 157 158/* 159 * Sensitivity to an event or events, which can be static or dynamic. 160 */ 161 162class SensitivityEvent : virtual public Sensitivity 163{ 164 protected: 165 const ::sc_core::sc_event *event; 166 167 SensitivityEvent(Process *p, const ::sc_core::sc_event *e=nullptr) : 168 Sensitivity(p), event(e) 169 {} 170 171 public: 172 void clear() override { delFromEvent(event); } 173}; 174 175class SensitivityEvents : virtual public Sensitivity 176{ 177 protected: 178 std::set<const ::sc_core::sc_event *> events; 179 180 SensitivityEvents(Process *p) : Sensitivity(p) {} 181 SensitivityEvents( 182 Process *p, const std::set<const ::sc_core::sc_event *> &s) : 183 Sensitivity(p), events(s) 184 {} 185 186 public: 187 void 188 clear() override 189 { 190 for (auto event: events) 191 delFromEvent(event); 192 } 193 194 void 195 addEvent(const ::sc_core::sc_event *event) 196 { 197 events.insert(event); 198 addToEvent(event); 199 } 200}; 201 202 203/* 204 * Static sensitivities. 205 */ 206 207void newStaticSensitivityEvent(Process *p, const sc_core::sc_event *e); 208void newStaticSensitivityInterface(Process *p, const sc_core::sc_interface *i); 209void newStaticSensitivityPort(Process *p, const sc_core::sc_port_base *pb); 210void newStaticSensitivityExport( 211 Process *p, const sc_core::sc_export_base *exp); 212void newStaticSensitivityFinder( 213 Process *p, const sc_core::sc_event_finder *f); 214 215 216class StaticSensitivityEvent : 217 public StaticSensitivity, public SensitivityEvent 218{ 219 friend void newStaticSensitivityEvent( 220 Process *p, const sc_core::sc_event *e); 221 222 protected: 223 StaticSensitivityEvent(Process *p, const sc_core::sc_event *e) : 224 Sensitivity(p), StaticSensitivity(p), SensitivityEvent(p, e) 225 {} 226}; 227 228class StaticSensitivityInterface : 229 public StaticSensitivity, public SensitivityEvent 230{ 231 friend void newStaticSensitivityInterface( 232 Process *p, const sc_core::sc_interface *i); 233 protected: 234 StaticSensitivityInterface(Process *p, const sc_core::sc_interface *i); 235}; 236 237class StaticSensitivityPort : 238 public StaticSensitivity, public SensitivityEvents 239{ 240 friend void newStaticSensitivityPort( 241 Process *p, const sc_core::sc_port_base *pb); 242 243 protected: 244 StaticSensitivityPort(Process *p) : 245 Sensitivity(p), StaticSensitivity(p), SensitivityEvents(p) 246 {} 247}; 248 249class StaticSensitivityExport : 250 public StaticSensitivity, public SensitivityEvent 251{ 252 private: 253 friend void newStaticSensitivityExport( 254 Process *p, const sc_core::sc_export_base *exp); 255 256 StaticSensitivityExport(Process *p, const sc_core::sc_export_base *exp); 257}; 258 259 260class StaticSensitivityFinder : 261 public StaticSensitivity, public SensitivityEvents 262{ 263 private: 264 const sc_core::sc_event_finder *finder; 265 266 friend void newStaticSensitivityFinder( 267 Process *p, const sc_core::sc_event_finder *f); 268 269 StaticSensitivityFinder(Process *p, const sc_core::sc_event_finder *f) : 270 Sensitivity(p), StaticSensitivity(p), SensitivityEvents(p), finder(f) 271 {} 272 273 public: 274 const ::sc_core::sc_event &find(::sc_core::sc_interface *i); 275}; 276 277 278/* 279 * Dynamic sensitivities. 280 */ 281 282void newDynamicSensitivityEvent(Process *p, const sc_core::sc_event *e); 283void newDynamicSensitivityEventOrList( 284 Process *p, const sc_core::sc_event_or_list *eol); 285void newDynamicSensitivityEventAndList( 286 Process *p, const sc_core::sc_event_and_list *eal); 287 288class DynamicSensitivityEvent : 289 public DynamicSensitivity, public SensitivityEvent 290{ 291 private: 292 friend void newDynamicSensitivityEvent( 293 Process *p, const sc_core::sc_event *e); 294 295 DynamicSensitivityEvent(Process *p, const sc_core::sc_event *e) : 296 Sensitivity(p), DynamicSensitivity(p), SensitivityEvent(p, e) 297 {} 298}; 299 300class DynamicSensitivityEventOrList : 301 public DynamicSensitivity, public SensitivityEvents 302{ 303 private: 304 friend void newDynamicSensitivityEventOrList( 305 Process *p, const sc_core::sc_event_or_list *eol); 306 307 DynamicSensitivityEventOrList( 308 Process *p, const sc_core::sc_event_or_list *eol); 309 310 bool notifyWork(Event *e) override; 311}; 312 313//XXX This sensitivity can't be reused. To reset it, it has to be deleted and 314//recreated. That works for dynamic sensitivities, but not for static. 315//Fortunately processes can't be statically sensitive to sc_event_and_lists. 316class DynamicSensitivityEventAndList : 317 public DynamicSensitivity, public SensitivityEvents 318{ 319 private: 320 friend void newDynamicSensitivityEventAndList( 321 Process *p, const sc_core::sc_event_and_list *eal); 322 323 DynamicSensitivityEventAndList( 324 Process *p, const sc_core::sc_event_and_list *eal); 325 326 bool notifyWork(Event *e) override; 327}; 328 329/* 330 * Reset sensitivities. 331 */ 332 333void newResetSensitivitySignal( 334 Process *p, const sc_core::sc_signal_in_if<bool> *signal, 335 bool val, bool sync); 336 337void newResetSensitivityPort( 338 Process *p, const sc_core::sc_in<bool> *port, bool val, bool sync); 339void newResetSensitivityPort( 340 Process *p, const sc_core::sc_inout<bool> *port, bool val, bool sync); 341void newResetSensitivityPort( 342 Process *p, const sc_core::sc_out<bool> *port, bool val, bool sync); 343 344class ResetSensitivitySignal : 345 public ResetSensitivity, public SensitivityEvent 346{ 347 protected: 348 const sc_core::sc_signal_in_if<bool> *_signal; 349 350 friend void newResetSensitivitySignal( 351 Process *p, const sc_core::sc_signal_in_if<bool> *signal, 352 bool val, bool sync); 353 354 ResetSensitivitySignal( 355 Process *p, const sc_core::sc_signal_in_if<bool> *signal, 356 bool _val, bool _sync); 357 358 bool notifyWork(Event *e) override; 359}; 360 361class ResetSensitivityPort : public ResetSensitivitySignal 362{ 363 private: 364 friend void newResetSensitivityPort( 365 Process *p, const sc_core::sc_in<bool> *port, bool val, bool sync); 366 friend void newResetSensitivityPort( 367 Process *p, const sc_core::sc_inout<bool> *port, 368 bool val, bool sync); 369 friend void newResetSensitivityPort( 370 Process *p, const sc_core::sc_out<bool> *port, 371 bool val, bool sync); 372 373 ResetSensitivityPort( 374 Process *p, const sc_core::sc_port_base *port, 375 bool _val, bool _sync) : 376 Sensitivity(p), ResetSensitivitySignal(p, nullptr, _val, _sync) 377 {} 378 379 public: 380 void setSignal(const ::sc_core::sc_signal_in_if<bool> *signal); 381}; 382 383} // namespace sc_gem5 384 385#endif //__SYSTEMC_CORE_SENSITIVITY_HH__ 386