1/*****************************************************************************
2
3  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4  more contributor license agreements.  See the NOTICE file distributed
5  with this work for additional information regarding copyright ownership.
6  Accellera licenses this file to you under the Apache License, Version 2.0
7  (the "License"); you may not use this file except in compliance with the
8  License.  You may obtain a copy of the License at
9
10    http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15  implied.  See the License for the specific language governing
16  permissions and limitations under the License.
17
18 *****************************************************************************/
19
20/*****************************************************************************
21
22  sc_signal_rv.h -- The resolved vector signal class.
23
24  Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
25
26  CHANGE LOG IS AT THE END OF THE FILE
27 *****************************************************************************/
28
29#ifndef SC_SIGNAL_RV_H
30#define SC_SIGNAL_RV_H
31
32#include "sysc/communication/sc_signal.h"
33#include "sysc/datatypes/bit/sc_lv.h"
34
35namespace sc_core {
36
37class sc_process_b;
38
39
40// ----------------------------------------------------------------------------
41//  CLASS sc_lv_resolve<W>
42//
43//  Resolution function for sc_dt::sc_lv<W>.
44// ----------------------------------------------------------------------------
45
46extern const sc_dt::sc_logic_value_t sc_logic_resolution_tbl[4][4];
47
48
49template <int W>
50class sc_lv_resolve
51{
52public:
53
54    // resolves sc_dt::sc_lv<W> values and returns the resolved value
55    static void resolve(sc_dt::sc_lv<W>&, const std::vector<sc_dt::sc_lv<W>*>&);
56};
57
58
59// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
60
61// resolves sc_dt::sc_lv<W> values and returns the resolved value
62
63template <int W>
64inline
65void
66sc_lv_resolve<W>::resolve( sc_dt::sc_lv<W>& result_,
67			   const std::vector<sc_dt::sc_lv<W>*>& values_ )
68{
69    int sz = values_.size();
70
71    assert( sz != 0 );
72
73    if( sz == 1 ) {
74	result_ = *values_[0];
75	return;
76    }
77
78    for( int j = result_.length() - 1; j >= 0; -- j ) {
79	sc_dt::sc_logic_value_t res = (*values_[0])[j].value();
80	for( int i = sz - 1; i > 0 && res != 3; -- i ) {
81	    res = sc_logic_resolution_tbl[res][(*values_[i])[j].value()];
82	}
83	result_[j] = res;
84    }
85}
86
87
88// ----------------------------------------------------------------------------
89//  CLASS : sc_signal_rv<W>
90//
91//  The resolved vector signal class.
92// ----------------------------------------------------------------------------
93
94template <int W>
95class sc_signal_rv
96: public sc_signal<sc_dt::sc_lv<W>, SC_MANY_WRITERS>
97{
98public:
99
100    // typedefs
101
102    typedef sc_signal_rv<W>                             this_type;
103    typedef sc_signal<sc_dt::sc_lv<W>, SC_MANY_WRITERS> base_type;
104    typedef sc_dt::sc_lv<W>                             data_type;
105
106public:
107
108    // constructors
109
110    sc_signal_rv()
111        : base_type( sc_gen_unique_name( "signal_rv" ) )
112	{}
113
114    explicit sc_signal_rv( const char* name_ )
115        : base_type( name_ )
116	{}
117
118
119    // destructor
120    virtual ~sc_signal_rv();
121
122
123    // interface methods
124
125    virtual void register_port( sc_port_base&, const char* )
126	{}
127
128
129    // write the new value
130    virtual void write( const data_type& );
131
132
133    // other methods
134
135    this_type& operator = ( const data_type& a )
136        { write( a ); return *this; }
137
138    this_type& operator = ( const this_type& a )
139        { write( a.read() ); return *this; }
140
141    virtual const char* kind() const
142        { return "sc_signal_rv"; }
143
144protected:
145
146    virtual void update();
147
148protected:
149
150    std::vector<sc_process_b*> m_proc_vec; // processes writing this signal
151    std::vector<data_type*>       m_val_vec;  // new values written this signal
152
153private:
154
155    // disabled
156    sc_signal_rv( const this_type& );
157};
158
159
160// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
161
162
163// destructor
164
165template <int W>
166inline
167sc_signal_rv<W>::~sc_signal_rv()
168{
169    for( int i = m_val_vec.size() - 1; i >= 0; -- i ) {
170	delete m_val_vec[i];
171    }
172}
173
174
175// write the new value
176
177template <int W>
178inline
179void
180sc_signal_rv<W>::write( const data_type& value_ )
181{
182    sc_process_b* cur_proc = sc_get_current_process_b();
183
184    bool value_changed = false;
185    bool found = false;
186
187    for( int i = m_proc_vec.size() - 1; i >= 0; -- i ) {
188	if( cur_proc == m_proc_vec[i] ) {
189	    if( value_ != *m_val_vec[i] ) {
190		*m_val_vec[i] = value_;
191		value_changed = true;
192	    }
193	    found = true;
194	    break;
195	}
196    }
197
198    if( ! found ) {
199	m_proc_vec.push_back( cur_proc );
200	m_val_vec.push_back( new data_type( value_ ) );
201	value_changed = true;
202    }
203
204    if( value_changed ) {
205	this->request_update();
206    }
207}
208
209
210template <int W>
211inline
212void
213sc_signal_rv<W>::update()
214{
215    sc_lv_resolve<W>::resolve( this->m_new_val, m_val_vec );
216    base_type::update();
217}
218
219} // namespace sc_core
220
221//$Log: sc_signal_rv.h,v $
222//Revision 1.4  2011/08/26 20:45:44  acg
223// Andy Goodrich: moved the modification log to the end of the file to
224// eliminate source line number skew when check-ins are done.
225//
226//Revision 1.3  2011/04/19 02:36:26  acg
227// Philipp A. Hartmann: new aysnc_update and mutex support.
228//
229//Revision 1.2  2011/02/18 20:23:45  acg
230// Andy Goodrich: Copyright update.
231//
232//Revision 1.1.1.1  2006/12/15 20:20:04  acg
233//SystemC 2.3
234//
235//Revision 1.3  2006/03/21 00:00:27  acg
236//  Andy Goodrich: changed name of sc_get_current_process_base() to be
237//  sc_get_current_process_b() since its returning an sc_process_b instance.
238//
239//Revision 1.2  2006/01/03 23:18:26  acg
240//Changed copyright to include 2006.
241//
242//Revision 1.1.1.1  2005/12/19 23:16:43  acg
243//First check in of SystemC 2.1 into its own archive.
244//
245//Revision 1.10  2005/09/15 23:01:52  acg
246//Added std:: prefix to appropriate methods and types to get around
247//issues with the Edison Front End.
248//
249//Revision 1.9  2005/06/10 22:43:55  acg
250//Added CVS change log annotation.
251//
252
253#endif
254
255// Taf!
256