MatchLib
All Classes Namespaces Files Functions Modules Pages
nvhls_packet.h
1/*
2 * Copyright (c) 2016-2019, NVIDIA CORPORATION. All rights reserved.
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// nvhls_packet.h
18//========================================================================
19// Packet and Flit class implementations
20
21#ifndef NVHLS_PACKET_H
22#define NVHLS_PACKET_H
23
24#include <systemc.h>
25#include <nvhls_types.h>
26#include <nvhls_marshaller.h>
27#include <nvhls_message.h>
28
29//------------------------------------------------------------------------
30// Packet
31//------------------------------------------------------------------------
32// Packet-id acts as unique identifier for the flits of a packet.
33// NOTE: 0 is default value. Initialize to value!=0.
34//
35// Dest denotes the packet destination
36//
37// For Source routing, Dest specifies the "route"
38
39enum RouterType { StoreForward, WormHole };
40
69template <int DataWidth, int DestWidthPerHop, int MaxHops = 1,
70 int PacketIdWidth = 0>
71class Packet : public nvhls_message {
72 public:
73 Packet() { reset(); }
74
75 Packet(const Packet& other) {
76 data = other.data;
77 dest = other.dest;
78 packet_id = other.packet_id;
79 }
80
81 Packet& operator=(const Packet& other) {
82 data = other.data;
83 dest = other.dest;
84 packet_id = other.packet_id;
85 return *this;
86 }
87
88 void reset() {
89 data = 0;
90 dest = 0;
91 packet_id = 0;
92 }
93
94 enum {
95 data_width = DataWidth,
96 dest_width_per_hop = DestWidthPerHop,
97 dest_width = DestWidthPerHop * MaxHops,
98 packet_id_width = PacketIdWidth,
99 width = data_width + dest_width + packet_id_width,
100 data_start_bit = 0,
101 data_end_bit = data_width - 1,
102 dest_start_bit = data_end_bit + 1,
103 dest_end_bit = dest_start_bit + dest_width - 1,
104 packet_id_start_bit = dest_end_bit + 1,
105 packet_id_end_bit = packet_id_start_bit + packet_id_width - 1
106 };
107
108 NVUINTW(data_width) data;
109 NVUINTW(dest_width) dest;
110 NVUINTW(packet_id_width) packet_id;
111
112 template <unsigned int Size>
113 void Marshall(Marshaller<Size>& m) {
114 m& data;
115 m& dest;
116 m& packet_id;
117 }
118};
119
120//-----------------------------------------------------------------------
121// Packet (specialization without ID)
122//-----------------------------------------------------------------------
123template <int DataWidth, int DestWidthPerHop, int MaxHops>
124class Packet<DataWidth, DestWidthPerHop, MaxHops, 0> : public nvhls_message {
125 public:
126 Packet() { reset(); }
127
128 Packet(const Packet& other) {
129 data = other.data;
130 dest = other.dest;
131 }
132
133 Packet& operator=(const Packet& other) {
134 data = other.data;
135 dest = other.dest;
136 return *this;
137 }
138
139 void reset() {
140 data = 0;
141 dest = 0;
142 }
143
144 enum {
145 data_width = DataWidth,
146 dest_width_per_hop = DestWidthPerHop,
147 dest_width = DestWidthPerHop * MaxHops,
148 width = data_width + dest_width,
149 data_start_bit = 0,
150 data_end_bit = data_width - 1,
151 dest_start_bit = data_end_bit + 1,
152 dest_end_bit = dest_start_bit + dest_width - 1,
153 };
154
155 NVUINTW(data_width) data;
156 NVUINTW(dest_width) dest;
157
158 template <unsigned int Size>
159 void Marshall(Marshaller<Size>& m) {
160 m& data;
161 m& dest;
162 }
163};
164
165//------------------------------------------------------------------------
166// Flit
167//------------------------------------------------------------------------
168class FlitId2bit;
169
170template <int DataWidth, int DestWidthPerHop, int MaxHops = 1,
171 int PacketIdWidth = 0, class FlitId = FlitId2bit,
172 RouterType Rtype = StoreForward>
173class Flit;
174
202class FlitId2bit : public nvhls_message {
203 public:
204 enum { width = 2 };
205
206 typedef enum { BODY = 0, HEAD = 1, TAIL = 2, SNGL = 3 } Encoding;
207
208 bool isHeader() const { return (data[0] == 1); }
209 bool isBody() const { return (data == BODY); }
210 bool isTail() const { return (data[1] == 1); }
211 bool isSingle() const { return (data == SNGL); }
212
213 void set(const Encoding& enc) { data = enc; }
214 void reset() { set(BODY); }
215
216 bool operator==(const FlitId2bit& other) const {
217 return (data == other.data);
218 }
219 FlitId2bit& operator=(const FlitId2bit& other) {
220 data = other.data;
221 return *this;
222 }
223
224 template <unsigned int Size>
225 void Marshall(Marshaller<Size>& m) {
226 m& data;
227 }
228
229 // Getter and setter providing raw access to the underlying data type
230 void set_raw(const NVUINTC(width) a) { data = a; }
231 NVUINTC(width) get_raw() { return data; }
232
233 NVUINTC(width) data;
234
235};
236
237#ifndef __SYNTHESIS__
238// NOTE: there is no real requirement to have this function templated. The only usage I am aware of it is with T=ostream
239// the reason this function was made templated is to avoid linker error. When multiple C files would independently include
240// current h file, unless this is a template function it would result a conflict in linkage stage because multiple
241// objects will have the implementation of this function. The "real" solution is to move all function bodies into C files,
242// and if necessary libraries. The quick and dirty workaround applied here relies on the fact that template functions are
243// required to be in h files which forces linker to resolve these kind of conflicts. So by templating this function
244// we avoid linker conflict scenario. Potentially can move it into a library in the future if/once such is created.
245template<class T>
246T& operator<<(T& os, const FlitId2bit& id) {
247 os << id.data;
248 return os;
249}
250#endif
282template <int DataWidth, int DestWidthPerHop, int MaxHops, int PacketIdWidth,
283 class FlitId>
284class Flit<DataWidth, DestWidthPerHop, MaxHops, PacketIdWidth, FlitId,
285 StoreForward> : public nvhls_message {
286 public:
287 Flit();
288
289 Flit(const Flit& other);
290
291 Flit& operator=(const Flit& other) {
292 data = other.data;
293 dest = other.dest;
294 packet_id = other.packet_id;
295 flit_id = other.flit_id;
296 return *this;
297 }
298
299 void reset();
300
301 enum {
302 data_width = DataWidth,
303 dest_width_per_hop = DestWidthPerHop,
304 dest_width = DestWidthPerHop * MaxHops,
305 packet_id_width = PacketIdWidth,
306 flit_id_width = FlitId::width,
307 width = data_width + dest_width + packet_id_width + flit_id_width,
308 data_start_bit = 0,
309 data_end_bit = data_width - 1,
310 dest_start_bit = data_end_bit + 1,
311 dest_end_bit = dest_start_bit + dest_width - 1,
312 packet_id_start_bit = dest_end_bit + 1,
313 packet_id_end_bit = packet_id_start_bit + packet_id_width - 1,
314 flit_id_start_bit = packet_id_end_bit + 1,
315 flit_id_end_bit = flit_id_start_bit + flit_id_width - 1
316 };
317
318 NVUINTW(data_width) data;
319 NVUINTW(dest_width) dest;
320 NVUINTW(packet_id_width) packet_id;
321 FlitId flit_id;
322
323 template <unsigned int Size>
324 void Marshall(Marshaller<Size>& m) {
325 m& data;
326 m& dest;
327 m& packet_id;
328 m& flit_id;
329 }
330};
331
332template <int DataWidth, int DestWidthPerHop, int MaxHops, int PacketIdWidth,
333 class FlitId>
334void Flit<DataWidth, DestWidthPerHop, MaxHops, PacketIdWidth, FlitId,
335 StoreForward>::reset() {
336 data = 0;
337 dest = 0;
338 packet_id = 0;
339 flit_id.reset();
340}
341
342template <int DataWidth, int DestWidthPerHop, int MaxHops, int PacketIdWidth,
343 class FlitId>
344Flit<DataWidth, DestWidthPerHop, MaxHops, PacketIdWidth, FlitId,
345 StoreForward>::Flit() {
346 reset();
347}
348
349template <int DataWidth, int DestWidthPerHop, int MaxHops, int PacketIdWidth,
350 class FlitId>
351Flit<DataWidth, DestWidthPerHop, MaxHops, PacketIdWidth, FlitId,
352 StoreForward>::Flit(const Flit<DataWidth, DestWidthPerHop, MaxHops,
353 PacketIdWidth, FlitId,
354 StoreForward>& other) {
355 data = other.data;
356 dest = other.dest;
357 packet_id = other.packet_id;
358 flit_id = other.flit_id;
359}
360
361//------------------------------------------------------------------------
362// WHFlit
363//------------------------------------------------------------------------
364// Packet-id acts as unique identifier for the flits of a packet
365// Flits of a packet take the same route and are always ordered
366// Flit-id is used to indicate type of payload : start, data, end
367
368template <int DataWidth, int PacketIdWidth, class FlitId>
369class Flit<DataWidth, 0, 0, PacketIdWidth, FlitId, WormHole> : public nvhls_message {
370 public:
371 Flit();
372
373 Flit(const Flit& other);
374
375 Flit& operator=(const Flit& other) {
376 data = other.data;
377 packet_id = other.packet_id;
378 flit_id = other.flit_id;
379 return *this;
380 }
381
382 void reset();
383
384 enum {
385 data_width = DataWidth,
386 packet_id_width = PacketIdWidth,
387 flit_id_width = FlitId::width,
388 width = data_width + packet_id_width + flit_id_width,
389 data_start_bit = 0,
390 data_end_bit = data_width - 1,
391 packet_id_start_bit = data_end_bit + 1,
392 packet_id_end_bit = packet_id_start_bit + packet_id_width - 1,
393 flit_id_start_bit = packet_id_end_bit + 1,
394 flit_id_end_bit = flit_id_start_bit + flit_id_width - 1
395 };
396
397 NVUINTW(data_width) data;
398 NVUINTW(packet_id_width) packet_id;
399 FlitId flit_id;
400
401 NVUINTW(packet_id_width) get_packet_id() const {
402 return packet_id;
403 }
404
405 template <unsigned int Size>
406 void Marshall(Marshaller<Size>& m) {
407 m& data;
408 m& packet_id;
409 m& flit_id;
410 }
411};
412
413template <int DataWidth, int PacketIdWidth, class FlitId>
415 data = 0;
416 packet_id = 0;
417 flit_id.reset();
418}
419
420template <int DataWidth, int PacketIdWidth, class FlitId>
422 reset();
423}
424
425template <int DataWidth, int PacketIdWidth, class FlitId>
428 data = other.data;
429 packet_id = other.packet_id;
430 flit_id = other.flit_id;
431}
432
433template <int DataWidth, int PacketIdWidth, class FlitId>
434inline std::ostream& operator<<(ostream& os, const Flit<DataWidth, 0, 0, PacketIdWidth, FlitId, WormHole>& flit)
435{
436 os << "<FlitId, PacketID, Data> <" << flit.flit_id << "," << flit.packet_id << "," << flit.data << ">";
437 return os;
438}
439// WHFlit specialization without packet id
440template <int DataWidth, class FlitId>
441class Flit<DataWidth, 0, 0, 0, FlitId, WormHole> : public nvhls_message {
442 public:
443 Flit();
444
445 Flit(const Flit& other);
446
447 Flit& operator=(const Flit& other) {
448 data = other.data;
449 flit_id = other.flit_id;
450 return *this;
451 }
452
453 void reset();
454
455 enum {
456 data_width = DataWidth,
457 flit_id_width = FlitId::width,
458 width = data_width + flit_id_width,
459 data_start_bit = 0,
460 data_end_bit = data_width - 1,
461 flit_id_start_bit = data_end_bit + 1,
462 flit_id_end_bit = flit_id_start_bit + flit_id_width - 1
463 };
464
465 NVUINTW(data_width) data;
466 FlitId flit_id;
467
468 int get_packet_id() const {
469 return 0;
470 }
471
472 template <unsigned int Size>
473 void Marshall(Marshaller<Size>& m) {
474 m& data;
475 m& flit_id;
476 }
477};
478
479template <int DataWidth, class FlitId>
481 data = 0;
482 flit_id.reset();
483}
484
485template <int DataWidth, class FlitId>
487 reset();
488}
489
490template <int DataWidth, class FlitId>
493 data = other.data;
494 flit_id = other.flit_id;
495}
496
497template <int DataWidth, class FlitId>
498inline std::ostream& operator<<(ostream& os, const Flit<DataWidth, 0, 0, 0, FlitId, WormHole>& flit)
499{
500 os << "<FlitId, Data> <" << flit.flit_id << "," << flit.data << ">";
501 return os;
502}
503
504#endif /*NVHLS_PACKET_H*/
Encoding for FlitID.
Parameterized implementation of a network packet.
#define NVUINTW(width)
Definition nvhls_types.h:35
#define NVUINTC(width)
Definition nvhls_types.h:66