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