diff options
author | Gabe Black <gabeblack@google.com> | 2018-10-01 22:02:21 -0700 |
---|---|---|
committer | Gabe Black <gabeblack@google.com> | 2018-10-16 00:46:10 +0000 |
commit | 167e6c06b5d61d54e3eab48d03eb50ec316aeec3 (patch) | |
tree | 55c43062a20d7d7fd5a1dff206c856c6521617cf /src/systemc/channel | |
parent | c736ef1b2f6447be1dcd9c9e62cc072befa91443 (diff) | |
download | gem5-167e6c06b5d61d54e3eab48d03eb50ec316aeec3.tar.xz |
systemc: Implement writer policies.
This includes the nonstandard SC_NO_WRITE_CHECK #define which the
Accellera tests use and depend on.
Change-Id: I106c4c16160325725a00d5c337047251817dca32
Reviewed-on: https://gem5-review.googlesource.com/c/13203
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
Diffstat (limited to 'src/systemc/channel')
-rw-r--r-- | src/systemc/channel/SConscript | 1 | ||||
-rw-r--r-- | src/systemc/channel/sc_signal.cc | 175 |
2 files changed, 176 insertions, 0 deletions
diff --git a/src/systemc/channel/SConscript b/src/systemc/channel/SConscript index c83c233c9..fe7973770 100644 --- a/src/systemc/channel/SConscript +++ b/src/systemc/channel/SConscript @@ -35,4 +35,5 @@ if env['USE_SYSTEMC']: Source('sc_out_resolved.cc') Source('sc_mutex.cc') Source('sc_semaphore.cc') + Source('sc_signal.cc') Source('sc_signal_resolved.cc') diff --git a/src/systemc/channel/sc_signal.cc b/src/systemc/channel/sc_signal.cc new file mode 100644 index 000000000..e2c9bdf9e --- /dev/null +++ b/src/systemc/channel/sc_signal.cc @@ -0,0 +1,175 @@ +/* + * Copyright 2018 Google, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#include <sstream> + +#include "systemc/core/scheduler.hh" +#include "systemc/ext/channel/sc_signal.hh" +#include "systemc/ext/core/sc_main.hh" + +namespace sc_gem5 +{ + +ScSignalBase::ScSignalBase(const char *name) : + sc_core::sc_prim_channel(name), _changeStamp(~0ULL), + _gem5WriterPort(nullptr) +{} + +ScSignalBase::~ScSignalBase() {} + +const sc_core::sc_event & +ScSignalBase::defaultEvent() const +{ + return valueChangedEvent(); +} + +const sc_core::sc_event & +ScSignalBase::valueChangedEvent() const +{ + return _valueChangedEvent; +} + +bool +ScSignalBase::event() const +{ + return _changeStamp == getChangeStamp(); +} + +void +ScSignalBase::_signalChange() +{ + _changeStamp = getChangeStamp(); + _valueChangedEvent.notify(sc_core::SC_ZERO_TIME); +} + +namespace +{ + +void +reportSignalError(ScSignalBase *sig, sc_core::sc_object *first, + sc_core::sc_object *second, bool delta_conflict=false) +{ + std::ostringstream ss; + ss << "\n signal " << "`" << sig->name() << "' (" << sig->kind() << ")"; + ss << "\n first driver `" << first->name() << "' (" << + first->kind() << ")"; + ss << "\n second driver `" << second->name() << "' (" << + second->kind() << ")"; + if (delta_conflict) { + ss << "\n conflicting write in delta cycle " << + sc_core::sc_delta_count(); + } + SC_REPORT_ERROR( + "(E115) sc_signal<T> cannot have more than one driver", + ss.str().c_str()); +} + +} // anonymous namespace + +WriteChecker<sc_core::SC_ONE_WRITER>::WriteChecker(ScSignalBase *_sig) : + sig(_sig), firstPort(nullptr), proc(nullptr), writeStamp(~0ULL) +{} + +void +WriteChecker<sc_core::SC_ONE_WRITER>::checkPort(sc_core::sc_port_base &port, + std::string iface_type_name, std::string out_name) +{ + if (iface_type_name == out_name) { + if (firstPort) + reportSignalError(sig, firstPort, &port); + firstPort = &port; + } +} + +void +WriteChecker<sc_core::SC_ONE_WRITER>::checkWriter() +{ + Process *p = scheduler.current(); + if (!p) + return; + uint64_t stamp = getChangeStamp(); + if (proc && proc != p) + reportSignalError(sig, proc, p); + proc = p; + writeStamp = stamp; +} + +WriteChecker<sc_core::SC_MANY_WRITERS>::WriteChecker(ScSignalBase *_sig) : + sig(_sig), proc(nullptr), writeStamp(~0ULL) +{} + +void +WriteChecker<sc_core::SC_MANY_WRITERS>::checkPort(sc_core::sc_port_base &port, + std::string iface_type_name, std::string out_name) +{ + return; +} + +void +WriteChecker<sc_core::SC_MANY_WRITERS>::checkWriter() +{ + Process *p = scheduler.current(); + if (!p) + return; + uint64_t stamp = getChangeStamp(); + if (writeStamp == stamp && proc && proc != p) + reportSignalError(sig, proc, p, writeStamp == stamp); + proc = p; + writeStamp = stamp; +} + +ScSignalBaseBinary::ScSignalBaseBinary(const char *_name) : + ScSignalBase(_name), _posStamp(~0ULL), _negStamp(~0ULL) +{} + +const sc_core::sc_event & +ScSignalBaseBinary::posedgeEvent() const +{ + return _posedgeEvent; +} + +const sc_core::sc_event & +ScSignalBaseBinary::negedgeEvent() const +{ + return _negedgeEvent; +} + +bool +ScSignalBaseBinary::posedge() const +{ + return _posStamp == getChangeStamp(); +} +bool + +ScSignalBaseBinary::negedge() const +{ + return _negStamp == getChangeStamp(); +} + +} // namespace sc_gem5 |