scc 2025.09
SystemC components library
signal_if.h
1/*******************************************************************************
2 * Copyright 2021 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 _BUS_TILELINK_SIGNAL_IF_H_
18#define _BUS_TILELINK_SIGNAL_IF_H_
19
20#include <scc/signal_opt_ports.h>
21#include <systemc>
22
23namespace tilelink {
24
25const sc_core::sc_time CLK_DELAY = 1_ps;
26
28 template <typename T> using m2s_t = sc_core::sc_out<T>;
29 template <typename T> using s2m_t = sc_core::sc_in<T>;
30 template <typename T> using m2s_full_t = sc_core::sc_out<T>;
31 template <typename T> using s2m_full_t = sc_core::sc_in<T>;
32 template <typename T> using m2s_opt_t = scc::sc_out_opt<T>;
33 template <typename T> using s2m_opt_t = scc::sc_in_opt<T>;
34};
35
37 template <typename T> using m2s_t = sc_core::sc_in<T>;
38 template <typename T> using s2m_t = sc_core::sc_out<T>;
39 template <typename T> using m2s_full_t = sc_core::sc_in<T>;
40 template <typename T> using s2m_full_t = sc_core::sc_out<T>;
41 template <typename T> using m2s_opt_t = scc::sc_in_opt<T>;
42 template <typename T> using s2m_opt_t = scc::sc_out_opt<T>;
43};
44
46 template <typename T> using m2s_t = sc_core::sc_signal<T>;
47 template <typename T> using s2m_t = sc_core::sc_signal<T>;
48 template <typename T> using m2s_full_t = sc_core::sc_signal<T>;
49 template <typename T> using s2m_full_t = sc_core::sc_signal<T>;
50 template <typename T> using m2s_opt_t = sc_core::sc_signal<T>;
51 template <typename T> using s2m_opt_t = sc_core::sc_signal<T>;
52};
53
54template <bool Cond, class T, class S> struct select_if { typedef S type; };
55
56template <class T, class S> struct select_if<true, T, S> { typedef T type; };
57
68template <unsigned int W = 32, unsigned int A = 32, unsigned int Z = 32, unsigned int O = 1, unsigned int I = 3> struct tl_cfg {
69
70 static_assert(W > 0, "W shall be larger than 0");
71 static_assert(W <= 4096, "W shall be less than or equal 4096");
72 // static_assert(CACHELINE > 0);
73 static_assert(A >= 0, "A shall be larger than or equal 0");
74 static_assert(A <= 128, "A shall be less than or equal 128");
75 static_assert(Z > 0, "Z shall be larger than 0");
76 static_assert(Z < 5, "Z shall be less than or equal 4");
77 static_assert(O >= 0, "O shall be larger than or equal 0");
78 static_assert(O <= 64, "O shall be less than or equal 64");
79 static_assert(I >= 0, "I shall be larger than or equal 0");
80 static_assert(I <= 64, "I shall be less than or equal 64");
81 constexpr static unsigned int BUSWIDTH = 8 * W;
82 constexpr static unsigned int MASKWIDTH = W;
83 constexpr static unsigned int ADDRWIDTH = A;
84 constexpr static unsigned int SZWIDTH = Z;
85 constexpr static unsigned int MIDWIDTH = O;
86 constexpr static unsigned int SIDWIDTH = I;
87 using addr_t = typename select_if<A <= 64, sc_dt::sc_uint<ADDRWIDTH>, sc_dt::sc_biguint<ADDRWIDTH>>::type;
88 using mask_t = typename select_if<W <= 64, sc_dt::sc_uint<MASKWIDTH>, sc_dt::sc_biguint<MASKWIDTH>>::type;
89 using data_t = typename select_if<(8 * W) <= 64, sc_dt::sc_uint<BUSWIDTH>, sc_dt::sc_biguint<BUSWIDTH>>::type;
90 using slave_types = ::tilelink::slave_types;
91 using master_types = ::tilelink::master_types;
92};
93
94inline std::string concat(const char* prefix, const char* name) { return std::string(prefix) + name; }
95
97template <typename CFG, typename TYPES = master_types> struct ch_a {
98 typename TYPES::template m2s_t<sc_dt::sc_uint<3>> code{"code"};
99 typename TYPES::template m2s_t<sc_dt::sc_uint<3>> param{"param"};
100 typename TYPES::template m2s_t<sc_dt::sc_uint<CFG::SZWIDTH>> size{"size"};
101 typename TYPES::template m2s_t<sc_dt::sc_uint<CFG::MIDWIDTH>> source{"source"};
102 typename TYPES::template m2s_t<CFG::addr_t> address{"address"};
103 typename TYPES::template m2s_t<CFG::mask_t> mask{"mask"};
104 typename TYPES::template m2s_t<CFG::data_t> data{"data"};
105 typename TYPES::template s2m_t<bool> corrupt{"corrupt"};
106 typename TYPES::template m2s_t<bool> valid{"valid"};
107 typename TYPES::template s2m_t<bool> ready{"ready"};
108
109 ch_a() = default;
110 ch_a(const char* prefix)
111 : code{concat(prefix, "_code").c_str()}
112 , param{concat(prefix, "_param").c_str()}
113 , size{concat(prefix, "_size").c_str()}
114 , source{concat(prefix, "_source").c_str()}
115 , address{concat(prefix, "_address").c_str()}
116 , mask{concat(prefix, "_mask").c_str()}
117 , data{concat(prefix, "_data").c_str()}
118 , corrupt{concat(prefix, "_corrupt").c_str()}
119 , valid{concat(prefix, "_valid").c_str()}
120 , ready{concat(prefix, "_ready").c_str()} {}
121
122 template <typename OTYPES> void bind_a(ch_a<CFG, OTYPES>& o) {
123 code.bind(o.code);
124 param.bind(o.param);
125 size.bind(o.size);
126 source.bind(o.source);
127 address.bind(o.address);
128 mask.bind(o.mask);
129 data.bind(o.data);
130 corrupt.bind(o.corrupt);
131 valid.bind(o.valid);
132 ready.bind(o.ready);
133 }
134};
135
137template <typename CFG, typename TYPES = master_types> struct ch_b {
138 typename TYPES::template s2m_t<sc_dt::sc_uint<3>> code{"code"};
139 typename TYPES::template s2m_t<sc_dt::sc_uint<3>> param{"param"};
140 typename TYPES::template s2m_t<sc_dt::sc_uint<CFG::SZWIDTH>> size{"size"};
141 typename TYPES::template s2m_t<sc_dt::sc_uint<CFG::MIDWIDTH>> source{"source"};
142 typename TYPES::template s2m_t<CFG::addr_t> address{"address"};
143 typename TYPES::template s2m_t<CFG::mask_t> mask{"mask"};
144 typename TYPES::template s2m_t<CFG::data_t> data{"data"};
145 typename TYPES::template m2s_t<bool> corrupt{"corrupt"};
146 typename TYPES::template s2m_t<bool> valid{"valid"};
147 typename TYPES::template m2s_t<bool> ready{"ready"};
148
149 ch_b() = default;
150 ch_b(const char* prefix)
151 : code{concat(prefix, "_code").c_str()}
152 , param{concat(prefix, "_param").c_str()}
153 , size{concat(prefix, "_size").c_str()}
154 , source{concat(prefix, "_source").c_str()}
155 , address{concat(prefix, "_address").c_str()}
156 , mask{concat(prefix, "_mask").c_str()}
157 , data{concat(prefix, "_data").c_str()}
158 , corrupt{concat(prefix, "_corrupt").c_str()}
159 , valid{concat(prefix, "_valid").c_str()}
160 , ready{concat(prefix, "_ready").c_str()} {}
161
162 template <typename OTYPES> void bind_b(ch_b<CFG, OTYPES>& o) {
163 code.bind(o.code);
164 param.bind(o.param);
165 size.bind(o.size);
166 source.bind(o.source);
167 address.bind(o.address);
168 mask.bind(o.mask);
169 data.bind(o.data);
170 corrupt.bind(o.corrupt);
171 valid.bind(o.valid);
172 ready.bind(o.ready);
173 }
174};
175
177template <typename CFG, typename TYPES = master_types> struct ch_c {
178 typename TYPES::template m2s_t<sc_dt::sc_uint<3>> code{"code"};
179 typename TYPES::template m2s_t<sc_dt::sc_uint<3>> param{"param"};
180 typename TYPES::template m2s_t<sc_dt::sc_uint<CFG::SZWIDTH>> size{"size"};
181 typename TYPES::template m2s_t<sc_dt::sc_uint<CFG::MIDWIDTH>> source{"source"};
182 typename TYPES::template m2s_t<CFG::addr_t> address{"address"};
183 typename TYPES::template m2s_t<CFG::data_t> data{"data"};
184 typename TYPES::template s2m_t<bool> corrupt{"corrupt"};
185 typename TYPES::template m2s_t<bool> valid{"valid"};
186 typename TYPES::template s2m_t<bool> ready{"ready"};
187
188 ch_c() = default;
189 ch_c(const char* prefix)
190 : code{concat(prefix, "_code").c_str()}
191 , param{concat(prefix, "_param").c_str()}
192 , size{concat(prefix, "_size").c_str()}
193 , source{concat(prefix, "_source").c_str()}
194 , address{concat(prefix, "_address").c_str()}
195 , data{concat(prefix, "_data").c_str()}
196 , corrupt{concat(prefix, "_corrupt").c_str()}
197 , valid{concat(prefix, "_valid").c_str()}
198 , ready{concat(prefix, "_ready").c_str()} {}
199
200 template <typename OTYPES> void bind_c(ch_b<CFG, OTYPES>& o) {
201 code.bind(o.code);
202 param.bind(o.param);
203 size.bind(o.size);
204 source.bind(o.source);
205 address.bind(o.address);
206 data.bind(o.data);
207 corrupt.bind(o.corrupt);
208 valid.bind(o.valid);
209 ready.bind(o.ready);
210 }
211};
212
214template <typename CFG, typename TYPES = master_types> struct ch_d {
215 typename TYPES::template s2m_t<sc_dt::sc_uint<3>> code{"code"};
216 typename TYPES::template s2m_t<sc_dt::sc_uint<2>> param{"param"};
217 typename TYPES::template s2m_t<sc_dt::sc_uint<CFG::SZWIDTH>> size{"size"};
218 typename TYPES::template s2m_t<sc_dt::sc_uint<CFG::MIDWIDTH>> source{"source"};
219 typename TYPES::template s2m_t<sc_dt::sc_uint<CFG::SIDWIDTH>> sink{"sink"};
220 typename TYPES::template m2s_t<bool> denied{"denied"};
221 typename TYPES::template s2m_t<CFG::data_t> data{"data"};
222 typename TYPES::template m2s_t<bool> corrupt{"corrupt"};
223 typename TYPES::template s2m_t<bool> valid{"valid"};
224 typename TYPES::template m2s_t<bool> ready{"ready"};
225
226 ch_d() = default;
227 ch_d(const char* prefix)
228 : code{concat(prefix, "_code").c_str()}
229 , param{concat(prefix, "_param").c_str()}
230 , size{concat(prefix, "_size").c_str()}
231 , source{concat(prefix, "_source").c_str()}
232 , sink{concat(prefix, "_sink").c_str()}
233 , denied{concat(prefix, "_denied").c_str()}
234 , data{concat(prefix, "_data").c_str()}
235 , corrupt{concat(prefix, "_corrupt").c_str()}
236 , valid{concat(prefix, "_valid").c_str()}
237 , ready{concat(prefix, "_ready").c_str()} {}
238
239 template <typename OTYPES> void bind_d(ch_d<CFG, OTYPES>& o) {
240 code.bind(o.code);
241 param.bind(o.param);
242 size.bind(o.size);
243 source.bind(o.source);
244 sink.bind(o.sink);
245 denied.bind(o.denied);
246 data.bind(o.data);
247 corrupt.bind(o.corrupt);
248 valid.bind(o.valid);
249 ready.bind(o.ready);
250 }
251};
252
254template <typename CFG, typename TYPES = master_types> struct ch_e {
255 typename TYPES::template m2s_t<sc_dt::sc_uint<CFG::SIDWIDTH>> sink{"sink"};
256 typename TYPES::template m2s_t<bool> valid{"valid"};
257 typename TYPES::template s2m_t<bool> ready{"ready"};
258
259 ch_e() = default;
260 ch_e(const char* prefix)
261 : sink{concat(prefix, "_sink").c_str()}
262 , valid{concat(prefix, "_valid").c_str()}
263 , ready{concat(prefix, "_ready").c_str()} {}
264
265 template <typename OTYPES> void bind_e(ch_e<CFG, OTYPES>& o) {
266 sink.bind(o.sink);
267 valid.bind(o.valid);
268 ready.bind(o.ready);
269 }
270};
271
272template <typename CFG, typename TYPES = master_types> struct tl_ul : public ch_a<CFG, TYPES>, public ch_d<CFG, TYPES> {
273 tl_ul()
274 : ch_a<CFG, TYPES>("a_")
275 , ch_d<CFG, TYPES>("d_") {}
276 tl_ul(const char* prefix)
277 : ch_a<CFG, TYPES>(concat(prefix, "_a_").c_str())
278 , ch_d<CFG, TYPES>(concat(prefix, "_d_").c_str()) {}
279 template <typename OTYPES> void bind(tl_ul<CFG, OTYPES>& o) {
280 bind_a(o);
281 bind_d(o);
282 }
283};
284
285template <typename CFG, typename TYPES = master_types> using tl_uh = tl_ul<CFG, TYPES>;
286
287template <typename CFG, typename TYPES = master_types>
288struct tl_c : public ch_a<CFG, TYPES>, public ch_b<CFG, TYPES>, public ch_c<CFG, TYPES>, public ch_d<CFG, TYPES>, public ch_e<CFG, TYPES> {
289 tl_c()
290 : ch_a<CFG, TYPES>("a_")
291 , ch_b<CFG, TYPES>("b_")
292 , ch_c<CFG, TYPES>("c_")
293 , ch_d<CFG, TYPES>("d_")
294 , ch_e<CFG, TYPES>("e_") {}
295 tl_c(const char* prefix)
296 : ch_a<CFG, TYPES>(concat(prefix, "_a_").c_str())
297 , ch_b<CFG, TYPES>(concat(prefix, "_b_").c_str())
298 , ch_c<CFG, TYPES>(concat(prefix, "_c_").c_str())
299 , ch_d<CFG, TYPES>(concat(prefix, "_d_").c_str())
300 , ch_e<CFG, TYPES>(concat(prefix, "_e_").c_str()) {}
301 template <typename OTYPES> void bind(tl_c<CFG, OTYPES>& o) {
302 bind_a(o);
303 bind_b(o);
304 bind_c(o);
305 bind_d(o);
306 bind_r(o);
307 }
308};
309
310} // namespace tilelink
311#endif /* _BUS_TILELINK_SIGNAL_IF_H_ */
A template class for an optional input port with optimized binding.
A template class for an optional input port with optimized binding.