scc 2025.09
SystemC components library
signal_initiator_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
17#ifndef __SIGNAL_INITIATOR_MIXIN_H__
18#define __SIGNAL_INITIATOR_MIXIN_H__
19
20#include "scc/utilities.h"
21#include <functional>
22#include <sstream>
23#include <tlm/scc/tlm_signal.h>
24
26namespace tlm {
28namespace scc {
29
30template <typename BASE_TYPE> class signal_initiator_mixin : public BASE_TYPE {
31public:
32 using tlm_signal_type = typename BASE_TYPE::tlm_signal_type;
33 using transaction_type = typename BASE_TYPE::transaction_type;
34 using phase_type = typename BASE_TYPE::phase_type;
35 using sync_enum_type = tlm::tlm_sync_enum;
38
39public:
40 signal_initiator_mixin()
41 : signal_initiator_mixin(sc_core::sc_gen_unique_name("signal_initiator_mixinn_socket")) {}
42
43 explicit signal_initiator_mixin(const char* n)
44 : BASE_TYPE(n)
45 , error_if_no_callback(false)
46 , bw_if(this) {
47 bind(bw_if);
48 }
49
50 using BASE_TYPE::bind;
51
52 void write_now(tlm_signal_type value) {
53 auto* gp = tlm_signal_gp<tlm_signal_type>::create();
54 gp->set_command(tlm::TLM_WRITE_COMMAND);
55 gp->set_value(value);
56 gp->acquire();
57 tlm::tlm_phase phase{tlm::BEGIN_REQ};
58 sc_core::sc_time delay{sc_core::SC_ZERO_TIME};
59 (*this)->nb_transport_fw(*gp, phase, delay);
60 gp->release();
61 }
62
63 template <typename EXT_TYPE> void write_now(tlm_signal_type value, EXT_TYPE* ext) {
64 auto* gp = tlm_signal_gp<tlm_signal_type>::create();
65 gp->set_command(tlm::TLM_WRITE_COMMAND);
66 gp->set_value(value);
67 if(ext)
68 gp->set_extension(ext);
69 gp->acquire();
70 tlm::tlm_phase phase{tlm::BEGIN_REQ};
71 sc_core::sc_time delay{sc_core::SC_ZERO_TIME};
72 (*this)->nb_transport_fw(*gp, phase, delay);
73 gp->release();
74 }
75
80 void register_nb_transport(std::function<sync_enum_type(transaction_type&, phase_type&, sc_core::sc_time&)> cb) {
81 bw_if.set_nb_transport_ptr(cb);
82 }
83
91 void register_nb_transport(std::function<sync_enum_type(unsigned int, transaction_type&, phase_type&, sc_core::sc_time&)> cb,
92 unsigned int tag) {
93 bw_if.set_nb_transport_ptr(cb);
94 }
95
96 bool error_if_no_callback;
97
98private:
99 class bw_transport_if : public bw_interface_type {
100 public:
101 using transport_fct = std::function<sync_enum_type(transaction_type&, phase_type&, sc_core::sc_time&)>;
102 using transport_tagged_fct = std::function<sync_enum_type(unsigned int, transaction_type&, phase_type&, sc_core::sc_time&)>;
103
104 bw_transport_if(const signal_initiator_mixin* owner)
105 : m_owner(owner) {}
106
107 void set_nb_transport_ptr(transport_fct p) {
108 if(m_transport_ptr || m_transport_tagged_ptr) {
109 std::stringstream s;
110 s << m_owner->name() << ": non-blocking callback allready registered";
111 SC_REPORT_WARNING("/OSCI_TLM-2/signal_initiator_mixin", s.str().c_str());
112 } else {
113 m_transport_ptr = p;
114 }
115 }
116
117 void set_nb_transport_ptr(transport_fct p, unsigned int tag) {
118 if(m_transport_ptr || m_transport_tagged_ptr) {
119 std::stringstream s;
120 s << m_owner->name() << ": non-blocking callback allready registered";
121 SC_REPORT_WARNING("/OSCI_TLM-2/signal_initiator_mixin", s.str().c_str());
122 } else {
123 m_transport_tagged_ptr = p;
124 this->tag = tag;
125 }
126 }
127
128 sync_enum_type nb_transport_bw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) {
129 if(m_transport_ptr)
130 return m_transport_ptr(trans, phase, t);
131 else if(m_transport_tagged_ptr)
132 return m_transport_tagged_ptr(tag, trans, phase, t);
133 else if(m_owner->error_if_no_callback) {
134 std::stringstream s;
135 s << m_owner->name() << ": no transport callback registered";
136 SC_REPORT_ERROR("/OSCI_TLM-2/signal_initiator_mixin", s.str().c_str());
137 }
138 return tlm::TLM_COMPLETED;
139 }
140
141 private:
142 const signal_initiator_mixin* m_owner;
143 unsigned int tag = 0;
144 transport_fct m_transport_ptr = nullptr;
145 transport_tagged_fct m_transport_tagged_ptr = nullptr;
146 };
147
148private:
149 bw_transport_if bw_if;
150};
151} // namespace scc
152} // namespace tlm
153
154#include <sysc/datatypes/bit/sc_logic.h>
155namespace tlm {
156namespace scc {
161} // namespace scc
162} // namespace tlm
163#endif //__SIGNAL_INITIATOR_MIXIN_H__
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_bw call
void register_nb_transport(std::function< sync_enum_type(transaction_type &, phase_type &, sc_core::sc_time &)> cb)
SCC TLM utilities.
Definition axis_tlm.h:56
SystemC TLM.
Definition dmi_mgr.h:19