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