113277Sgabeblack@google.com/*
213277Sgabeblack@google.com * Copyright 2018 Google, Inc.
313277Sgabeblack@google.com *
413277Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
513277Sgabeblack@google.com * modification, are permitted provided that the following conditions are
613277Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
713277Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
813277Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
913277Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1013277Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1113277Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1213277Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1313277Sgabeblack@google.com * this software without specific prior written permission.
1413277Sgabeblack@google.com *
1513277Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1613277Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1713277Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1813277Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1913277Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2013277Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2113277Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2213277Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2313277Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2413277Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2513277Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2613277Sgabeblack@google.com *
2713277Sgabeblack@google.com * Authors: Gabe Black
2813277Sgabeblack@google.com */
2913277Sgabeblack@google.com
3013277Sgabeblack@google.com#include <sstream>
3113277Sgabeblack@google.com
3213277Sgabeblack@google.com#include "systemc/core/scheduler.hh"
3313324Sgabeblack@google.com#include "systemc/ext/channel/messages.hh"
3413277Sgabeblack@google.com#include "systemc/ext/channel/sc_signal.hh"
3513277Sgabeblack@google.com#include "systemc/ext/core/sc_main.hh"
3613277Sgabeblack@google.com
3713277Sgabeblack@google.comnamespace sc_gem5
3813277Sgabeblack@google.com{
3913277Sgabeblack@google.com
4013277Sgabeblack@google.comScSignalBase::ScSignalBase(const char *name) :
4113277Sgabeblack@google.com    sc_core::sc_prim_channel(name), _changeStamp(~0ULL),
4213277Sgabeblack@google.com    _gem5WriterPort(nullptr)
4313277Sgabeblack@google.com{}
4413277Sgabeblack@google.com
4513277Sgabeblack@google.comScSignalBase::~ScSignalBase() {}
4613277Sgabeblack@google.com
4713277Sgabeblack@google.comconst sc_core::sc_event &
4813277Sgabeblack@google.comScSignalBase::defaultEvent() const
4913277Sgabeblack@google.com{
5013277Sgabeblack@google.com    return valueChangedEvent();
5113277Sgabeblack@google.com}
5213277Sgabeblack@google.com
5313277Sgabeblack@google.comconst sc_core::sc_event &
5413277Sgabeblack@google.comScSignalBase::valueChangedEvent() const
5513277Sgabeblack@google.com{
5613277Sgabeblack@google.com    return _valueChangedEvent;
5713277Sgabeblack@google.com}
5813277Sgabeblack@google.com
5913277Sgabeblack@google.combool
6013277Sgabeblack@google.comScSignalBase::event() const
6113277Sgabeblack@google.com{
6213277Sgabeblack@google.com    return _changeStamp == getChangeStamp();
6313277Sgabeblack@google.com}
6413277Sgabeblack@google.com
6513277Sgabeblack@google.comvoid
6613277Sgabeblack@google.comScSignalBase::_signalChange()
6713277Sgabeblack@google.com{
6813277Sgabeblack@google.com    _changeStamp = getChangeStamp();
6913277Sgabeblack@google.com    _valueChangedEvent.notify(sc_core::SC_ZERO_TIME);
7013277Sgabeblack@google.com}
7113277Sgabeblack@google.com
7213495Sgabeblack@google.comvoid
7313495Sgabeblack@google.comScSignalBaseBinary::_signalPosedge()
7413495Sgabeblack@google.com{
7513495Sgabeblack@google.com    _posStamp = getChangeStamp();
7613495Sgabeblack@google.com    _posedgeEvent.notify(sc_core::SC_ZERO_TIME);
7713495Sgabeblack@google.com}
7813495Sgabeblack@google.com
7913495Sgabeblack@google.comvoid
8013495Sgabeblack@google.comScSignalBaseBinary::_signalNegedge()
8113495Sgabeblack@google.com{
8213495Sgabeblack@google.com    _negStamp = getChangeStamp();
8313495Sgabeblack@google.com    _negedgeEvent.notify(sc_core::SC_ZERO_TIME);
8413495Sgabeblack@google.com}
8513495Sgabeblack@google.com
8613277Sgabeblack@google.comnamespace
8713277Sgabeblack@google.com{
8813277Sgabeblack@google.com
8913277Sgabeblack@google.comvoid
9013277Sgabeblack@google.comreportSignalError(ScSignalBase *sig, sc_core::sc_object *first,
9113277Sgabeblack@google.com        sc_core::sc_object *second, bool delta_conflict=false)
9213277Sgabeblack@google.com{
9313277Sgabeblack@google.com    std::ostringstream ss;
9413277Sgabeblack@google.com    ss << "\n signal " << "`" << sig->name() << "' (" << sig->kind() << ")";
9513278Sgabeblack@google.com    ss << "\n first driver `" << first->name() << "' (" <<
9613277Sgabeblack@google.com        first->kind() << ")";
9713277Sgabeblack@google.com    ss << "\n second driver `" << second->name() << "' (" <<
9813277Sgabeblack@google.com        second->kind() << ")";
9913277Sgabeblack@google.com    if (delta_conflict) {
10013277Sgabeblack@google.com        ss << "\n conflicting write in delta cycle " <<
10113277Sgabeblack@google.com            sc_core::sc_delta_count();
10213277Sgabeblack@google.com    }
10313324Sgabeblack@google.com    SC_REPORT_ERROR(sc_core::SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_,
10413277Sgabeblack@google.com            ss.str().c_str());
10513277Sgabeblack@google.com}
10613277Sgabeblack@google.com
10713277Sgabeblack@google.com} // anonymous namespace
10813277Sgabeblack@google.com
10913277Sgabeblack@google.comWriteChecker<sc_core::SC_ONE_WRITER>::WriteChecker(ScSignalBase *_sig) :
11013277Sgabeblack@google.com    sig(_sig), firstPort(nullptr), proc(nullptr), writeStamp(~0ULL)
11113277Sgabeblack@google.com{}
11213277Sgabeblack@google.com
11313277Sgabeblack@google.comvoid
11413277Sgabeblack@google.comWriteChecker<sc_core::SC_ONE_WRITER>::checkPort(sc_core::sc_port_base &port,
11513277Sgabeblack@google.com        std::string iface_type_name, std::string out_name)
11613277Sgabeblack@google.com{
11713277Sgabeblack@google.com    if (iface_type_name == out_name) {
11813277Sgabeblack@google.com        if (firstPort)
11913277Sgabeblack@google.com            reportSignalError(sig, firstPort, &port);
12013277Sgabeblack@google.com        firstPort = &port;
12113277Sgabeblack@google.com    }
12213277Sgabeblack@google.com}
12313277Sgabeblack@google.com
12413277Sgabeblack@google.comvoid
12513277Sgabeblack@google.comWriteChecker<sc_core::SC_ONE_WRITER>::checkWriter()
12613277Sgabeblack@google.com{
12713277Sgabeblack@google.com    Process *p = scheduler.current();
12813277Sgabeblack@google.com    if (!p)
12913277Sgabeblack@google.com        return;
13013277Sgabeblack@google.com    uint64_t stamp = getChangeStamp();
13113277Sgabeblack@google.com    if (proc && proc != p)
13213277Sgabeblack@google.com        reportSignalError(sig, proc, p);
13313277Sgabeblack@google.com    proc = p;
13413277Sgabeblack@google.com    writeStamp = stamp;
13513277Sgabeblack@google.com}
13613277Sgabeblack@google.com
13713277Sgabeblack@google.comWriteChecker<sc_core::SC_MANY_WRITERS>::WriteChecker(ScSignalBase *_sig) :
13813277Sgabeblack@google.com    sig(_sig), proc(nullptr), writeStamp(~0ULL)
13913277Sgabeblack@google.com{}
14013277Sgabeblack@google.com
14113277Sgabeblack@google.comvoid
14213277Sgabeblack@google.comWriteChecker<sc_core::SC_MANY_WRITERS>::checkPort(sc_core::sc_port_base &port,
14313277Sgabeblack@google.com        std::string iface_type_name, std::string out_name)
14413277Sgabeblack@google.com{
14513277Sgabeblack@google.com    return;
14613277Sgabeblack@google.com}
14713277Sgabeblack@google.com
14813277Sgabeblack@google.comvoid
14913277Sgabeblack@google.comWriteChecker<sc_core::SC_MANY_WRITERS>::checkWriter()
15013277Sgabeblack@google.com{
15113277Sgabeblack@google.com    Process *p = scheduler.current();
15213277Sgabeblack@google.com    if (!p)
15313277Sgabeblack@google.com        return;
15413277Sgabeblack@google.com    uint64_t stamp = getChangeStamp();
15513277Sgabeblack@google.com    if (writeStamp == stamp && proc && proc != p)
15613277Sgabeblack@google.com        reportSignalError(sig, proc, p, writeStamp == stamp);
15713277Sgabeblack@google.com    proc = p;
15813277Sgabeblack@google.com    writeStamp = stamp;
15913277Sgabeblack@google.com}
16013277Sgabeblack@google.com
16113277Sgabeblack@google.comScSignalBaseBinary::ScSignalBaseBinary(const char *_name) :
16213277Sgabeblack@google.com    ScSignalBase(_name), _posStamp(~0ULL), _negStamp(~0ULL)
16313277Sgabeblack@google.com{}
16413277Sgabeblack@google.com
16513277Sgabeblack@google.comconst sc_core::sc_event &
16613277Sgabeblack@google.comScSignalBaseBinary::posedgeEvent() const
16713277Sgabeblack@google.com{
16813277Sgabeblack@google.com    return _posedgeEvent;
16913277Sgabeblack@google.com}
17013277Sgabeblack@google.com
17113277Sgabeblack@google.comconst sc_core::sc_event &
17213277Sgabeblack@google.comScSignalBaseBinary::negedgeEvent() const
17313277Sgabeblack@google.com{
17413277Sgabeblack@google.com    return _negedgeEvent;
17513277Sgabeblack@google.com}
17613277Sgabeblack@google.com
17713277Sgabeblack@google.combool
17813277Sgabeblack@google.comScSignalBaseBinary::posedge() const
17913277Sgabeblack@google.com{
18013277Sgabeblack@google.com    return _posStamp == getChangeStamp();
18113277Sgabeblack@google.com}
18213288Sgabeblack@google.com
18313277Sgabeblack@google.combool
18413277Sgabeblack@google.comScSignalBaseBinary::negedge() const
18513277Sgabeblack@google.com{
18613277Sgabeblack@google.com    return _negStamp == getChangeStamp();
18713277Sgabeblack@google.com}
18813277Sgabeblack@google.com
18913288Sgabeblack@google.comvoid
19013288Sgabeblack@google.comScSignalBaseBinary::_signalReset(sc_gem5::Reset *r)
19113288Sgabeblack@google.com{
19213288Sgabeblack@google.com    r->update();
19313288Sgabeblack@google.com}
19413288Sgabeblack@google.com
19513288Sgabeblack@google.comvoid
19613288Sgabeblack@google.comScSignalBaseBinary::_signalReset()
19713288Sgabeblack@google.com{
19813288Sgabeblack@google.com    for (auto r: _resets)
19913288Sgabeblack@google.com        _signalReset(r);
20013288Sgabeblack@google.com}
20113288Sgabeblack@google.com
20213277Sgabeblack@google.com} // namespace sc_gem5
203