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