20 #ifndef NVHLS_CONNECTIONS_NETWORK_H_ 21 #define NVHLS_CONNECTIONS_NETWORK_H_ 24 #include <nvhls_connections.h> 25 #include <nvhls_packet.h> 33 template <
typename Message,
unsigned int DestWidthPerHop,
unsigned int MaxHops,
34 unsigned int PacketIdWidth>
39 typedef Wrapped<Message> WMessage;
40 static const unsigned int width = WMessage::width;
41 typedef sc_lv<WMessage::width> MsgBits;
52 : sc_module(sc_module_name(sc_gen_unique_name(
"in_network"))),
58 InNetwork(sc_module_name name) : sc_module(name), clk(
"clk"), rst(
"rst") {
64 #ifdef CONNECTIONS_SIM_ONLY 70 sensitive << enq.msg << rst;
82 }
else if (enq.val.read()) {
83 sc_lv<Wrapped<Packet_t>::width> pbits = enq.msg.read();
84 Marshaller<Wrapped<Packet_t>::width> pmarshaller(pbits);
86 packet.Marshall(pmarshaller);
87 MsgBits mbits(packet.data);
92 void AssignVal() { deq.val.write(enq.val.read()); }
93 void AssignRdy() { enq.rdy.write(deq.rdy.read()); }
99 unsigned int pwidth = (Packet_t::width / 4);
101 if (enq.val.read() && enq.rdy.read()) {
102 std::cout << std::hex << std::setw(pwidth) << enq.msg.read();
104 std::cout << std::setw(pwidth + 1) <<
" ";
109 unsigned int mwidth = (Message().length() / 4);
110 if (deq.val.read() && deq.rdy.read()) {
111 std::cout << std::hex << std::setw(mwidth) << deq.msg.read();
113 std::cout << std::setw(mwidth + 1) <<
" ";
125 template <
typename Message,
unsigned int DestWidthPerHop,
unsigned int MaxHops,
126 unsigned int PacketIdWidth>
131 typedef Wrapped<Message> WMessage;
132 static const unsigned int width = WMessage::width;
133 typedef sc_lv<WMessage::width> MsgBits;
142 In<sc_lv<DestWidthPerHop * MaxHops> > route;
143 In<sc_lv<PacketIdWidth> > id;
146 sc_signal<sc_lv<DestWidthPerHop * MaxHops> > route_state;
147 sc_signal<sc_lv<PacketIdWidth> > id_state;
150 : sc_module(sc_module_name(sc_gen_unique_name(
"out_network"))),
156 OutNetwork(sc_module_name name) : sc_module(name), clk(
"clk"), rst(
"rst") {
162 #ifdef CONNECTIONS_SIM_ONLY 165 route.disable_spawn();
169 SC_METHOD(AssignMsg);
170 sensitive << enq.msg << id_state << route_state << rst;
172 SC_METHOD(AssignVal);
173 sensitive << enq.val;
175 SC_METHOD(AssignRdy);
176 sensitive << deq.rdy;
178 SC_METHOD(TieToHigh);
179 sensitive << clk.pos();
182 sensitive << clk.pos();
189 }
else if (enq.val.read()) {
191 vector_to_type(id_state.read(),
false, &packet.packet_id);
192 vector_to_type(route_state.read(),
false, &packet.dest);
193 vector_to_type(enq.msg.read(),
false, &packet.data);
194 Marshaller<Wrapped<Packet_t>::width> pmarshaller;
195 packet.Marshall(pmarshaller);
196 deq.msg.write(pmarshaller.GetResult());
200 void AssignVal() { deq.val.write(enq.val.read()); }
201 void AssignRdy() { enq.rdy.write(deq.rdy.read()); }
210 route_state.write(0);
213 if (route.val.read()) {
214 route_state.write(route.msg.read());
218 id_state.write(
id.msg.read());
224 #ifndef __SYNTHESIS__ 228 unsigned int mwidth = (Message().length() / 4);
230 if (enq.val.read() && enq.rdy.read()) {
231 std::cout << std::hex << std::setw(mwidth) << enq.msg.read();
233 std::cout << std::setw(mwidth + 1) <<
" ";
238 unsigned int pwidth = (Packet_t::width / 4);
239 if (deq.val.read() && deq.rdy.read()) {
240 std::cout << std::hex << std::setw(pwidth) << deq.msg.read();
242 std::cout << std::setw(pwidth + 1) <<
" ";
256 template <
typename Message,
unsigned int DestWidthPerHop,
unsigned int MaxHops,
257 unsigned int PacketIdWidth,
unsigned int CreditWidth>
262 typedef Wrapped<Message> WMessage;
263 static const unsigned int width = WMessage::width;
264 typedef sc_lv<WMessage::width> MsgBits;
269 typedef sc_lv<CreditWidth> Credit_t;
276 Out<CreditPacket_t> credit;
277 In<Credit_t> init_credits;
278 In<sc_lv<DestWidthPerHop * MaxHops> > credit_route;
279 In<sc_lv<PacketIdWidth> > credit_id;
285 Combinational<Credit_t> credit_enq;
288 sc_signal<Credit_t> credits;
289 sc_signal<Credit_t> credits_next;
292 : sc_module(sc_module_name(sc_gen_unique_name(
"in_nw_credit"))),
295 credit_out(
"credit_out") {
300 : sc_module(name), clk(
"clk"), rst(
"rst"), credit_out(
"credit_out") {
306 #ifdef CONNECTIONS_SIM_ONLY 309 credit.disable_spawn();
310 init_credits.disable_spawn();
311 credit_route.disable_spawn();
312 credit_id.disable_spawn();
317 credit_out.route(credit_route);
318 credit_out.id(credit_id);
319 credit_out.enq(credit_enq);
320 credit_out.deq(credit);
322 SC_METHOD(AssignMsg);
323 sensitive << enq.msg << rst;
325 SC_METHOD(AssignVal);
326 sensitive << enq.val;
328 SC_METHOD(AssignRdy);
329 sensitive << deq.rdy;
331 SC_METHOD(TieToHigh);
332 sensitive << clk.pos();
334 SC_METHOD(AssignNextCredits);
335 sensitive << deq.val << deq.rdy << credit_enq.val << credit_enq.rdy
338 SC_METHOD(AssignCreditMsg);
339 sensitive << deq.val << deq.rdy << credit_enq.val << credit_enq.rdy
342 SC_METHOD(AssignCreditVal);
343 sensitive << deq.val << deq.rdy << credits;
345 SC_THREAD(UpdateCredit);
346 sensitive << clk.pos();
353 }
else if (enq.val.read()) {
354 sc_lv<Wrapped<Packet_t>::width> pbits = enq.msg.read();
355 Marshaller<Wrapped<Packet_t>::width> pmarshaller(pbits);
357 packet.Marshall(pmarshaller);
358 MsgBits mbits(packet.data);
359 deq.msg.write(mbits);
363 void AssignVal() { deq.val.write(enq.val.read()); }
364 void AssignRdy() { enq.rdy.write(deq.rdy.read()); }
366 void TieToHigh() { init_credits.rdy.write(1); }
368 void AssignNextCredits() {
369 bool do_deq = deq.val.read() && deq.rdy.read();
370 bool do_credit = credit_enq.val.read() && credit_enq.rdy.read();
371 if (do_credit && !do_deq && (credits.read() != 0)) {
372 credits_next.write(0);
373 }
else if (do_credit && do_deq) {
374 credits_next.write(0);
375 }
else if (!do_credit && do_deq) {
376 credits_next.write(credits.read().to_uint() + 1);
378 credits_next.write(credits.read());
382 void AssignCreditMsg() {
383 bool do_deq = deq.val.read() && deq.rdy.read();
384 bool do_credit = credit_enq.val.read() && credit_enq.rdy.read();
385 if (do_deq && do_credit && (credits.read() == 0)) {
386 credit_enq.msg.write(1);
387 }
else if (do_deq && do_credit && (credits.read() != 0)) {
388 credit_enq.msg.write(credits.read().to_uint() + 1);
389 }
else if (!do_deq && do_credit && (credits.read() != 0)) {
390 credit_enq.msg.write(credits.read());
392 credit_enq.msg.write(0);
396 void AssignCreditVal() {
397 bool do_deq = deq.val.read() && deq.rdy.read();
398 if (do_deq || (credits.read() != 0)) {
399 credit_enq.val.write(1);
401 credit_enq.val.write(0);
405 void UpdateCredit() {
409 if (init_credits.val.read()) {
410 credits.write(init_credits.msg.read());
412 credits.write(credits_next.read());
418 #ifndef __SYNTHESIS__ 422 unsigned int pwidth = (Packet_t::width / 4);
424 if (enq.val.read() && enq.rdy.read()) {
425 std::cout << std::hex << std::setw(pwidth) << enq.msg.read();
427 std::cout << std::setw(pwidth + 1) <<
" ";
432 unsigned int mwidth = (Message().length() / 4);
433 if (deq.val.read() && deq.rdy.read()) {
434 std::cout << std::hex << std::setw(mwidth) << deq.msg.read();
436 std::cout << std::setw(mwidth + 1) <<
" ";
441 std::cout << std::hex <<
" ( " << credits.read() <<
" ) ";
444 unsigned int cwidth = (CreditPacket_t::width / 4);
445 if (credit.val.read() && credit.rdy.read()) {
446 std::cout << std::hex << std::setw(cwidth) << credit.msg.read();
448 std::cout << std::setw(cwidth + 1) <<
" ";
462 template <
typename Message,
unsigned int DestWidthPerHop,
unsigned int MaxHops,
463 unsigned int PacketIdWidth,
unsigned int CreditWidth>
468 typedef Wrapped<Message> WMessage;
469 static const unsigned int width = WMessage::width;
470 typedef sc_lv<WMessage::width> MsgBits;
475 typedef sc_lv<CreditWidth> Credit_t;
482 In<CreditPacket_t> credit;
483 In<sc_lv<DestWidthPerHop * MaxHops> > route;
484 In<sc_lv<PacketIdWidth> > id;
490 Combinational<Credit_t> credit_deq;
493 sc_signal<sc_lv<DestWidthPerHop * MaxHops> > route_state;
494 sc_signal<sc_lv<PacketIdWidth> > id_state;
495 sc_signal<Credit_t> credits;
496 sc_signal<Credit_t> credits_next;
499 : sc_module(sc_module_name(sc_gen_unique_name(
"out_nw_credit"))),
502 credit_in(
"credit_in") {
507 : sc_module(name), clk(
"clk"), rst(
"rst"), credit_in(
"credit_in") {
513 #ifdef CONNECTIONS_SIM_ONLY 516 credit.disable_spawn();
517 route.disable_spawn();
523 credit_in.enq(credit);
524 credit_in.deq(credit_deq);
526 SC_METHOD(AssignMsg);
527 sensitive << enq.msg << id_state << route_state << rst;
529 SC_METHOD(AssignVal);
530 sensitive << enq.val << credits << credit_deq.val << credit_deq.rdy;
532 SC_METHOD(AssignRdy);
533 sensitive << deq.rdy;
535 SC_METHOD(TieToHigh);
536 sensitive << clk.pos();
538 SC_METHOD(AssignNextCredits);
539 sensitive << deq.val << deq.rdy << credit_deq.val << credit_deq.rdy
542 SC_METHOD(AssignCreditRdy);
543 sensitive << deq.val << deq.rdy << credits;
545 SC_THREAD(UpdateCredit);
546 sensitive << clk.pos();
550 sensitive << clk.pos();
557 }
else if (enq.val.read()) {
559 vector_to_type(id_state.read(),
false, &packet.packet_id);
560 vector_to_type(route_state.read(),
false, &packet.dest);
561 vector_to_type(enq.msg.read(),
false, &packet.data);
562 Marshaller<Wrapped<Packet_t>::width> pmarshaller;
563 packet.Marshall(pmarshaller);
564 deq.msg.write(pmarshaller.GetResult());
569 bool do_credit = credit_deq.val.read() && credit_deq.rdy.read();
570 if (enq.val.read() && (credits.read() != 0)) {
572 }
else if (enq.val.read() && (credits.read() == 0) && do_credit) {
579 void AssignRdy() { enq.rdy.write(deq.rdy.read()); }
586 void AssignNextCredits() {
587 bool do_deq = deq.val.read() && deq.rdy.read();
588 bool do_credit = credit_deq.val.read() && credit_deq.rdy.read();
589 if (!do_credit && do_deq) {
590 credits_next.write(credits.read().to_uint() - 1);
591 }
else if (do_credit && !do_deq) {
592 credits_next.write(credits.read().to_uint() +
593 credit.msg.read().to_uint());
594 }
else if (do_credit && do_deq) {
595 credits_next.write(credits.read().to_uint() +
596 credit.msg.read().to_uint() - 1);
598 credits_next.write(credits.read());
602 void AssignCreditRdy() { credit_deq.rdy.write(1); }
604 void UpdateCredit() {
608 credits.write(credits_next.read());
615 route_state.write(0);
618 if (route.val.read()) {
619 route_state.write(route.msg.read());
623 id_state.write(
id.msg.read());
629 #ifndef __SYNTHESIS__ 633 unsigned int mwidth = (Message().length() / 4);
635 if (enq.val.read() && enq.rdy.read()) {
636 std::cout << std::hex << std::setw(mwidth) << enq.msg.read();
638 std::cout << std::setw(mwidth + 1) <<
" ";
643 unsigned int pwidth = (Packet_t::width / 4);
644 if (deq.val.read() && deq.rdy.read()) {
645 std::cout << std::hex << std::setw(pwidth) << deq.msg.read();
647 std::cout << std::setw(pwidth + 1) <<
" ";
652 std::cout << std::hex <<
" ( " << credits.read() <<
" ) ";
655 unsigned int cwidth = (CreditPacket_t::width / 4);
656 if (credit.val.read() && credit.rdy.read()) {
657 std::cout << std::hex << std::setw(cwidth) << credit.msg.read();
659 std::cout << std::setw(cwidth + 1) <<
" ";
669 #endif // NVHLS_CONNECTIONS_NETWORK_H_
Parameterized implementation of a network packet.
#define NVHLS_NEG_RESET_SIGNAL_IS(port)
ENABLE_SYNC_RESET define: Select synchronous or asynchronous reset.Matchlib uses asynchronous, active-low reset by default. Defining ENABLE_SYNC_RESET will use synchronous, active-low reset instead. The macros NVHLS_NEG_RESET_SIGNAL_IS() and NVHLS_POS_RESET_SIGNAL_IS() can be used in place of SystemC's reset_signal_is() and async_reset_signal_is() so that ENABLE_SYNC_RESET can select type.