scc  2022.4.0
SystemC components library
signal_target_mixin.h
1 /*******************************************************************************
2  * Copyright 2016, 2018 MINRES Technologies GmbH
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *******************************************************************************/
16 #ifndef __SIGNAL_TARGET_MIXIN_H__
17 #define __SIGNAL_TARGET_MIXIN_H__
18 
19 #include "scc/utilities.h"
20 #include <functional>
21 #include <sstream>
22 #include <tlm/scc/tlm_signal.h>
23 
25 namespace tlm {
27 namespace scc {
28 
29 template <typename BASE_TYPE> class signal_target_mixin : public BASE_TYPE {
30 public:
31  using tlm_signal_type = typename BASE_TYPE::tlm_signal_type;
32  using transaction_type = typename BASE_TYPE::transaction_type;
33  using phase_type = typename BASE_TYPE::phase_type;
34  using sync_enum_type = tlm::tlm_sync_enum;
37 
38 public:
43  : signal_target_mixin(sc_core::sc_gen_unique_name("signal_target_mixin_socket")) {}
48  explicit signal_target_mixin(const char* n)
49  : BASE_TYPE(n)
50  , error_if_no_callback(true)
51  , fw_if(this) {
52  bind(fw_if);
53  }
54 
55  using BASE_TYPE::bind;
56 
61  void register_nb_transport(std::function<sync_enum_type(transaction_type&, phase_type&, sc_core::sc_time&)> cb) {
62  fw_if.set_nb_transport_ptr(cb);
63  }
72  void register_nb_transport(std::function<sync_enum_type(unsigned int, transaction_type&, phase_type&, sc_core::sc_time&)> cb,
73  unsigned int tag) {
74  fw_if.set_nb_transport_ptr(cb, tag);
75  }
76 
77  bool error_if_no_callback;
78 
79 private:
80  // make call on bw path.
81  sync_enum_type bw_nb_transport(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) {
82  return BASE_TYPE::operator->()->nb_transport_bw(trans, phase, t);
83  }
84 
85  class fw_process_if : public fw_interface_type {
86  public:
87  using transport_fct = std::function<sync_enum_type(transaction_type&, phase_type&, sc_core::sc_time&)>;
88  using transport_tagged_fct = std::function<sync_enum_type(unsigned int, transaction_type&, phase_type&, sc_core::sc_time&)>;
89 
90  fw_process_if(const signal_target_mixin* p_own)
91  : m_owner(p_own) {}
92 
93  void set_nb_transport_ptr(transport_fct p) {
94  if(m_transport_ptr || m_transport_tagged_ptr) {
95  std::stringstream s;
96  s << m_owner->name() << ": non-blocking callback allready registered";
97  SC_REPORT_WARNING("/OSCI_TLM-2/signal_target_mixin", s.str().c_str());
98  } else {
99  m_transport_ptr = p;
100  }
101  }
102 
103  void set_nb_transport_ptr(transport_tagged_fct p, unsigned int tag) {
104  if(m_transport_ptr || m_transport_tagged_ptr) {
105  std::stringstream s;
106  s << m_owner->name() << ": non-blocking callback allready registered";
107  SC_REPORT_WARNING("/OSCI_TLM-2/signal_target_mixin", s.str().c_str());
108  } else {
109  m_transport_tagged_ptr = p;
110  this->tag = tag;
111  }
112  }
113 
114  // Interface implementation
115  sync_enum_type nb_transport_fw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) {
116  if(m_transport_ptr) {
117  // forward call
118  return m_transport_ptr(trans, phase, t);
119  } else if(m_transport_tagged_ptr) {
120  // forward call
121  return m_transport_tagged_ptr(tag, trans, phase, t);
122  } else if(m_owner->error_if_no_callback) {
123  std::stringstream s;
124  s << m_owner->name() << ": no transport callback registered";
125  SC_REPORT_ERROR("/OSCI_TLM-2/signal_target_mixin", s.str().c_str());
126  }
127  return tlm::TLM_COMPLETED;
128  }
129 
130  private:
131  const signal_target_mixin* m_owner;
132  unsigned int tag = 0;
133  transport_fct m_transport_ptr = nullptr;
134  transport_tagged_fct m_transport_tagged_ptr = nullptr;
135  };
136 
137 private:
138  fw_process_if fw_if;
139 };
140 } // namespace scc
141 } // namespace tlm
142 
143 #include <sysc/datatypes/bit/sc_logic.h>
144 namespace tlm {
145 namespace scc {
146 using tlm_signal_bool_in = signal_target_mixin<tlm_signal_target_socket<bool>>;
147 using tlm_signal_logic_in = signal_target_mixin<tlm_signal_target_socket<sc_dt::sc_logic>>;
148 using tlm_signal_bool_opt_in = signal_target_mixin<tlm_signal_opt_target_socket<bool>>;
149 using tlm_signal_logic_opt_in = signal_target_mixin<tlm_signal_opt_target_socket<sc_dt::sc_logic>>;
150 } // namespace scc
151 } // namespace tlm
152 
153 #endif //__SIGNAL_TARGET_MIXIN_H__
void register_nb_transport(std::function< sync_enum_type(transaction_type &, phase_type &, sc_core::sc_time &)> cb)
void register_nb_transport(std::function< sync_enum_type(unsigned int, transaction_type &, phase_type &, sc_core::sc_time &)> cb, unsigned int tag)
register a functor for nb_transport_fw call
SCC SystemC utilities.
SystemC TLM.