sc_signal_rv.hh revision 13330:bcb4b4dea5d8
13115SN/A/*
23115SN/A * Copyright 2018 Google, Inc.
33115SN/A *
43115SN/A * Redistribution and use in source and binary forms, with or without
53115SN/A * modification, are permitted provided that the following conditions are
63115SN/A * met: redistributions of source code must retain the above copyright
73115SN/A * notice, this list of conditions and the following disclaimer;
83115SN/A * redistributions in binary form must reproduce the above copyright
93115SN/A * notice, this list of conditions and the following disclaimer in the
103115SN/A * documentation and/or other materials provided with the distribution;
113115SN/A * neither the name of the copyright holders nor the names of its
123115SN/A * contributors may be used to endorse or promote products derived from
133115SN/A * this software without specific prior written permission.
143115SN/A *
153115SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
163115SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
173115SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
183115SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
193115SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
203115SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
213115SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
223115SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
233115SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
243115SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
253115SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
263115SN/A *
273115SN/A * Authors: Gabe Black
283115SN/A */
293115SN/A
303115SN/A#ifndef __SYSTEMC_EXT_CHANNEL_SC_SIGNAL_RV_HH__
318117Sgblack@eecs.umich.edu#define __SYSTEMC_EXT_CHANNEL_SC_SIGNAL_RV_HH__
328117Sgblack@eecs.umich.edu
333115SN/A#include "../core/sc_module.hh" // for sc_gen_unique_name
348229Snate@binkert.org#include "../dt/bit/sc_logic.hh"
358229Snate@binkert.org#include "../dt/bit/sc_lv.hh"
368115SN/A#include "sc_signal.hh"
378229Snate@binkert.org
386216SN/Anamespace sc_gem5
393115SN/A{
403115SN/A
418113SN/Aclass Process;
423115SN/AProcess *getCurrentProcess();
438117Sgblack@eecs.umich.edu
443115SN/A} // namespace sc_gem5
458108SN/A
468108SN/Anamespace sc_dt
478108SN/A{
488108SN/A
498108SN/Atemplate <int W>
508108SN/Aclass sc_lv;
518108SN/A
528108SN/A};
538108SN/A
548108SN/Anamespace sc_core
558108SN/A{
568108SN/A
578108SN/Aclass sc_port_base;
588108SN/A
598108SN/Atemplate <int W>
608108SN/Aclass sc_signal_rv : public sc_signal<sc_dt::sc_lv<W>, SC_MANY_WRITERS>
618108SN/A{
628108SN/A  public:
638108SN/A    sc_signal_rv() : sc_signal<sc_dt::sc_lv<W>, SC_MANY_WRITERS>(
648108SN/A            sc_gen_unique_name("signal_rv"))
653115SN/A    {}
668108SN/A    sc_signal_rv(const char *name) :
678108SN/A            sc_signal<sc_dt::sc_lv<W>, SC_MANY_WRITERS>(name)
683115SN/A    {}
698108SN/A    virtual ~sc_signal_rv() {}
703115SN/A
718117Sgblack@eecs.umich.edu    virtual void register_port(sc_port_base &, const char *) {}
723115SN/A
738108SN/A    virtual void
748108SN/A    write(const sc_dt::sc_lv<W> &l)
758108SN/A    {
768108SN/A        ::sc_gem5::Process *p = ::sc_gem5::getCurrentProcess();
778118Sgblack@eecs.umich.edu
788108SN/A        auto it = inputs.find(p);
798108SN/A        if (it == inputs.end()) {
808108SN/A            inputs.emplace(p, l);
818117Sgblack@eecs.umich.edu            this->request_update();
828108SN/A        } else if (it->second != l) {
838108SN/A            it->second = l;
848108SN/A            this->request_update();
853115SN/A        }
863115SN/A    }
873115SN/A    sc_signal_rv<W> &
88    operator = (const sc_dt::sc_lv<W> &l)
89    {
90        write(l);
91        return *this;
92    }
93    sc_signal_rv<W> &
94    operator = (const sc_signal_rv<W> &r)
95    {
96        write(r.read());
97        return *this;
98    }
99
100    virtual const char *kind() const { return "sc_signal_rv"; }
101
102  protected:
103    virtual void
104    update()
105    {
106        using sc_dt::Log_0;
107        using sc_dt::Log_1;
108        using sc_dt::Log_Z;
109        using sc_dt::Log_X;
110        static sc_dt::sc_logic_value_t merge_table[4][4] = {
111            { Log_0, Log_X, Log_0, Log_X },
112            { Log_X, Log_1, Log_1, Log_X },
113            { Log_0, Log_1, Log_Z, Log_X },
114            { Log_X, Log_X, Log_X, Log_X }
115        };
116
117        // Resolve the inputs, and give the result to the underlying
118        // signal class.
119        for (int i = 0; i < W; i++) {
120            sc_dt::sc_logic_value_t bit = Log_Z;
121            for (auto &input: inputs)
122                bit = merge_table[bit][input.second.get_bit(i)];
123            this->m_new_val.set_bit(i, bit);
124        }
125
126        // Ask the signal to update it's value.
127        sc_signal<sc_dt::sc_lv<W>, SC_MANY_WRITERS>::update();
128    }
129
130  private:
131    // Disabled
132    sc_signal_rv(const sc_signal_rv<W> &) :
133            sc_signal<sc_dt::sc_lv<W>, SC_MANY_WRITERS>()
134    {}
135
136    std::map<::sc_gem5::Process *, sc_dt::sc_lv<W> > inputs;
137};
138
139} // namespace sc_core
140
141#endif  //__SYSTEMC_EXT_CHANNEL_SC_SIGNAL_RV_HH__
142