scc 2025.09
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,
134 sc_core::sc_port_b<axi::axi_fw_transport_if<axi_protocol_types>>& port,
135 size_t transfer_width, bool coherent = false);
136
137 simple_initiator_b() = delete;
138
139 simple_initiator_b(simple_initiator_b const&) = delete;
140
142
143 simple_initiator_b& operator=(simple_initiator_b const&) = delete;
144
145 simple_initiator_b& operator=(simple_initiator_b&&) = delete;
146
147 void fsm_clk_method() { process_fsm_clk_queue(); }
156
157 void process_snoop_resp();
158
159 unsigned thread_avail{0}, thread_active{0};
160 sc_core::sc_fifo<tlm::scc::tlm_gp_shared_ptr> dispatch_queue{"dispatch_queue"};
161 sc_core::sc_port_b<axi::axi_fw_transport_if<axi_protocol_types>>& socket_fw;
162 std::deque<fsm::fsm_handle*> idle_proc;
163 ::scc::ordered_semaphore rd{1}, wr{1}, snp{1};
164 ::scc::fifo_w_cb<std::tuple<axi::fsm::protocol_time_point_e, payload_type*, unsigned>> snp_resp_queue;
165 sc_core::sc_process_handle snp_resp_queue_hndl;
166 // TODO: remove hard coded value
167 sc_core::sc_time clk_period{1, sc_core::SC_NS};
168 std::function<unsigned(payload_type& trans)> snoop_cb;
169 std::array<std::function<void(payload_type&, bool)>, axi::fsm::CB_CNT> protocol_cb;
170 sc_core::sc_clock* clk_if{nullptr};
171 void end_of_elaboration() override;
172 scc::peq<std::tuple<axi::fsm::protocol_time_point_e, tlm::scc::tlm_gp_shared_ptr, bool>> cbpeq;
173 void cbpeq_cb();
174};
175
178template <unsigned int BUSWIDTH = 32, typename TYPES = axi::axi_protocol_types, int N = 1,
179 sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
180class simple_axi_initiator : public simple_initiator_b, public axi::axi_bw_transport_if<axi::axi_protocol_types> {
181public:
182 using base = simple_initiator_b;
183
184 using payload_type = base::payload_type;
185 using phase_type = base::phase_type;
191 : simple_initiator_b(nm, socket_.get_base_port(), BUSWIDTH)
192 , socket(socket_) {
193 socket(*this);
194 this->instance_name = name();
195 }
196
197 simple_axi_initiator() = delete;
198
200
202
203 simple_axi_initiator& operator=(simple_axi_initiator const&) = delete;
204
205 simple_axi_initiator& operator=(simple_axi_initiator&&) = delete;
206
214 tlm::tlm_sync_enum nb_transport_bw(payload_type& trans, phase_type& phase, sc_core::sc_time& t) override {
215 return base::nb_transport_bw(trans, phase, t);
216 }
217
222 void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range) override {
223 return base::invalidate_direct_mem_ptr(start_range, end_range);
224 }
225
226private:
228};
229
232template <unsigned int BUSWIDTH = 32, typename TYPES = axi::axi_protocol_types, int N = 1,
233 sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
234class simple_ace_initiator : public simple_initiator_b, public axi::ace_bw_transport_if<axi::axi_protocol_types> {
235public:
236 using base = simple_initiator_b;
237
238 using payload_type = base::payload_type;
239 using phase_type = base::phase_type;
244
246 : simple_initiator_b(nm, socket.get_base_port(), BUSWIDTH, true)
247 , socket(socket) {
248 socket(*this);
249 this->instance_name = name();
250 }
251
252 simple_ace_initiator() = delete;
253
255
257
258 simple_ace_initiator& operator=(simple_ace_initiator const&) = delete;
259
260 simple_ace_initiator& operator=(simple_ace_initiator&&) = delete;
266 void b_snoop(payload_type& trans, sc_core::sc_time& t) override { base::b_snoop(trans, t); }
274 tlm::tlm_sync_enum nb_transport_bw(payload_type& trans, phase_type& phase, sc_core::sc_time& t) override {
275 return base::nb_transport_bw(trans, phase, t);
276 }
277
282 void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range) override {
283 return base::invalidate_direct_mem_ptr(start_range, end_range);
284 }
285
286private:
288};
289
290} // namespace pe
291} // 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:956
tlm::tlm_fw_transport_if< TYPES > axi_fw_transport_if
alias declaration for the forward interface
Definition axi_tlm.h:954
The AXI protocol traits class. Since the protocoll defines additional non-ignorable phases a dedicate...
Definition axi_tlm.h:920
base class of all AXITLM based adapters and interfaces.
Definition base.h:43
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:107
axi::axi_protocol_types::tlm_payload_type payload_type
aliases used in the class
Definition base.h:45