113245Sgabeblack@google.com/*
213245Sgabeblack@google.com * Copyright 2018 Google, Inc.
313245Sgabeblack@google.com *
413245Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
513245Sgabeblack@google.com * modification, are permitted provided that the following conditions are
613245Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
713245Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
813245Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
913245Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1013245Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1113245Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1213245Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1313245Sgabeblack@google.com * this software without specific prior written permission.
1413245Sgabeblack@google.com *
1513245Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1613245Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1713245Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1813245Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1913245Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2013245Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2113245Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2213245Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2313245Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2413245Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2513245Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2613245Sgabeblack@google.com *
2713245Sgabeblack@google.com * Authors: Gabe Black
2813245Sgabeblack@google.com */
2913245Sgabeblack@google.com
3013245Sgabeblack@google.com#ifndef __SYSTEMC_UTILS_TRACEFILE_HH__
3113245Sgabeblack@google.com#define __SYSTEMC_UTILS_TRACEFILE_HH__
3213245Sgabeblack@google.com
3313245Sgabeblack@google.com#include <iostream>
3413245Sgabeblack@google.com#include <string>
3513245Sgabeblack@google.com#include <vector>
3613245Sgabeblack@google.com
3713245Sgabeblack@google.com#include "systemc/core/event.hh"
3813245Sgabeblack@google.com#include "systemc/ext/channel/sc_signal_in_if.hh"
3913245Sgabeblack@google.com#include "systemc/ext/core/sc_event.hh"
4013245Sgabeblack@google.com#include "systemc/ext/dt/fx/sc_fxnum.hh"
4113245Sgabeblack@google.com#include "systemc/ext/utils/sc_trace_file.hh"
4213245Sgabeblack@google.com
4313245Sgabeblack@google.comclass OutputStream;
4413245Sgabeblack@google.com
4513245Sgabeblack@google.comnamespace sc_gem5
4613245Sgabeblack@google.com{
4713245Sgabeblack@google.com
4813245Sgabeblack@google.comclass TraceValBase
4913245Sgabeblack@google.com{
5013245Sgabeblack@google.com  protected:
5113245Sgabeblack@google.com    int _width;
5213245Sgabeblack@google.com
5313245Sgabeblack@google.com  public:
5413245Sgabeblack@google.com    TraceValBase(int _width) : _width(_width) {}
5513245Sgabeblack@google.com    virtual ~TraceValBase() {}
5613245Sgabeblack@google.com
5713245Sgabeblack@google.com    int width() { return _width; }
5813245Sgabeblack@google.com
5913245Sgabeblack@google.com    virtual void finalize() {};
6013245Sgabeblack@google.com    virtual bool check() = 0;
6113245Sgabeblack@google.com};
6213245Sgabeblack@google.com
6313245Sgabeblack@google.comtemplate <typename T, typename Base=TraceValBase>
6413245Sgabeblack@google.comclass TraceVal : public Base
6513245Sgabeblack@google.com{
6613245Sgabeblack@google.com  private:
6713245Sgabeblack@google.com    const T *t;
6813245Sgabeblack@google.com    T oldVal;
6913245Sgabeblack@google.com
7013245Sgabeblack@google.com  public:
7113245Sgabeblack@google.com    TraceVal(const T *_t, int _width) : Base(_width), t(_t), oldVal(*t)
7213245Sgabeblack@google.com    {}
7313245Sgabeblack@google.com    ~TraceVal() {}
7413245Sgabeblack@google.com
7513245Sgabeblack@google.com    void finalize() override { oldVal = *t; }
7613245Sgabeblack@google.com    const T &value() { return oldVal; }
7713245Sgabeblack@google.com
7813245Sgabeblack@google.com    bool
7913245Sgabeblack@google.com    check() override
8013245Sgabeblack@google.com    {
8113245Sgabeblack@google.com        bool changed = (*t != oldVal);
8213245Sgabeblack@google.com        oldVal = *t;
8313245Sgabeblack@google.com        return changed;
8413245Sgabeblack@google.com    }
8513245Sgabeblack@google.com};
8613245Sgabeblack@google.com
8713245Sgabeblack@google.comtemplate <typename T, typename Base>
8813245Sgabeblack@google.comclass TraceVal<::sc_core::sc_signal_in_if<T>, Base> : public Base
8913245Sgabeblack@google.com{
9013245Sgabeblack@google.com  private:
9113245Sgabeblack@google.com    const ::sc_core::sc_signal_in_if<T> *iface;
9213245Sgabeblack@google.com    T oldVal;
9313245Sgabeblack@google.com
9413245Sgabeblack@google.com  public:
9513245Sgabeblack@google.com    TraceVal(const ::sc_core::sc_signal_in_if<T> *_iface, int _width) :
9613245Sgabeblack@google.com        Base(_width), iface(_iface), oldVal(iface->read())
9713245Sgabeblack@google.com    {}
9813245Sgabeblack@google.com    ~TraceVal() {}
9913245Sgabeblack@google.com
10013245Sgabeblack@google.com    void finalize() override { oldVal = iface->read(); }
10113245Sgabeblack@google.com    const T &value() { return oldVal; }
10213245Sgabeblack@google.com
10313245Sgabeblack@google.com    bool
10413245Sgabeblack@google.com    check() override
10513245Sgabeblack@google.com    {
10613245Sgabeblack@google.com        T newVal = iface->read();
10713245Sgabeblack@google.com        bool changed = (newVal != oldVal);
10813245Sgabeblack@google.com        oldVal = newVal;
10913245Sgabeblack@google.com        return changed;
11013245Sgabeblack@google.com    }
11113245Sgabeblack@google.com};
11213245Sgabeblack@google.com
11313245Sgabeblack@google.comtemplate <typename Base>
11413245Sgabeblack@google.comclass TraceVal<::sc_core::sc_event, Base> : public Base
11513245Sgabeblack@google.com{
11613245Sgabeblack@google.com  private:
11713245Sgabeblack@google.com    bool triggered;
11813245Sgabeblack@google.com    uint64_t oldStamp;
11913245Sgabeblack@google.com    const Event *event;
12013245Sgabeblack@google.com
12113245Sgabeblack@google.com  public:
12213245Sgabeblack@google.com    TraceVal(const ::sc_core::sc_event *_event, int _width) :
12313245Sgabeblack@google.com        Base(_width), triggered(false), oldStamp(0),
12413245Sgabeblack@google.com        event(Event::getFromScEvent(_event))
12513245Sgabeblack@google.com    {}
12613245Sgabeblack@google.com    ~TraceVal() {}
12713245Sgabeblack@google.com
12813245Sgabeblack@google.com    bool value() { return triggered; }
12913245Sgabeblack@google.com    void finalize() override { oldStamp = event->triggeredStamp(); }
13013245Sgabeblack@google.com
13113245Sgabeblack@google.com    bool
13213245Sgabeblack@google.com    check() override
13313245Sgabeblack@google.com    {
13413245Sgabeblack@google.com        uint64_t newStamp = event->triggeredStamp();
13513245Sgabeblack@google.com        triggered = (oldStamp != newStamp);
13613245Sgabeblack@google.com        oldStamp = newStamp;
13713245Sgabeblack@google.com        return triggered;
13813245Sgabeblack@google.com    }
13913245Sgabeblack@google.com};
14013245Sgabeblack@google.com
14113245Sgabeblack@google.comtemplate <typename T, typename Base>
14213245Sgabeblack@google.comclass TraceValFxnumBase : public Base
14313245Sgabeblack@google.com{
14413245Sgabeblack@google.com  private:
14513245Sgabeblack@google.com    const T *t;
14613245Sgabeblack@google.com    T oldVal;
14713245Sgabeblack@google.com
14813245Sgabeblack@google.com  public:
14913245Sgabeblack@google.com    TraceValFxnumBase(const T *_t, int _width) :
15013245Sgabeblack@google.com        Base(_width), t(_t),
15113245Sgabeblack@google.com        oldVal(_t->m_params.type_params(), _t->m_params.enc(),
15213245Sgabeblack@google.com                _t->m_params.cast_switch(), 0)
15313245Sgabeblack@google.com    {}
15413245Sgabeblack@google.com    ~TraceValFxnumBase() {}
15513245Sgabeblack@google.com
15613245Sgabeblack@google.com    void
15713245Sgabeblack@google.com    finalize() override
15813245Sgabeblack@google.com    {
15913245Sgabeblack@google.com        oldVal = *t;
16013245Sgabeblack@google.com        this->_width = t->wl();
16113245Sgabeblack@google.com    }
16213245Sgabeblack@google.com
16313245Sgabeblack@google.com    const T &value() { return oldVal; }
16413245Sgabeblack@google.com
16513245Sgabeblack@google.com    bool
16613245Sgabeblack@google.com    check() override
16713245Sgabeblack@google.com    {
16813245Sgabeblack@google.com        bool changed = (*t != oldVal);
16913245Sgabeblack@google.com        oldVal = *t;
17013245Sgabeblack@google.com        return changed;
17113245Sgabeblack@google.com    }
17213245Sgabeblack@google.com};
17313245Sgabeblack@google.com
17413245Sgabeblack@google.comtemplate <typename Base>
17513245Sgabeblack@google.comclass TraceVal<::sc_dt::sc_fxnum, Base> :
17613245Sgabeblack@google.com    public TraceValFxnumBase<::sc_dt::sc_fxnum, Base>
17713245Sgabeblack@google.com{
17813245Sgabeblack@google.com  public:
17913245Sgabeblack@google.com    using TraceValFxnumBase<::sc_dt::sc_fxnum, Base>::TraceValFxnumBase;
18013245Sgabeblack@google.com    ~TraceVal() {}
18113245Sgabeblack@google.com};
18213245Sgabeblack@google.com
18313245Sgabeblack@google.comtemplate <typename Base>
18413245Sgabeblack@google.comclass TraceVal<::sc_dt::sc_fxnum_fast, Base> :
18513245Sgabeblack@google.com    public TraceValFxnumBase<::sc_dt::sc_fxnum_fast, Base>
18613245Sgabeblack@google.com{
18713245Sgabeblack@google.com  public:
18813245Sgabeblack@google.com    using TraceValFxnumBase<::sc_dt::sc_fxnum_fast, Base>::TraceValFxnumBase;
18913245Sgabeblack@google.com    ~TraceVal() {}
19013245Sgabeblack@google.com};
19113245Sgabeblack@google.com
19213245Sgabeblack@google.comclass TraceFile : public sc_core::sc_trace_file
19313245Sgabeblack@google.com{
19413245Sgabeblack@google.com  protected:
19513245Sgabeblack@google.com    OutputStream *_os;
19613245Sgabeblack@google.com    uint64_t timeUnitTicks;
19713245Sgabeblack@google.com    double timeUnitValue;
19813245Sgabeblack@google.com    ::sc_core::sc_time_unit timeUnitUnit;
19913245Sgabeblack@google.com
20013245Sgabeblack@google.com    bool _traceDeltas;
20113245Sgabeblack@google.com
20213245Sgabeblack@google.com    TraceFile(const std::string &name);
20313245Sgabeblack@google.com
20413245Sgabeblack@google.com    std::ostream &stream();
20513245Sgabeblack@google.com
20613245Sgabeblack@google.com  public:
20713245Sgabeblack@google.com    ~TraceFile();
20813245Sgabeblack@google.com
20913245Sgabeblack@google.com    void traceDeltas(bool on) { _traceDeltas = on; }
21013245Sgabeblack@google.com
21113245Sgabeblack@google.com    void set_time_unit(double, ::sc_core::sc_time_unit) override;
21213245Sgabeblack@google.com    void finalizeTime();
21313245Sgabeblack@google.com
21413245Sgabeblack@google.com    virtual void trace(bool delta) = 0;
21513245Sgabeblack@google.com
21613245Sgabeblack@google.com    virtual void addTraceVal(const bool *v, const std::string &name) = 0;
21713245Sgabeblack@google.com    virtual void addTraceVal(const float *v, const std::string &name) = 0;
21813245Sgabeblack@google.com    virtual void addTraceVal(const double *v, const std::string &name) = 0;
21913245Sgabeblack@google.com
22013245Sgabeblack@google.com    virtual void addTraceVal(const sc_dt::sc_logic *v,
22113245Sgabeblack@google.com                             const std::string &name) = 0;
22213245Sgabeblack@google.com    virtual void addTraceVal(const sc_dt::sc_int_base *v,
22313245Sgabeblack@google.com                             const std::string &name) = 0;
22413245Sgabeblack@google.com    virtual void addTraceVal(const sc_dt::sc_uint_base *v,
22513245Sgabeblack@google.com                             const std::string &name) = 0;
22613245Sgabeblack@google.com    virtual void addTraceVal(const sc_dt::sc_signed *v,
22713245Sgabeblack@google.com                             const std::string &name) = 0;
22813245Sgabeblack@google.com    virtual void addTraceVal(const sc_dt::sc_unsigned *v,
22913245Sgabeblack@google.com                             const std::string &name) = 0;
23013245Sgabeblack@google.com    virtual void addTraceVal(const sc_dt::sc_bv_base *v,
23113245Sgabeblack@google.com                             const std::string &name) = 0;
23213245Sgabeblack@google.com    virtual void addTraceVal(const sc_dt::sc_lv_base *v,
23313245Sgabeblack@google.com                             const std::string &name) = 0;
23413245Sgabeblack@google.com    virtual void addTraceVal(const sc_dt::sc_fxval *v,
23513245Sgabeblack@google.com                             const std::string &name) = 0;
23613245Sgabeblack@google.com    virtual void addTraceVal(const sc_dt::sc_fxval_fast *v,
23713245Sgabeblack@google.com                             const std::string &name) = 0;
23813245Sgabeblack@google.com    virtual void addTraceVal(const sc_dt::sc_fxnum *v,
23913245Sgabeblack@google.com                             const std::string &name) = 0;
24013245Sgabeblack@google.com    virtual void addTraceVal(const sc_dt::sc_fxnum_fast *v,
24113245Sgabeblack@google.com                             const std::string &name) = 0;
24213245Sgabeblack@google.com
24313245Sgabeblack@google.com    virtual void addTraceVal(const sc_core::sc_event *v,
24413245Sgabeblack@google.com                             const std::string &name) = 0;
24513245Sgabeblack@google.com    virtual void addTraceVal(const sc_core::sc_time *v,
24613245Sgabeblack@google.com                             const std::string &name) = 0;
24713245Sgabeblack@google.com
24813245Sgabeblack@google.com    virtual void addTraceVal(const unsigned char *v,
24913245Sgabeblack@google.com                             const std::string &name, int width) = 0;
25013245Sgabeblack@google.com    virtual void addTraceVal(const char *v, const std::string &name,
25113245Sgabeblack@google.com                             int width) = 0;
25213245Sgabeblack@google.com    virtual void addTraceVal(const unsigned short *v,
25313245Sgabeblack@google.com                             const std::string &name, int width) = 0;
25413245Sgabeblack@google.com    virtual void addTraceVal(const short *v, const std::string &name,
25513245Sgabeblack@google.com                             int width) = 0;
25613245Sgabeblack@google.com    virtual void addTraceVal(const unsigned int *v,
25713245Sgabeblack@google.com                             const std::string &name, int width) = 0;
25813245Sgabeblack@google.com    virtual void addTraceVal(const int *v, const std::string &name,
25913245Sgabeblack@google.com                             int width) = 0;
26013245Sgabeblack@google.com    virtual void addTraceVal(const unsigned long *v,
26113245Sgabeblack@google.com                             const std::string &name, int width) = 0;
26213245Sgabeblack@google.com    virtual void addTraceVal(const long *v, const std::string &name,
26313245Sgabeblack@google.com                             int width) = 0;
26413245Sgabeblack@google.com
26513245Sgabeblack@google.com    virtual void addTraceVal(const sc_dt::int64 *v,
26613245Sgabeblack@google.com                             const std::string &name, int width) = 0;
26713245Sgabeblack@google.com    virtual void addTraceVal(const sc_dt::uint64 *v,
26813245Sgabeblack@google.com                             const std::string &name, int width) = 0;
26913245Sgabeblack@google.com
27013245Sgabeblack@google.com    virtual void addTraceVal(const unsigned int *,
27113245Sgabeblack@google.com                             const std::string &name,
27213245Sgabeblack@google.com                             const char **literals) = 0;
27313245Sgabeblack@google.com
27413245Sgabeblack@google.com    virtual void writeComment(const std::string &comment) = 0;
27513245Sgabeblack@google.com};
27613245Sgabeblack@google.com
27713245Sgabeblack@google.com} // namespace sc_gem5
27813245Sgabeblack@google.com
27913245Sgabeblack@google.com#endif // __SYSTEMC_UTILS_TRACEFILE_HH__
280