scc  2024.06
SystemC components library
spi_tlm.h
1 /*******************************************************************************
2  * Copyright 2024 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 _SPI_SPI_TLM_H_
18 #define _SPI_SPI_TLM_H_
19 
20 #include <cci_configuration>
21 #include <cstdint>
22 #include <scc/fifo_w_cb.h>
23 #include <scc/peq.h>
24 #include <scc/report.h>
25 #include <scc/sc_variable.h>
26 #include <tlm/nw/tlm_network_gp.h>
27 #include <tlm/nw/tlm_network_sockets.h>
28 #include <tlm/scc/tlm_gp_shared.h>
29 #include <tlm/scc/tlm_mm.h>
30 
32 namespace spi {
33 enum class SPI_PKT { DATA };
35  spi_packet_payload() = default;
36 
37  spi_packet_payload(unsigned target_id)
38  : target_id(target_id) {}
39 
42 
43  explicit spi_packet_payload(tlm::nw::tlm_base_mm_interface* mm, unsigned target_id)
45  , target_id(target_id) {}
46 
47  unsigned get_target_id() const { return target_id; }
48 
49 private:
50  unsigned target_id{0};
51  sc_core::sc_time sender_clk_period{sc_core::SC_ZERO_TIME};
52 };
53 
56  using tlm_phase_type = ::tlm::tlm_phase;
57 };
58 
59 } // namespace spi
60 
61 namespace tlm {
62 namespace scc {
63 // provide needed info for SCC memory manager
64 template <> struct tlm_mm_traits<spi::spi_packet_types> {
67 };
68 } // namespace scc
69 } // namespace tlm
70 
71 namespace spi {
72 template <int N = 1> using spi_pkt_initiator_socket = tlm::nw::tlm_network_initiator_socket<1, SPI_PKT, spi_packet_types, N>;
73 template <int N = 1> using spi_pkt_target_socket = tlm::nw::tlm_network_target_socket<1, SPI_PKT, spi_packet_types, N>;
76 
77 struct spi_channel : public sc_core::sc_module,
78  public tlm::nw::tlm_network_fw_transport_if<spi_packet_types>,
79  public tlm::nw::tlm_network_bw_transport_if<spi_packet_types> {
80 
82  using phase_type = spi_packet_types::tlm_phase_type;
83 
84  spi_pkt_target_socket<> tsck{"tsck"};
85 
86  sc_core::sc_vector<spi_pkt_initiator_socket<>> isck{"isck"};
87 
88  cci::cci_param<sc_core::sc_time> channel_delay{"channel_delay", sc_core::SC_ZERO_TIME, "delay of the SPI channel"};
89 
90  spi_channel(sc_core::sc_module_name const& nm, size_t slave_count)
91  : sc_core::sc_module(nm)
92  , isck{"isckt", slave_count} {
93  for(auto& is : isck)
94  is(*this);
95  tsck(*this);
96  }
97 
98  spi_pkt_target_socket<>& operator()() { return tsck; }
99 
100  spi_pkt_initiator_socket<>& operator()(size_t idx) { return isck.at(idx); }
101 
102  void b_transport(transaction_type& trans, sc_core::sc_time& t) override {
103  t += channel_delay;
104  isck.at(trans.get_target_id())->b_transport(trans, t);
105  }
106 
107  tlm::tlm_sync_enum nb_transport_fw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) override {
108  SCCTRACE(SCMOD) << "Received non-blocking transaction in fw path with phase " << phase.get_name();
109  if(phase == tlm::nw::REQUEST) {
110  auto idx = trans.get_target_id();
111  if(idx < isck.size()) {
112  phase_type ph = tlm::nw::INDICATION;
113  auto ret = isck.at(idx)->nb_transport_fw(trans, ph, t);
114  if(ph == tlm::nw::RESPONSE)
115  phase = tlm::nw::CONFIRM;
116  return ret;
117  } else {
118  trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE);
119  phase = tlm::nw::CONFIRM;
120  return tlm::TLM_COMPLETED;
121  }
122  }
123  return tlm::TLM_ACCEPTED;
124  }
125 
126  tlm::tlm_sync_enum nb_transport_bw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) override {
127  SCCTRACE(SCMOD) << "Received non-blocking transaction in bw path with phase " << phase.get_name();
128  if(phase == tlm::nw::RESPONSE) {
129  phase_type ph = tlm::nw::CONFIRM;
130  return tsck->nb_transport_bw(trans, ph, t);
131  }
132  return tlm::TLM_ACCEPTED;
133  }
134 
135  unsigned int transport_dbg(transaction_type& trans) override { return isck.at(trans.get_target_id())->transport_dbg(trans); }
136 };
137 } // namespace spi
138 #endif // _SPI_SPI_TLM_H_
SCC TLM utilities.
SPI TLM utilities.
Definition: spi_tlm.h:32
SystemC TLM.
Definition: cxs_tlm.h:69
a tlm memory manager
Definition: tlm_mm.h:285