scc 2026.07
SystemC components library
simple_initiator.h
1/*
2 * Copyright 2020 Arteris IP
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.axi_util.cpp
15 */
16
17#pragma once
18
19#ifndef SC_INCLUDE_DYNAMIC_PROCESSES
20#define SC_INCLUDE_DYNAMIC_PROCESSES
21#endif
22
23#include <array>
24#include <axi/fsm/base.h>
25#include <deque>
26#include <scc/ordered_semaphore.h>
27#include <sysc/kernel/sc_attribute.h>
28#include <tlm/scc/pe/intor_if.h>
29#include <unordered_map>
30#include <unordered_set>
31
33namespace axi {
35namespace pe {
39class simple_initiator_b : public sc_core::sc_module, public tlm::scc::pe::intor_fw_b, protected axi::fsm::base {
40public:
41 using payload_type = axi::axi_protocol_types::tlm_payload_type;
42 using phase_type = axi::axi_protocol_types::tlm_phase_type;
43
44 sc_core::sc_in<bool> clk_i{"clk_i"};
45
46 sc_core::sc_export<tlm::scc::pe::intor_fw_b> fw_i{"fw_i"};
47
48 sc_core::sc_port<tlm::scc::pe::intor_bw_b, 1, sc_core::SC_ZERO_OR_MORE_BOUND> bw_o{"bw_o"};
53 sc_core::sc_attribute<unsigned> wr_data_beat_delay{"wr_data_beat_delay", 0};
57 sc_core::sc_attribute<unsigned> rd_data_accept_delay{"rd_data_accept_delay", 0};
61 sc_core::sc_attribute<unsigned> wr_resp_accept_delay{"wr_resp_accept_delay", 0};
65 sc_core::sc_attribute<unsigned> ack_resp_delay{"ack_resp_delay", 0};
66
67 void b_snoop(payload_type& trans, sc_core::sc_time& t);
68
69 tlm::tlm_sync_enum nb_transport_bw(payload_type& trans, phase_type& phase, sc_core::sc_time& t);
70
71 void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range) {}
72
73 void set_clock_period(sc_core::sc_time clk_period) { this->clk_period = clk_period; }
74
75 size_t get_transferwith_in_bytes() const { return transfer_width_in_bytes; }
85 void transport(payload_type& trans, bool blocking) override;
99 void set_snoop_cb(std::function<unsigned(payload_type& trans)> cb) { snoop_cb = cb; }
106 void snoop_resp(payload_type& trans, bool sync = false) override;
112 unsigned snoop_latency{1};
122 void add_protocol_cb(axi::fsm::protocol_time_point_e e, std::function<void(payload_type&, bool)> cb) {
123 assert(e < axi::fsm::CB_CNT);
124 protocol_cb[e] = cb;
125 }
126
127protected:
133 explicit simple_initiator_b(const sc_core::sc_module_name& nm, sc_core::sc_port_b<axi::axi_fw_transport_if<axi_protocol_types>>& port,
134 size_t transfer_width, bool coherent = false);
135
136 simple_initiator_b() = delete;
137
138 simple_initiator_b(simple_initiator_b const&) = delete;
139
141
142 simple_initiator_b& operator=(simple_initiator_b const&) = delete;
143
144 simple_initiator_b& operator=(simple_initiator_b&&) = delete;
145
146 void fsm_clk_method() { process_fsm_clk_queue(); }
155
156 void process_snoop_resp();
157
158 unsigned thread_avail{0}, thread_active{0};
159 sc_core::sc_fifo<tlm::scc::tlm_gp_shared_ptr> dispatch_queue{"dispatch_queue"};
160 sc_core::sc_port_b<axi::axi_fw_transport_if<axi_protocol_types>>& socket_fw;
161 std::deque<fsm::fsm_handle*> idle_proc;
162 ::scc::ordered_semaphore rd{1}, wr{1}, snp{1};
163 ::scc::fifo_w_cb<std::tuple<axi::fsm::protocol_time_point_e, payload_type*, unsigned>> snp_resp_queue;
164 sc_core::sc_process_handle snp_resp_queue_hndl;
165 // TODO: remove hard coded value
166 sc_core::sc_time clk_period{1, sc_core::SC_NS};
167 std::function<unsigned(payload_type& trans)> snoop_cb;
168 std::array<std::function<void(payload_type&, bool)>, axi::fsm::CB_CNT> protocol_cb;
169 sc_core::sc_clock* clk_if{nullptr};
170 void end_of_elaboration() override;
171 scc::peq<std::tuple<axi::fsm::protocol_time_point_e, tlm::scc::tlm_gp_shared_ptr, bool>> cbpeq;
172 void cbpeq_cb();
173};
174
177template <unsigned int BUSWIDTH = 32, typename TYPES = axi::axi_protocol_types, int N = 1,
178 sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
179class simple_axi_initiator : public simple_initiator_b, public axi::axi_bw_transport_if<axi::axi_protocol_types> {
180public:
181 using base = simple_initiator_b;
182
183 using payload_type = base::payload_type;
184 using phase_type = base::phase_type;
190 : simple_initiator_b(nm, socket_.get_base_port(), BUSWIDTH)
191 , socket(socket_) {
192 socket(*this);
193 this->instance_name = name();
194 }
195
196 simple_axi_initiator() = delete;
197
199
201
202 simple_axi_initiator& operator=(simple_axi_initiator const&) = delete;
203
204 simple_axi_initiator& operator=(simple_axi_initiator&&) = delete;
205
213 tlm::tlm_sync_enum nb_transport_bw(payload_type& trans, phase_type& phase, sc_core::sc_time& t) override {
214 return base::nb_transport_bw(trans, phase, t);
215 }
216
221 void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range) override {
222 return base::invalidate_direct_mem_ptr(start_range, end_range);
223 }
224
225private:
227};
228
231template <unsigned int BUSWIDTH = 32, typename TYPES = axi::axi_protocol_types, int N = 1,
232 sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
233class simple_ace_initiator : public simple_initiator_b, public axi::ace_bw_transport_if<axi::axi_protocol_types> {
234public:
235 using base = simple_initiator_b;
236
237 using payload_type = base::payload_type;
238 using phase_type = base::phase_type;
243
245 : simple_initiator_b(nm, socket.get_base_port(), BUSWIDTH, true)
246 , socket(socket) {
247 socket(*this);
248 this->instance_name = name();
249 }
250
251 simple_ace_initiator() = delete;
252
254
256
257 simple_ace_initiator& operator=(simple_ace_initiator const&) = delete;
258
259 simple_ace_initiator& operator=(simple_ace_initiator&&) = delete;
265 void b_snoop(payload_type& trans, sc_core::sc_time& t) override { base::b_snoop(trans, t); }
273 tlm::tlm_sync_enum nb_transport_bw(payload_type& trans, phase_type& phase, sc_core::sc_time& t) override {
274 return base::nb_transport_bw(trans, phase, t);
275 }
276
281 void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range) override {
282 return base::invalidate_direct_mem_ptr(start_range, end_range);
283 }
284
285private:
287};
288
289} // namespace pe
290} // namespace axi
void b_snoop(payload_type &trans, sc_core::sc_time &t) override
forwarding function to the base class (due to inheritance)
simple_ace_initiator(const sc_core::sc_module_name &nm, axi::ace_initiator_socket< BUSWIDTH, TYPES, N, POL > &socket)
the constructor
void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range) override
forwarding function to the base class (due to inheritance)
tlm::tlm_sync_enum nb_transport_bw(payload_type &trans, phase_type &phase, sc_core::sc_time &t) override
forwarding function to the base class (due to inheritance)
void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range) override
forwarding function to the base class (due to inheritance)
simple_axi_initiator(const sc_core::sc_module_name &nm, axi::axi_initiator_socket< BUSWIDTH, TYPES, N, POL > &socket_)
the constructor
tlm::tlm_sync_enum nb_transport_bw(payload_type &trans, phase_type &phase, sc_core::sc_time &t) override
forwarding function to the base class (due to inheritance)
void setup_callbacks(axi::fsm::fsm_handle *) override
axi::fsm::fsm_handle * create_fsm_handle() override
void add_protocol_cb(axi::fsm::protocol_time_point_e e, std::function< void(payload_type &, bool)> cb)
register a callback for a certain time point
void snoop_resp(payload_type &trans, bool sync=false) override
triggers a non-blocking snoop response if the snoop callback does not do so.
simple_initiator_b(const sc_core::sc_module_name &nm, sc_core::sc_port_b< axi::axi_fw_transport_if< axi_protocol_types > > &port, size_t transfer_width, bool coherent=false)
sc_core::sc_attribute< unsigned > rd_data_accept_delay
the latency between between BEGIN(_PARTIAL)_RESP and END(_PARTIAL)_RESP (RVALID to RREADY)
sc_core::sc_attribute< unsigned > wr_resp_accept_delay
the latency between between BEGIN_RESP and END_RESP (BVALID to BREADY)
sc_core::sc_attribute< unsigned > ack_resp_delay
the latency between between BEGIN_RESP and END_RESP (BVALID to BREADY)
unsigned snoop_latency
the default snoop latency between request and response phase. Will be overwritten by the return of th...
sc_core::sc_attribute< unsigned > wr_data_beat_delay
the latency between between END(_PARTIAL)_REQ and BEGIN(_PARTIAL)_REQ (AWREADY to AWVALID and WREADY ...
void transport(payload_type &trans, bool blocking) override
The forward transport function. It behaves blocking and is re-entrant.
void set_snoop_cb(std::function< unsigned(payload_type &trans)> cb)
Set the snoop callback function.
protocol engine implementations
TLM2.0 components modeling AHB.
tlm::tlm_bw_transport_if< TYPES > axi_bw_transport_if
alias declaration for the backward interface:
Definition axi_tlm.h:953
tlm::tlm_fw_transport_if< TYPES > axi_fw_transport_if
alias declaration for the forward interface
Definition axi_tlm.h:951
The AXI protocol traits class. Since the protocoll defines additional non-ignorable phases a dedicate...
Definition axi_tlm.h:919
base class of all AXITLM based adapters and interfaces.
Definition base.h:40
void process_fsm_clk_queue()
processes the fsm_clk_queue and triggers the FSM accordingly. Should be registered as rising-edge clo...
Definition base.cpp:108
axi::axi_protocol_types::tlm_payload_type payload_type
aliases used in the class
Definition base.h:42