scc 2025.09
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>
28#include <tlm/scc/tlm_gp_shared.h>
29#include <tlm/scc/tlm_mm.h>
30
32namespace spi {
33enum class SPI_PKT { DATA };
34struct spi_packet_payload : public tlm::nw::tlm_network_payload<SPI_PKT> {
35 spi_packet_payload() = default;
36
37 spi_packet_payload(unsigned target_id)
38 : target_id(target_id) {}
39
40 explicit spi_packet_payload(tlm::nw::tlm_base_mm_interface* mm)
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 const sc_core::sc_time& get_sender_clk_period() const { return sender_clk_period; }
50
51 void set_sender_clk_period(sc_core::sc_time period) { this->sender_clk_period = period; }
52
53 void set_target_id(unsigned id) { target_id = id; }
54
55private:
56 unsigned target_id{0};
57 sc_core::sc_time sender_clk_period{sc_core::SC_ZERO_TIME};
58};
59
61 using tlm_payload_type = spi_packet_payload;
62 using tlm_phase_type = ::tlm::tlm_phase;
63};
64
65} // namespace spi
66
67namespace tlm {
68namespace scc {
69// provide needed info for SCC memory manager
70template <> struct tlm_mm_traits<spi::spi_packet_types> {
71 using mm_if_type = tlm::nw::tlm_base_mm_interface;
72 using payload_base = tlm::nw::tlm_network_payload_base;
73};
74} // namespace scc
75} // namespace tlm
76
77namespace spi {
78template <int N = 1> using spi_pkt_initiator_socket = tlm::nw::tlm_network_initiator_socket<1, SPI_PKT, spi_packet_types, N>;
79template <int N = 1> using spi_pkt_target_socket = tlm::nw::tlm_network_target_socket<1, SPI_PKT, spi_packet_types, N>;
82
83struct spi_channel : public sc_core::sc_module,
84 public tlm::nw::tlm_network_fw_transport_if<spi_packet_types>,
85 public tlm::nw::tlm_network_bw_transport_if<spi_packet_types> {
86
87 using transaction_type = spi_packet_types::tlm_payload_type;
88 using phase_type = spi_packet_types::tlm_phase_type;
89
90 spi_pkt_target_socket<> tsck{"tsck"};
91
92 sc_core::sc_vector<spi_pkt_initiator_socket<>> isck{"isck"};
93
94 cci::cci_param<sc_core::sc_time> channel_delay{"channel_delay", sc_core::SC_ZERO_TIME, "delay of the SPI channel"};
95
96 spi_channel(sc_core::sc_module_name const& nm, size_t slave_count)
97 : sc_core::sc_module(nm)
98 , isck{"isckt", slave_count} {
99 for(auto& is : isck)
100 is(*this);
101 tsck(*this);
102 }
103
104 spi_pkt_target_socket<>& operator()() { return tsck; }
105
106 spi_pkt_initiator_socket<>& operator()(size_t idx) { return isck.at(idx); }
107
108 void b_transport(transaction_type& trans, sc_core::sc_time& t) override {
109 t += channel_delay;
110 isck.at(trans.get_target_id())->b_transport(trans, t);
111 }
112
113 tlm::tlm_sync_enum nb_transport_fw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) override {
114 SCCTRACE(SCMOD) << "Received non-blocking transaction in fw path with phase " << phase.get_name();
115 if(phase == tlm::nw::REQUEST) {
116 auto idx = trans.get_target_id();
117 if(idx < isck.size()) {
118 phase_type ph = tlm::nw::INDICATION;
119 auto ret = isck.at(idx)->nb_transport_fw(trans, ph, t);
120 if(ph == tlm::nw::RESPONSE)
121 phase = tlm::nw::CONFIRM;
122 return ret;
123 } else {
124 trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE);
125 phase = tlm::nw::CONFIRM;
126 return tlm::TLM_COMPLETED;
127 }
128 }
129 return tlm::TLM_ACCEPTED;
130 }
131
132 tlm::tlm_sync_enum nb_transport_bw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) override {
133 SCCTRACE(SCMOD) << "Received non-blocking transaction in bw path with phase " << phase.get_name();
134 if(phase == tlm::nw::RESPONSE) {
135 phase_type ph = tlm::nw::CONFIRM;
136 return tsck->nb_transport_bw(trans, ph, t);
137 }
138 return tlm::TLM_ACCEPTED;
139 }
140
141 unsigned int transport_dbg(transaction_type& trans) override { return isck.at(trans.get_target_id())->transport_dbg(trans); }
142};
143} // namespace spi
144#endif // _SPI_SPI_TLM_H_
SCC TLM utilities.
SPI TLM utilities.
Definition spi_tlm.h:32
SystemC TLM.
Definition dmi_mgr.h:19
Definition of the tlm_network_initiator_socket class.
A base class for TLM network payloads.
A class for TLM network payloads with support for extensions and memory management.
void set_response_status(const tlm_response_status response_status)
Sets the response status in the payload.
Definition of the tlm_network_target_socket class.
a tlm memory manager
Definition tlm_mm.h:330
The SystemC Transaction Level Model (TLM) Network TLM utilities.