00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00037 #ifndef RC_SIGNAL_H_
00038 #define RC_SIGNAL_H_
00039
00040 #include "ReChannel/components/rc_prim_channel.h"
00041 #include "ReChannel/components/rc_report_ids.h"
00042 #include "ReChannel/core/rc_reset_channel_if.h"
00043 #include "ReChannel/communication/rc_fallback_interface.h"
00044
00045 namespace ReChannel {
00046
00047 namespace internals {
00048 namespace signals {
00049
00050 void report_binding_error(
00051 const sc_object& target, const sc_object& port1,
00052 const sc_object& port2);
00053
00054 void report_driver_conflict(
00055 const sc_object& target, const sc_object& driver1,
00056 const sc_object& driver2);
00057
00058 }
00059 }
00060
00064 template<class T>
00065 class rc_signal_b
00066 : public sc_signal_inout_if<T>,
00067 public rc_prim_channel
00068 {
00069 protected:
00070
00071
00072
00073 explicit rc_signal_b(const char* name_)
00074 : rc_prim_channel(name_),
00075 m_current_value(rc_undefined_value<T>()),
00076 m_delta(~0), m_new_value(m_current_value),
00077 m_reset_value(m_current_value),
00078 m_notify_value_changed_event(false),
00079 m_notify_posedge_event(false), m_notify_negedge_event(false),
00080 m_output_port(0), m_driver_proc(0)
00081 { }
00082
00083 public:
00084
00085
00086
00087 virtual const char* kind() const
00088 { return "rc_signal"; }
00089
00090 virtual void register_port(sc_port_base& port_, const char* if_name_);
00091
00092 virtual const sc_event& default_event() const
00093 { m_notify_value_changed_event = true; return m_value_changed_event; }
00094
00095 virtual const sc_event& value_changed_event() const
00096 { m_notify_value_changed_event = true; return m_value_changed_event; }
00097
00098 virtual const T& read() const
00099 { return m_current_value; }
00100
00101 virtual const T& get_data_ref() const
00102 { return m_current_value; }
00103
00104 virtual bool event() const
00105 { return (m_delta == sc_delta_count()); }
00106
00107 virtual void write(const T& value);
00108
00109 virtual void print(std::ostream& os=std::cout) const
00110 { os << m_current_value; }
00111
00112 virtual void dump(std::ostream& os=std::cout) const;
00113
00114 protected:
00115
00116 virtual void update();
00117
00118 RC_ON_INIT_RESETTABLE()
00119 {
00120
00121 m_reset_value = m_new_value;
00122 }
00123
00124 RC_ON_RESET()
00125 {
00126
00127 m_delta = ~0;
00128 m_new_value = m_reset_value;
00129 m_current_value = m_reset_value;
00130 if (m_notify_value_changed_event) {
00131 m_value_changed_event.cancel();
00132 }
00133 }
00134
00135 protected:
00136 T m_current_value;
00137 sc_dt::uint64 m_delta;
00138 T m_new_value;
00139 T m_reset_value;
00140
00141 mutable bool m_notify_value_changed_event : 1;
00142 mutable bool m_notify_posedge_event : 1;
00143 mutable bool m_notify_negedge_event : 1;
00144 sc_event m_value_changed_event;
00145
00146 sc_port_base* m_output_port;
00147 sc_object* m_driver_proc;
00148
00149 private:
00150
00151 rc_signal_b(const rc_signal_b<T>& other);
00152 rc_signal_b<T>& operator=(const rc_signal_b<T>& value);
00153 };
00154
00158 template<class T>
00159 class rc_signal
00160 : public rc_signal_b<T>
00161 {
00162 private:
00163 typedef rc_signal<T> this_type;
00164 typedef rc_signal_b<T> base_type;
00165
00166 public:
00167 explicit rc_signal(
00168 const sc_module_name& name_=sc_gen_unique_name("signal"))
00169 : base_type(name_)
00170 { }
00171
00172 operator const T&() const
00173 { return this->read(); }
00174
00175 this_type& operator=(const T& value)
00176 { this->write(value); return *this; }
00177
00178 this_type& operator=(const this_type& signal_)
00179 { this->write(signal_.read()); return *this; }
00180 };
00181
00185 template<>
00186 class rc_signal<bool>
00187 : public rc_signal_b<bool>,
00188 virtual public rc_reset_channel_if
00189 {
00190 private:
00191 typedef rc_signal<bool> this_type;
00192 typedef rc_signal_b<bool> base_type;
00193
00194 typedef std::set<rc_process_control*> pctrl_set;
00195
00196 public:
00197 explicit rc_signal(
00198 const sc_module_name& name_=sc_gen_unique_name("signal"))
00199 : base_type(name_), p_reset_signal(NULL)
00200 { }
00201
00202
00203
00204 virtual const sc_event& posedge_event() const
00205 { m_notify_posedge_event = true; return m_posedge_event; }
00206
00207 virtual const sc_event& negedge_event() const
00208 { m_notify_negedge_event = true; return m_negedge_event; }
00209
00210 virtual bool posedge() const
00211 { return (this->event() && m_current_value); }
00212
00213 virtual bool negedge() const
00214 { return (this->event() && !m_current_value); }
00215
00216 #if !defined(RC_USE_NON_OSCI_KERNEL)
00217
00218 virtual sc_reset* is_reset() const
00219 {
00220 return _rc_get_reset_signal().is_reset();
00221 }
00222 #endif // !defined(RC_USE_NON_OSCI_KERNEL)
00223
00224
00225
00226 operator const bool&() const
00227 { return this->read(); }
00228
00229 this_type& operator=(const bool& value)
00230 { this->write(value); return *this; }
00231
00232 this_type& operator=(const this_type& signal_)
00233 { this->write(signal_.read()); return *this; }
00234
00235 protected:
00236
00237 virtual void register_process_control(
00238 rc_process_control& pctrl, bool active_level) const;
00239
00240 virtual void unregister_process_control(
00241 rc_process_control& pctrl) const;
00242
00243 virtual bool get_current_level() const;
00244
00245 virtual const sc_signal<bool>* get_underlying_reset_signal() const;
00246
00247 virtual void update();
00248
00249 RC_ON_RESET()
00250 {
00251 base_type::rc_on_reset();
00252
00253
00254 if (m_notify_negedge_event) {
00255 m_negedge_event.cancel();
00256 }
00257 if (m_notify_posedge_event) {
00258 m_posedge_event.cancel();
00259 }
00260 }
00261
00262 private:
00263 sc_signal<bool>& _rc_get_reset_signal() const;
00264
00265 void _rc_reset_updater_proc();
00266
00267 protected:
00268 sc_event m_posedge_event;
00269 sc_event m_negedge_event;
00270
00271 private:
00272 mutable pctrl_set p_pctrl_set[2];
00273 mutable sc_signal<bool>* p_reset_signal;
00274 };
00275
00279 template<>
00280 class rc_signal<sc_dt::sc_logic>
00281 : public rc_signal_b<sc_dt::sc_logic>
00282 {
00283 private:
00284 typedef rc_signal<sc_dt::sc_logic> this_type;
00285 typedef rc_signal_b<sc_dt::sc_logic> base_type;
00286
00287 public:
00288 explicit rc_signal(
00289 const sc_module_name& name_=sc_gen_unique_name("signal"))
00290 : base_type(name_)
00291 { }
00292
00293
00294
00295 virtual const sc_event& posedge_event() const
00296 { m_notify_posedge_event = true; return m_posedge_event; }
00297
00298 virtual const sc_event& negedge_event() const
00299 { m_notify_negedge_event = true; return m_negedge_event; }
00300
00301 virtual bool posedge() const
00302 { return (this->event() && m_current_value == sc_dt::SC_LOGIC_1); }
00303
00304 virtual bool negedge() const
00305 { return (this->event() && m_current_value == sc_dt::SC_LOGIC_0); }
00306
00307
00308
00309 operator const sc_dt::sc_logic&() const
00310 { return this->read(); }
00311
00312 this_type& operator=(const sc_dt::sc_logic& value)
00313 { this->write(value); return *this; }
00314
00315 this_type& operator=(const this_type& signal_)
00316 { this->write(signal_.read()); return *this; }
00317
00318 protected:
00319
00320 virtual void update();
00321
00322 RC_ON_RESET()
00323 {
00324 base_type::rc_on_reset();
00325
00326
00327 if (m_notify_negedge_event) {
00328 m_negedge_event.cancel();
00329 }
00330 if (m_notify_posedge_event) {
00331 m_posedge_event.cancel();
00332 }
00333 }
00334
00335 protected:
00336 sc_event m_posedge_event;
00337 sc_event m_negedge_event;
00338 };
00339
00340
00341
00342 template<class T>
00343 void rc_signal_b<T>::register_port(
00344 sc_port_base& port_, const char* if_name_)
00345 {
00346 std::string if_name(if_name_);
00347 if (if_name == typeid(sc_signal_inout_if<T>).name()) {
00348 if (m_output_port != NULL) {
00349 internals::signals::report_binding_error(
00350 *this, *m_output_port, port_);
00351 }
00352 m_output_port = &port_;
00353 }
00354 }
00355
00356 template<class T>
00357 void rc_signal_b<T>::write(const T& value)
00358 {
00359 if (this->rc_is_active() || !sc_is_running()) {
00360 if (this->rc_is_constr_done()) {
00361 sc_object* driver_proc =
00362 sc_get_current_process_handle().get_process_object();
00363 if (m_driver_proc == NULL) {
00364 m_driver_proc = driver_proc;
00365 } else if (m_driver_proc != driver_proc && driver_proc != NULL) {
00366 internals::signals::report_driver_conflict(
00367 *this, *m_driver_proc, *driver_proc);
00368 }
00369 }
00370
00371 m_new_value = value;
00372 if (!(m_new_value == m_current_value)) {
00373 this->request_update();
00374 }
00375 }
00376 }
00377
00378 template<class T>
00379 void rc_signal_b<T>::dump(std::ostream& os) const
00380 {
00381 os << " name = " << this->name() << std::endl;
00382 os << " value = " << m_current_value << std::endl;
00383 os << "new value = " << m_new_value << std::endl;
00384 }
00385
00386 template<class T>
00387 void rc_signal_b<T>::update()
00388 {
00389 if (this->rc_is_active() && !(m_new_value == m_current_value)) {
00390 m_current_value = m_new_value;
00391 if (m_notify_value_changed_event) {
00392 m_value_changed_event.notify(SC_ZERO_TIME);
00393 }
00394 m_delta = sc_delta_count();
00395 }
00396 }
00397
00398 }
00399
00400 #endif // RC_SIGNAL_H_
00401
00402
00403
00404
00405