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_PROCESS_HH__ 31#define __SYSTEMC_CORE_PROCESS_HH__ 32 33#include <functional> 34#include <memory> 35#include <vector> 36 37#include "base/fiber.hh" 38#include "sim/eventq.hh" 39#include "systemc/core/bindinfo.hh" 40#include "systemc/core/event.hh" 41#include "systemc/core/list.hh" 42#include "systemc/core/object.hh" 43#include "systemc/core/sched_event.hh" 44#include "systemc/ext/core/sc_event.hh" 45#include "systemc/ext/core/sc_export.hh" 46#include "systemc/ext/core/sc_interface.hh" 47#include "systemc/ext/core/sc_module.hh" 48#include "systemc/ext/core/sc_port.hh" 49#include "systemc/ext/core/sc_process_handle.hh" 50#include "systemc/ext/utils/sc_report.hh" 51
| 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_PROCESS_HH__ 31#define __SYSTEMC_CORE_PROCESS_HH__ 32 33#include <functional> 34#include <memory> 35#include <vector> 36 37#include "base/fiber.hh" 38#include "sim/eventq.hh" 39#include "systemc/core/bindinfo.hh" 40#include "systemc/core/event.hh" 41#include "systemc/core/list.hh" 42#include "systemc/core/object.hh" 43#include "systemc/core/sched_event.hh" 44#include "systemc/ext/core/sc_event.hh" 45#include "systemc/ext/core/sc_export.hh" 46#include "systemc/ext/core/sc_interface.hh" 47#include "systemc/ext/core/sc_module.hh" 48#include "systemc/ext/core/sc_port.hh" 49#include "systemc/ext/core/sc_process_handle.hh" 50#include "systemc/ext/utils/sc_report.hh" 51
|
52namespace sc_gem5 53{ 54 55class ScHalt 56{}; 57 58class Sensitivity 59{ 60 protected: 61 Process *process; 62 63 public: 64 Sensitivity(Process *p) : process(p) {} 65 virtual ~Sensitivity() {} 66 67 void satisfy(bool timedOut=false); 68 69 virtual void notifyWork(Event *e) { satisfy(); } 70 void notify(Event *e); 71 void notify() { notify(nullptr); } 72 73 const std::string name(); 74}; 75 76class SensitivityTimeout : virtual public Sensitivity 77{ 78 private: 79 void timeout(); 80 ScEvent timeoutEvent; 81 82 public: 83 SensitivityTimeout(Process *p, ::sc_core::sc_time t); 84 ~SensitivityTimeout(); 85}; 86 87class SensitivityEvent : virtual public Sensitivity 88{ 89 private: 90 const ::sc_core::sc_event *event; 91 92 public: 93 SensitivityEvent(Process *p, const ::sc_core::sc_event *e); 94 ~SensitivityEvent(); 95}; 96 97//XXX This sensitivity can't be reused. To reset it, it has to be deleted and 98//recreated. That works for dynamic sensitivities, but not for static. 99//Fortunately processes can't be statically sensitive to sc_event_and_lists. 100class SensitivityEventAndList : virtual public Sensitivity 101{ 102 private: 103 const ::sc_core::sc_event_and_list *list; 104 int count; 105 106 public: 107 SensitivityEventAndList( 108 Process *p, const ::sc_core::sc_event_and_list *list); 109 ~SensitivityEventAndList(); 110 111 void notifyWork(Event *e) override; 112}; 113 114class SensitivityEventOrList : virtual public Sensitivity 115{ 116 private: 117 const ::sc_core::sc_event_or_list *list; 118 119 public: 120 SensitivityEventOrList( 121 Process *p, const ::sc_core::sc_event_or_list *list); 122 ~SensitivityEventOrList(); 123}; 124 125// Combined sensitivities. These trigger when any of their parts do. 126 127class SensitivityTimeoutAndEvent : 128 public SensitivityTimeout, public SensitivityEvent 129{ 130 public: 131 SensitivityTimeoutAndEvent( 132 Process *p, ::sc_core::sc_time t, const ::sc_core::sc_event *e) : 133 Sensitivity(p), SensitivityTimeout(p, t), SensitivityEvent(p, e) 134 {} 135 136 void notifyWork(Event *e) override { satisfy(e == nullptr); } 137}; 138 139class SensitivityTimeoutAndEventAndList : 140 public SensitivityTimeout, public SensitivityEventAndList 141{ 142 public: 143 SensitivityTimeoutAndEventAndList( 144 Process *p, ::sc_core::sc_time t, 145 const ::sc_core::sc_event_and_list *eal) : 146 Sensitivity(p), SensitivityTimeout(p, t), 147 SensitivityEventAndList(p, eal) 148 {} 149 150 void notifyWork(Event *e) override; 151}; 152 153class SensitivityTimeoutAndEventOrList : 154 public SensitivityTimeout, public SensitivityEventOrList 155{ 156 public: 157 SensitivityTimeoutAndEventOrList( 158 Process *p, ::sc_core::sc_time t, 159 const ::sc_core::sc_event_or_list *eol) : 160 Sensitivity(p), SensitivityTimeout(p, t), 161 SensitivityEventOrList(p, eol) 162 {} 163 164 void notifyWork(Event *e) override { satisfy(e == nullptr); } 165}; 166 167typedef std::vector<Sensitivity *> Sensitivities; 168 169 170/* 171 * Pending sensitivities. These are records of sensitivities to install later, 172 * once all the information to configure them is available. 173 */ 174 175class PendingSensitivity 176{ 177 protected: 178 Process *process; 179 180 public: 181 virtual void finalize(Sensitivities &s) = 0; 182 PendingSensitivity(Process *p) : process(p) {} 183 virtual ~PendingSensitivity() {} 184}; 185 186class PendingSensitivityEvent : public PendingSensitivity 187{ 188 private: 189 const sc_core::sc_event *event; 190 191 public: 192 PendingSensitivityEvent(Process *p, const sc_core::sc_event *e) : 193 PendingSensitivity(p), event(e) {} 194 195 void 196 finalize(Sensitivities &s) override 197 { 198 s.push_back(new SensitivityEvent(process, event)); 199 } 200}; 201 202class PendingSensitivityInterface : public PendingSensitivity 203{ 204 private: 205 const sc_core::sc_interface *interface; 206 207 public: 208 PendingSensitivityInterface(Process *p, const sc_core::sc_interface *i) : 209 PendingSensitivity(p), interface(i) 210 {} 211 212 void 213 finalize(Sensitivities &s) override 214 { 215 s.push_back(new SensitivityEvent(process, 216 &interface->default_event())); 217 } 218}; 219 220class PendingSensitivityPort : public PendingSensitivity 221{ 222 private: 223 const sc_core::sc_port_base *port; 224 225 public: 226 PendingSensitivityPort(Process *p, const sc_core::sc_port_base *pb) : 227 PendingSensitivity(p), port(pb) 228 {} 229 230 void 231 finalize(Sensitivities &s) override 232 { 233 for (int i = 0; i < port->size(); i++) { 234 const ::sc_core::sc_event *e = 235 &port->_gem5Interface(i)->default_event(); 236 s.push_back(new SensitivityEvent(process, e)); 237 } 238 } 239}; 240 241class PendingSensitivityExport : public PendingSensitivity 242{ 243 private: 244 const sc_core::sc_export_base *exp; 245 246 public: 247 PendingSensitivityExport(Process *p, const sc_core::sc_export_base *exp) : 248 PendingSensitivity(p), exp(exp) 249 {} 250 251 void 252 finalize(Sensitivities &s) override 253 { 254 s.push_back(new SensitivityEvent(process, 255 &exp->get_interface()->default_event())); 256 } 257}; 258 259class PendingSensitivityFinder : public PendingSensitivity 260{ 261 private: 262 const sc_core::sc_event_finder *finder; 263 264 public: 265 PendingSensitivityFinder(Process *p, const sc_core::sc_event_finder *f) : 266 PendingSensitivity(p), finder(f) 267 {} 268 269 void 270 finalize(Sensitivities &s) override 271 { 272 const ::sc_core::sc_port_base *port = finder->port(); 273 int size = port->size(); 274 for (int i = 0; i < size; i++) { 275 ::sc_core::sc_interface *interface = port->_gem5Interface(i); 276 const ::sc_core::sc_event *event = &finder->find_event(interface); 277 s.push_back(new SensitivityEvent(process, event)); 278 } 279 } 280}; 281 282typedef std::vector<PendingSensitivity *> PendingSensitivities; 283 284 285class Process : public ::sc_core::sc_process_b, public ListNode 286{ 287 public: 288 virtual ::sc_core::sc_curr_proc_kind procKind() const = 0; 289 bool needsStart() const { return _needsStart; } 290 void needsStart(bool ns) { _needsStart = ns; } 291 bool dynamic() const { return _dynamic; } 292 bool isUnwinding() const { return _isUnwinding; } 293 void isUnwinding(bool v) { _isUnwinding = v; } 294 bool terminated() const { return _terminated; } 295 296 void forEachKid(const std::function<void(Process *)> &work); 297 298 bool suspended() const { return _suspended; } 299 bool disabled() const { return _disabled; } 300 301 void suspend(bool inc_kids); 302 void resume(bool inc_kids); 303 void disable(bool inc_kids); 304 void enable(bool inc_kids); 305 306 void kill(bool inc_kids); 307 void reset(bool inc_kids); 308 virtual void throw_it(ExceptionWrapperBase &exc, bool inc_kids); 309 310 void injectException(ExceptionWrapperBase &exc); 311 ExceptionWrapperBase *excWrapper; 312 313 void syncResetOn(bool inc_kids); 314 void syncResetOff(bool inc_kids); 315 316 void incref() { refCount++; } 317 void decref() { refCount--; } 318 319 const ::sc_core::sc_event &resetEvent() { return _resetEvent; } 320 const ::sc_core::sc_event &terminatedEvent() { return _terminatedEvent; } 321 322 void setStackSize(size_t size) { stackSize = size; } 323 324 void finalize(); 325 326 void run(); 327 328 void addStatic(PendingSensitivity *); 329 void setDynamic(Sensitivity *); 330 331 void satisfySensitivity(Sensitivity *); 332 333 void ready(); 334 335 virtual Fiber *fiber() { return Fiber::primaryFiber(); } 336 337 static Process *newest() { return _newest; } 338 339 void lastReport(::sc_core::sc_report *report); 340 ::sc_core::sc_report *lastReport() const; 341 342 bool hasStaticSensitivities() { return !staticSensitivities.empty(); } 343 bool internal() { return _internal; } 344 bool timedOut() { return _timedOut; } 345 void timedOut(bool to) { _timedOut = to; } 346 347 bool dontInitialize() { return _dontInitialize; } 348 void dontInitialize(bool di) { _dontInitialize = di; } 349
| 59namespace sc_gem5 60{ 61 62class ScHalt 63{}; 64 65class Sensitivity 66{ 67 protected: 68 Process *process; 69 70 public: 71 Sensitivity(Process *p) : process(p) {} 72 virtual ~Sensitivity() {} 73 74 void satisfy(bool timedOut=false); 75 76 virtual void notifyWork(Event *e) { satisfy(); } 77 void notify(Event *e); 78 void notify() { notify(nullptr); } 79 80 const std::string name(); 81}; 82 83class SensitivityTimeout : virtual public Sensitivity 84{ 85 private: 86 void timeout(); 87 ScEvent timeoutEvent; 88 89 public: 90 SensitivityTimeout(Process *p, ::sc_core::sc_time t); 91 ~SensitivityTimeout(); 92}; 93 94class SensitivityEvent : virtual public Sensitivity 95{ 96 private: 97 const ::sc_core::sc_event *event; 98 99 public: 100 SensitivityEvent(Process *p, const ::sc_core::sc_event *e); 101 ~SensitivityEvent(); 102}; 103 104//XXX This sensitivity can't be reused. To reset it, it has to be deleted and 105//recreated. That works for dynamic sensitivities, but not for static. 106//Fortunately processes can't be statically sensitive to sc_event_and_lists. 107class SensitivityEventAndList : virtual public Sensitivity 108{ 109 private: 110 const ::sc_core::sc_event_and_list *list; 111 int count; 112 113 public: 114 SensitivityEventAndList( 115 Process *p, const ::sc_core::sc_event_and_list *list); 116 ~SensitivityEventAndList(); 117 118 void notifyWork(Event *e) override; 119}; 120 121class SensitivityEventOrList : virtual public Sensitivity 122{ 123 private: 124 const ::sc_core::sc_event_or_list *list; 125 126 public: 127 SensitivityEventOrList( 128 Process *p, const ::sc_core::sc_event_or_list *list); 129 ~SensitivityEventOrList(); 130}; 131 132// Combined sensitivities. These trigger when any of their parts do. 133 134class SensitivityTimeoutAndEvent : 135 public SensitivityTimeout, public SensitivityEvent 136{ 137 public: 138 SensitivityTimeoutAndEvent( 139 Process *p, ::sc_core::sc_time t, const ::sc_core::sc_event *e) : 140 Sensitivity(p), SensitivityTimeout(p, t), SensitivityEvent(p, e) 141 {} 142 143 void notifyWork(Event *e) override { satisfy(e == nullptr); } 144}; 145 146class SensitivityTimeoutAndEventAndList : 147 public SensitivityTimeout, public SensitivityEventAndList 148{ 149 public: 150 SensitivityTimeoutAndEventAndList( 151 Process *p, ::sc_core::sc_time t, 152 const ::sc_core::sc_event_and_list *eal) : 153 Sensitivity(p), SensitivityTimeout(p, t), 154 SensitivityEventAndList(p, eal) 155 {} 156 157 void notifyWork(Event *e) override; 158}; 159 160class SensitivityTimeoutAndEventOrList : 161 public SensitivityTimeout, public SensitivityEventOrList 162{ 163 public: 164 SensitivityTimeoutAndEventOrList( 165 Process *p, ::sc_core::sc_time t, 166 const ::sc_core::sc_event_or_list *eol) : 167 Sensitivity(p), SensitivityTimeout(p, t), 168 SensitivityEventOrList(p, eol) 169 {} 170 171 void notifyWork(Event *e) override { satisfy(e == nullptr); } 172}; 173 174typedef std::vector<Sensitivity *> Sensitivities; 175 176 177/* 178 * Pending sensitivities. These are records of sensitivities to install later, 179 * once all the information to configure them is available. 180 */ 181 182class PendingSensitivity 183{ 184 protected: 185 Process *process; 186 187 public: 188 virtual void finalize(Sensitivities &s) = 0; 189 PendingSensitivity(Process *p) : process(p) {} 190 virtual ~PendingSensitivity() {} 191}; 192 193class PendingSensitivityEvent : public PendingSensitivity 194{ 195 private: 196 const sc_core::sc_event *event; 197 198 public: 199 PendingSensitivityEvent(Process *p, const sc_core::sc_event *e) : 200 PendingSensitivity(p), event(e) {} 201 202 void 203 finalize(Sensitivities &s) override 204 { 205 s.push_back(new SensitivityEvent(process, event)); 206 } 207}; 208 209class PendingSensitivityInterface : public PendingSensitivity 210{ 211 private: 212 const sc_core::sc_interface *interface; 213 214 public: 215 PendingSensitivityInterface(Process *p, const sc_core::sc_interface *i) : 216 PendingSensitivity(p), interface(i) 217 {} 218 219 void 220 finalize(Sensitivities &s) override 221 { 222 s.push_back(new SensitivityEvent(process, 223 &interface->default_event())); 224 } 225}; 226 227class PendingSensitivityPort : public PendingSensitivity 228{ 229 private: 230 const sc_core::sc_port_base *port; 231 232 public: 233 PendingSensitivityPort(Process *p, const sc_core::sc_port_base *pb) : 234 PendingSensitivity(p), port(pb) 235 {} 236 237 void 238 finalize(Sensitivities &s) override 239 { 240 for (int i = 0; i < port->size(); i++) { 241 const ::sc_core::sc_event *e = 242 &port->_gem5Interface(i)->default_event(); 243 s.push_back(new SensitivityEvent(process, e)); 244 } 245 } 246}; 247 248class PendingSensitivityExport : public PendingSensitivity 249{ 250 private: 251 const sc_core::sc_export_base *exp; 252 253 public: 254 PendingSensitivityExport(Process *p, const sc_core::sc_export_base *exp) : 255 PendingSensitivity(p), exp(exp) 256 {} 257 258 void 259 finalize(Sensitivities &s) override 260 { 261 s.push_back(new SensitivityEvent(process, 262 &exp->get_interface()->default_event())); 263 } 264}; 265 266class PendingSensitivityFinder : public PendingSensitivity 267{ 268 private: 269 const sc_core::sc_event_finder *finder; 270 271 public: 272 PendingSensitivityFinder(Process *p, const sc_core::sc_event_finder *f) : 273 PendingSensitivity(p), finder(f) 274 {} 275 276 void 277 finalize(Sensitivities &s) override 278 { 279 const ::sc_core::sc_port_base *port = finder->port(); 280 int size = port->size(); 281 for (int i = 0; i < size; i++) { 282 ::sc_core::sc_interface *interface = port->_gem5Interface(i); 283 const ::sc_core::sc_event *event = &finder->find_event(interface); 284 s.push_back(new SensitivityEvent(process, event)); 285 } 286 } 287}; 288 289typedef std::vector<PendingSensitivity *> PendingSensitivities; 290 291 292class Process : public ::sc_core::sc_process_b, public ListNode 293{ 294 public: 295 virtual ::sc_core::sc_curr_proc_kind procKind() const = 0; 296 bool needsStart() const { return _needsStart; } 297 void needsStart(bool ns) { _needsStart = ns; } 298 bool dynamic() const { return _dynamic; } 299 bool isUnwinding() const { return _isUnwinding; } 300 void isUnwinding(bool v) { _isUnwinding = v; } 301 bool terminated() const { return _terminated; } 302 303 void forEachKid(const std::function<void(Process *)> &work); 304 305 bool suspended() const { return _suspended; } 306 bool disabled() const { return _disabled; } 307 308 void suspend(bool inc_kids); 309 void resume(bool inc_kids); 310 void disable(bool inc_kids); 311 void enable(bool inc_kids); 312 313 void kill(bool inc_kids); 314 void reset(bool inc_kids); 315 virtual void throw_it(ExceptionWrapperBase &exc, bool inc_kids); 316 317 void injectException(ExceptionWrapperBase &exc); 318 ExceptionWrapperBase *excWrapper; 319 320 void syncResetOn(bool inc_kids); 321 void syncResetOff(bool inc_kids); 322 323 void incref() { refCount++; } 324 void decref() { refCount--; } 325 326 const ::sc_core::sc_event &resetEvent() { return _resetEvent; } 327 const ::sc_core::sc_event &terminatedEvent() { return _terminatedEvent; } 328 329 void setStackSize(size_t size) { stackSize = size; } 330 331 void finalize(); 332 333 void run(); 334 335 void addStatic(PendingSensitivity *); 336 void setDynamic(Sensitivity *); 337 338 void satisfySensitivity(Sensitivity *); 339 340 void ready(); 341 342 virtual Fiber *fiber() { return Fiber::primaryFiber(); } 343 344 static Process *newest() { return _newest; } 345 346 void lastReport(::sc_core::sc_report *report); 347 ::sc_core::sc_report *lastReport() const; 348 349 bool hasStaticSensitivities() { return !staticSensitivities.empty(); } 350 bool internal() { return _internal; } 351 bool timedOut() { return _timedOut; } 352 void timedOut(bool to) { _timedOut = to; } 353 354 bool dontInitialize() { return _dontInitialize; } 355 void dontInitialize(bool di) { _dontInitialize = di; } 356
|