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#include "systemc/core/sensitivity.hh" 31 32#include "systemc/core/event.hh" 33#include "systemc/core/port.hh" 34#include "systemc/core/process.hh" 35#include "systemc/core/scheduler.hh" 36#include "systemc/ext/channel/sc_in.hh" 37#include "systemc/ext/channel/sc_inout.hh" 38#include "systemc/ext/channel/sc_out.hh" 39#include "systemc/ext/core/messages.hh" 40#include "systemc/ext/core/sc_export.hh" 41#include "systemc/ext/core/sc_interface.hh" 42#include "systemc/ext/core/sc_port.hh" 43 44namespace sc_gem5 45{ 46 47/* 48 * Common sensitivity interface. 49 */ 50 51void 52Sensitivity::satisfy() 53{ 54 process->satisfySensitivity(this); 55} 56 57bool 58Sensitivity::notifyWork(Event *e) 59{ 60 satisfy(); 61 return true; 62} 63 64bool 65Sensitivity::notify(Event *e) 66{ 67 if (scheduler.current() == process) { 68 static bool warned = false; 69 if (!warned) { 70 SC_REPORT_WARNING(sc_core::SC_ID_IMMEDIATE_SELF_NOTIFICATION_, 71 process->name()); 72 warned = true; 73 } 74 return false; 75 } 76 77 if (process->disabled()) 78 return false; 79 80 return notifyWork(e); 81} 82 83bool 84Sensitivity::ofMethod() 85{ 86 return process->procKind() == sc_core::SC_METHOD_PROC_; 87} 88 89 90/* 91 * Dynamic vs. static sensitivity. 92 */ 93 94void 95DynamicSensitivity::addToEvent(const ::sc_core::sc_event *e) 96{ 97 Event::getFromScEvent(e)->addSensitivity(this); 98} 99 100void 101DynamicSensitivity::delFromEvent(const ::sc_core::sc_event *e) 102{ 103 Event::getFromScEvent(e)->delSensitivity(this); 104} 105 106void 107StaticSensitivity::addToEvent(const ::sc_core::sc_event *e) 108{ 109 Event::getFromScEvent(e)->addSensitivity(this); 110} 111 112void 113StaticSensitivity::delFromEvent(const ::sc_core::sc_event *e) 114{ 115 Event::getFromScEvent(e)->delSensitivity(this); 116} 117 118 119/* 120 * Static sensitivities. 121 */ 122 123void 124newStaticSensitivityEvent(Process *p, const sc_core::sc_event *e) 125{ 126 auto s = new StaticSensitivityEvent(p, e); 127 s->addToEvent(s->event); 128 p->addStatic(s); 129} 130 131void 132newStaticSensitivityInterface(Process *p, const sc_core::sc_interface *i) 133{ 134 auto s = new StaticSensitivityInterface(p, i); 135 s->addToEvent(s->event); 136 p->addStatic(s); 137} 138 139void 140newStaticSensitivityPort(Process *p, const sc_core::sc_port_base *pb) 141{ 142 auto s = new StaticSensitivityPort(p); 143 Port *port = Port::fromPort(pb); 144 port->sensitive(s); 145 p->addStatic(s); 146} 147 148void 149newStaticSensitivityExport(Process *p, const sc_core::sc_export_base *exp) 150{ 151 auto s = new StaticSensitivityExport(p, exp); 152 s->addToEvent(s->event); 153 p->addStatic(s); 154} 155 156void 157newStaticSensitivityFinder(Process *p, const sc_core::sc_event_finder *f) 158{ 159 auto s = new StaticSensitivityFinder(p, f); 160 Port *port = Port::fromPort(f->port()); 161 port->sensitive(s); 162 p->addStatic(s); 163} 164 165 166StaticSensitivityInterface::StaticSensitivityInterface( 167 Process *p, const sc_core::sc_interface *i) : 168 Sensitivity(p), StaticSensitivity(p), 169 SensitivityEvent(p, &i->default_event()) 170{} 171 172StaticSensitivityExport::StaticSensitivityExport( 173 Process *p, const sc_core::sc_export_base *exp) : 174 Sensitivity(p), StaticSensitivity(p), 175 SensitivityEvent(p, &exp->get_interface()->default_event()) 176{} 177 178const ::sc_core::sc_event & 179StaticSensitivityFinder::find(::sc_core::sc_interface *i) 180{ 181 return finder->find_event(i); 182} 183 184 185/* 186 * Dynamic sensitivities. 187 */ 188 189void 190newDynamicSensitivityEvent(Process *p, const sc_core::sc_event *e) 191{ 192 auto s = new DynamicSensitivityEvent(p, e); 193 s->addToEvent(s->event); 194 p->setDynamic(s); 195} 196 197void 198newDynamicSensitivityEventOrList( 199 Process *p, const sc_core::sc_event_or_list *eol) 200{ 201 auto s = new DynamicSensitivityEventOrList(p, eol); 202 for (auto event: s->events) 203 s->addToEvent(event); 204 p->setDynamic(s); 205} 206 207void newDynamicSensitivityEventAndList( 208 Process *p, const sc_core::sc_event_and_list *eal) 209{ 210 auto s = new DynamicSensitivityEventAndList(p, eal); 211 for (auto event: s->events) 212 s->addToEvent(event); 213 p->setDynamic(s); 214} 215 216 217DynamicSensitivityEventOrList::DynamicSensitivityEventOrList( 218 Process *p, const sc_core::sc_event_or_list *eol) : 219 Sensitivity(p), DynamicSensitivity(p), SensitivityEvents(p, eol->events) 220{} 221 222bool 223DynamicSensitivityEventOrList::notifyWork(Event *e) 224{ 225 events.erase(e->sc_event()); 226 227 // All the other events need this deleted from their lists since this 228 // sensitivity has been satisfied without them triggering. 229 for (auto le: events) 230 delFromEvent(le); 231 232 satisfy(); 233 return true; 234} 235 236DynamicSensitivityEventAndList::DynamicSensitivityEventAndList( 237 Process *p, const sc_core::sc_event_and_list *eal) : 238 Sensitivity(p), DynamicSensitivity(p), SensitivityEvents(p, eal->events) 239{} 240 241bool 242DynamicSensitivityEventAndList::notifyWork(Event *e) 243{ 244 events.erase(e->sc_event()); 245 246 // This sensitivity is satisfied if all events have triggered. 247 if (events.empty()) 248 satisfy(); 249 250 return true; 251} 252 253} // namespace sc_gem5 254