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