sensitivity.hh revision 13288
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 }; 86 87 virtual Category category() = 0; 88 89 bool ofMethod(); 90}; 91 92 93/* 94 * Dynamic vs. static sensitivity. 95 */ 96 97class DynamicSensitivity : virtual public Sensitivity 98{ 99 protected: 100 DynamicSensitivity(Process *p) : Sensitivity(p) {} 101 102 void addToEvent(const ::sc_core::sc_event *e) override; 103 void delFromEvent(const ::sc_core::sc_event *e) override; 104 105 public: 106 Category category() override { return Dynamic; } 107}; 108 109typedef std::vector<DynamicSensitivity *> DynamicSensitivities; 110 111 112class StaticSensitivity : virtual public Sensitivity 113{ 114 protected: 115 StaticSensitivity(Process *p) : Sensitivity(p) {} 116 117 void addToEvent(const ::sc_core::sc_event *e) override; 118 void delFromEvent(const ::sc_core::sc_event *e) override; 119 120 public: 121 Category category() override { return Static; } 122}; 123 124typedef std::vector<StaticSensitivity *> StaticSensitivities; 125 126 127/* 128 * Sensitivity to an event or events, which can be static or dynamic. 129 */ 130 131class SensitivityEvent : virtual public Sensitivity 132{ 133 protected: 134 const ::sc_core::sc_event *event; 135 136 SensitivityEvent(Process *p, const ::sc_core::sc_event *e=nullptr) : 137 Sensitivity(p), event(e) 138 {} 139 140 public: 141 void clear() override { delFromEvent(event); } 142}; 143 144class SensitivityEvents : virtual public Sensitivity 145{ 146 protected: 147 std::set<const ::sc_core::sc_event *> events; 148 149 SensitivityEvents(Process *p) : Sensitivity(p) {} 150 SensitivityEvents( 151 Process *p, const std::set<const ::sc_core::sc_event *> &s) : 152 Sensitivity(p), events(s) 153 {} 154 155 public: 156 void 157 clear() override 158 { 159 for (auto event: events) 160 delFromEvent(event); 161 } 162 163 void 164 addEvent(const ::sc_core::sc_event *event) 165 { 166 events.insert(event); 167 addToEvent(event); 168 } 169}; 170 171 172/* 173 * Static sensitivities. 174 */ 175 176void newStaticSensitivityEvent(Process *p, const sc_core::sc_event *e); 177void newStaticSensitivityInterface(Process *p, const sc_core::sc_interface *i); 178void newStaticSensitivityPort(Process *p, const sc_core::sc_port_base *pb); 179void newStaticSensitivityExport( 180 Process *p, const sc_core::sc_export_base *exp); 181void newStaticSensitivityFinder( 182 Process *p, const sc_core::sc_event_finder *f); 183 184 185class StaticSensitivityEvent : 186 public StaticSensitivity, public SensitivityEvent 187{ 188 friend void newStaticSensitivityEvent( 189 Process *p, const sc_core::sc_event *e); 190 191 protected: 192 StaticSensitivityEvent(Process *p, const sc_core::sc_event *e) : 193 Sensitivity(p), StaticSensitivity(p), SensitivityEvent(p, e) 194 {} 195}; 196 197class StaticSensitivityInterface : 198 public StaticSensitivity, public SensitivityEvent 199{ 200 friend void newStaticSensitivityInterface( 201 Process *p, const sc_core::sc_interface *i); 202 protected: 203 StaticSensitivityInterface(Process *p, const sc_core::sc_interface *i); 204}; 205 206class StaticSensitivityPort : 207 public StaticSensitivity, public SensitivityEvents 208{ 209 friend void newStaticSensitivityPort( 210 Process *p, const sc_core::sc_port_base *pb); 211 212 protected: 213 StaticSensitivityPort(Process *p) : 214 Sensitivity(p), StaticSensitivity(p), SensitivityEvents(p) 215 {} 216}; 217 218class StaticSensitivityExport : 219 public StaticSensitivity, public SensitivityEvent 220{ 221 private: 222 friend void newStaticSensitivityExport( 223 Process *p, const sc_core::sc_export_base *exp); 224 225 StaticSensitivityExport(Process *p, const sc_core::sc_export_base *exp); 226}; 227 228 229class StaticSensitivityFinder : 230 public StaticSensitivity, public SensitivityEvents 231{ 232 private: 233 const sc_core::sc_event_finder *finder; 234 235 friend void newStaticSensitivityFinder( 236 Process *p, const sc_core::sc_event_finder *f); 237 238 StaticSensitivityFinder(Process *p, const sc_core::sc_event_finder *f) : 239 Sensitivity(p), StaticSensitivity(p), SensitivityEvents(p), finder(f) 240 {} 241 242 public: 243 const ::sc_core::sc_event &find(::sc_core::sc_interface *i); 244}; 245 246 247/* 248 * Dynamic sensitivities. 249 */ 250 251void newDynamicSensitivityEvent(Process *p, const sc_core::sc_event *e); 252void newDynamicSensitivityEventOrList( 253 Process *p, const sc_core::sc_event_or_list *eol); 254void newDynamicSensitivityEventAndList( 255 Process *p, const sc_core::sc_event_and_list *eal); 256 257class DynamicSensitivityEvent : 258 public DynamicSensitivity, public SensitivityEvent 259{ 260 private: 261 friend void newDynamicSensitivityEvent( 262 Process *p, const sc_core::sc_event *e); 263 264 DynamicSensitivityEvent(Process *p, const sc_core::sc_event *e) : 265 Sensitivity(p), DynamicSensitivity(p), SensitivityEvent(p, e) 266 {} 267}; 268 269class DynamicSensitivityEventOrList : 270 public DynamicSensitivity, public SensitivityEvents 271{ 272 private: 273 friend void newDynamicSensitivityEventOrList( 274 Process *p, const sc_core::sc_event_or_list *eol); 275 276 DynamicSensitivityEventOrList( 277 Process *p, const sc_core::sc_event_or_list *eol); 278 279 bool notify(Event *e) override; 280}; 281 282//XXX This sensitivity can't be reused. To reset it, it has to be deleted and 283//recreated. That works for dynamic sensitivities, but not for static. 284//Fortunately processes can't be statically sensitive to sc_event_and_lists. 285class DynamicSensitivityEventAndList : 286 public DynamicSensitivity, public SensitivityEvents 287{ 288 private: 289 friend void newDynamicSensitivityEventAndList( 290 Process *p, const sc_core::sc_event_and_list *eal); 291 292 DynamicSensitivityEventAndList( 293 Process *p, const sc_core::sc_event_and_list *eal); 294 295 bool notify(Event *e) override; 296}; 297 298} // namespace sc_gem5 299 300#endif //__SYSTEMC_CORE_SENSITIVITY_HH__ 301