scc  2024.06
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 
23 namespace tilelink {
24 
25 const sc_core::sc_time CLK_DELAY = 1_ps;
26 
27 struct master_types {
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 
36 struct slave_types {
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 
45 struct signal_types {
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 
54 template <bool Cond, class T, class S> struct select_if { typedef S type; };
55 
56 template <class T, class S> struct select_if<true, T, S> { typedef T type; };
57 
68 template <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;
92 };
93 
94 inline std::string concat(const char* prefix, const char* name) { return std::string(prefix) + name; }
95 
97 template <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 
137 template <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 
177 template <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 
214 template <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 
254 template <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 
272 template <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 
285 template <typename CFG, typename TYPES = master_types> using tl_uh = tl_ul<CFG, TYPES>;
286 
287 template <typename CFG, typename TYPES = master_types>
288 struct 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_ */