scc  2024.06
SystemC components library
axi_target_pe.h
1 /*
2  * Copyright 2020-2022 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 <functional>
26 #include <memory>
27 #include <scc/mt19937_rng.h>
28 #include <scc/ordered_semaphore.h>
29 #include <scc/sc_variable.h>
30 #include <tlm/scc/pe/intor_if.h>
31 #include <tlm_utils/peq_with_cb_and_phase.h>
32 #include <unordered_set>
33 
35 namespace axi {
37 namespace pe {
38 
39 inline unsigned get_cci_randomized_value(cci::cci_param<int> const& p) {
40  if(p.get_value()<0) return scc::MT19937::uniform(0, -p.get_value());
41  return p.get_value();
42 }
46 class axi_target_pe : public sc_core::sc_module,
47 protected axi::fsm::base,
48 public axi::axi_fw_transport_if<axi::axi_protocol_types> {
49  struct bw_intor_impl;
50 public:
51 
52  using payload_type = axi::axi_protocol_types::tlm_payload_type;
53  using phase_type = axi::axi_protocol_types::tlm_phase_type;
54 
55  sc_core::sc_in<bool> clk_i{"clk_i"};
56 
57  sc_core::sc_port<tlm::scc::pe::intor_fw_nb, 1, sc_core::SC_ZERO_OR_MORE_BOUND> fw_o{"fw_o"};
58 
59  sc_core::sc_export<tlm::scc::pe::intor_bw_nb> bw_i{"bw_i"};
60 
65  cci::cci_param<unsigned> max_outstanding_tx{"max_outstanding_tx", 0};
69  cci::cci_param<bool> rd_data_interleaving{"rd_data_interleaving", true};
74  cci::cci_param<int> wr_data_accept_delay{"wr_data_accept_delay", 0};
78  cci::cci_param<int> rd_addr_accept_delay{"rd_addr_accept_delay", 0};
82  cci::cci_param<int> rd_data_beat_delay{"rd_data_beat_delay", 0};
87  cci::cci_param<int> rd_resp_delay{"rd_resp_delay", 0};
92  cci::cci_param<int> wr_resp_delay{"wr_resp_delay", 0};
93 
94  void b_transport(payload_type& trans, sc_core::sc_time& t) override;
95 
96  tlm::tlm_sync_enum nb_transport_fw(payload_type& trans, phase_type& phase, sc_core::sc_time& t) override;
97 
98  bool get_direct_mem_ptr(payload_type& trans, tlm::tlm_dmi& dmi_data) override;
99 
100  unsigned int transport_dbg(payload_type& trans) override;
111  void set_operation_cb(std::function<unsigned(payload_type& trans)> cb) { operation_cb = cb; }
118  void operation_resp(payload_type& trans, unsigned clk_delay = 0);
124  bool is_active() { return !active_fsm.empty(); }
130  const sc_core::sc_event& tx_finish_event() { return finish_evt; }
131 
132  ~axi_target_pe();
133 
140  explicit axi_target_pe(const sc_core::sc_module_name& nm, size_t transfer_width, flavor_e flavor = flavor_e::AXI);
141 
142  void set_bw_interface(axi::axi_bw_transport_if<axi_protocol_types>* ifs) {socket_bw=ifs;}
143 
144  inline unsigned getAllOutStandingTx() const {
145  return outstanding_rd_tx + outstanding_wr_tx + outstanding_ign_tx;
146  }
147 
148 protected:
149  axi_target_pe() = delete;
150 
151  axi_target_pe(axi_target_pe const&) = delete;
152 
153  axi_target_pe(axi_target_pe&&) = delete;
154 
155  axi_target_pe& operator=(axi_target_pe const&) = delete;
156 
157  axi_target_pe& operator=(axi_target_pe&&) = delete;
158 
159  void end_of_elaboration() override;
160 
161  void start_of_simulation() override;
162 
163  void fsm_clk_method() { process_fsm_clk_queue(); }
167  fsm::fsm_handle* create_fsm_handle() override;
171  void setup_callbacks(fsm::fsm_handle*) override;
172 
173  unsigned operations_callback(payload_type& trans);
174 
176  std::function<unsigned(payload_type& trans)> operation_cb;
177  scc::fifo_w_cb<std::tuple<payload_type*, unsigned>> rd_req2resp_fifo{"rd_req2resp_fifo"};
178  scc::fifo_w_cb<std::tuple<payload_type*, unsigned>> wr_req2resp_fifo{"wr_req2resp_fifo"};
179  void process_req2resp_fifos();
180  sc_core::sc_fifo<payload_type*> rd_resp_fifo{1}, wr_resp_fifo{1};
181  void start_rd_resp_thread();
182  void start_wr_resp_thread();
183  sc_core::sc_fifo<std::tuple<fsm::fsm_handle*, axi::fsm::protocol_time_point_e>> wr_resp_beat_fifo{128},
184  rd_resp_beat_fifo{128};
185  scc::ordered_semaphore rd_resp{1}, wr_resp_ch{1}, rd_resp_ch{1};
186  void send_wr_resp_beat_thread();
187  void send_rd_resp_beat_thread();
188 
189  sc_core::sc_clock* clk_if{nullptr};
190  std::unique_ptr<bw_intor_impl> bw_intor;
191  std::array<unsigned, 3> outstanding_cnt{{0, 0, 0}}; // count for limiting
192  scc::sc_variable<unsigned> outstanding_rd_tx{"OutstandingRd", 0};
193  scc::sc_variable<unsigned> outstanding_wr_tx{"OutstandingWr", 0};
194  scc::sc_variable<unsigned> outstanding_ign_tx{"OutstandingIgn", 0};
195  inline scc::sc_variable<unsigned>& getOutStandingTx(tlm::tlm_command cmd) {
196  switch(cmd) {
197  case tlm::TLM_READ_COMMAND:
198  return outstanding_rd_tx;
199  case tlm::TLM_WRITE_COMMAND:
200  return outstanding_wr_tx;
201  default:
202  return outstanding_ign_tx;
203  }
204  }
205  inline scc::sc_variable<unsigned> getOutStandingTx(tlm::tlm_command cmd) const {
206  switch(cmd) {
207  case tlm::TLM_READ_COMMAND:
208  return outstanding_rd_tx;
209  case tlm::TLM_WRITE_COMMAND:
210  return outstanding_wr_tx;
211  default:
212  return outstanding_ign_tx;
213  }
214  }
215  std::array<tlm::tlm_generic_payload*, 3> stalled_tx{nullptr, nullptr, nullptr};
216  std::array<axi::fsm::protocol_time_point_e, 3> stalled_tp{{axi::fsm::CB_CNT, axi::fsm::CB_CNT, axi::fsm::CB_CNT}};
217  void nb_fw(payload_type& trans, const phase_type& phase) {
218  auto delay = sc_core::SC_ZERO_TIME;
219  base::nb_fw(trans, phase, delay);
220  }
221  tlm_utils::peq_with_cb_and_phase<axi_target_pe> fw_peq{this, &axi_target_pe::nb_fw};
222  std::unordered_set<unsigned> active_rdresp_id;
223 };
224 
225 } // namespace pe
226 } // namespace axi
cci::cci_param< int > rd_addr_accept_delay
the latency between between BEGIN_REQ and END_REQ (ARVALID to ARREADY) -> APR
Definition: axi_target_pe.h:78
cci::cci_param< int > wr_data_accept_delay
the latency between between BEGIN(_PARTIAL)_REQ and END(_PARTIAL)_REQ (AWVALID to AWREADY and WVALID ...
Definition: axi_target_pe.h:74
cci::cci_param< bool > rd_data_interleaving
enable data interleaving on read responses if rd_data_beat_delay is greater than 0
Definition: axi_target_pe.h:69
const sc_core::sc_event & tx_finish_event()
fsm::fsm_handle * create_fsm_handle() override
void set_operation_cb(std::function< unsigned(payload_type &trans)> cb)
Set the operation callback function.
void operation_resp(payload_type &trans, unsigned clk_delay=0)
cci::cci_param< int > rd_data_beat_delay
the latency between between END(_PARTIAL)_RESP and BEGIN(_PARTIAL)_RESP (RREADY to RVALID) -> RBV
Definition: axi_target_pe.h:82
void setup_callbacks(fsm::fsm_handle *) override
cci::cci_param< int > rd_resp_delay
the latency between request and response phase. Will be overwritten by the return of the callback fun...
Definition: axi_target_pe.h:87
cci::cci_param< unsigned > max_outstanding_tx
the number of supported outstanding transactions. If this limit is reached the target starts to do ba...
Definition: axi_target_pe.h:65
cci::cci_param< int > wr_resp_delay
the latency between request and response phase. Will be overwritten by the return of the callback fun...
Definition: axi_target_pe.h:92
static uint64_t uniform()
Definition: mt19937_rng.h:60
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:956
tlm::tlm_fw_transport_if< TYPES > axi_fw_transport_if
alias declaration for the forward interface
Definition: axi_tlm.h:954
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