scc  2022.4.0
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 
33 namespace axi {
35 namespace pe {
39 class simple_initiator_b : public sc_core::sc_module, public tlm::scc::pe::intor_fw_b, protected axi::fsm::base {
40 public:
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 
127 protected:
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(); }
155  void setup_callbacks(axi::fsm::fsm_handle*) override;
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};
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;
173  void cbpeq_cb();
174 };
178 template <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>
180 class simple_axi_initiator : public simple_initiator_b, public axi::axi_bw_transport_if<axi::axi_protocol_types> {
181 public:
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  }
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 
226 private:
228 };
232 template <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>
234 class simple_ace_initiator : public simple_initiator_b, public axi::ace_bw_transport_if<axi::axi_protocol_types> {
235 public:
236  using base = simple_initiator_b;
237 
238  using payload_type = base::payload_type;
239  using phase_type = base::phase_type;
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  }
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 
286 private:
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.
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.
fifo with callbacks
Definition: fifo_w_cb.h:38
The ordered_semaphore primitive channel class.
TLM2.0 components modeling AHB.
Definition: axi_initiator.h:30
tlm::tlm_bw_transport_if< TYPES > axi_bw_transport_if
alias declaration for the backward interface:
Definition: axi_tlm.h:918
tlm::tlm_fw_transport_if< TYPES > axi_fw_transport_if
alias declaration for the forward interface
Definition: axi_tlm.h:916
The AXI protocol traits class. Since the protocoll defines additional non-ignorable phases a dedicate...
Definition: axi_tlm.h:890
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
priority event queue
Definition: peq.h:41