MatchLib
WHVCRouter.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 #ifndef __WHVCROUTER_H__
18 #define __WHVCROUTER_H__
19 
20 // WormHole router with virtual channel and Multicast support.
21 // -Source Routing is assumed.
22 // -First flit stores route information.
23 // -Multi-cast to 1 remote port and many local ports.
24 // -Changing the destination format and route computation can allow multi-cast
25 // to all ports without distinction between local and remote ports.
26 // -Port numbers: local ports are numbered 0 to L-1, remote ports are numbered
27 // L to L+R-1.
28 // -1 hot encoding for local destination - send flit to port i if dest[i]=1.
29 // -Destination format per hop <Remote Dst> <Local Dst> .
30 // -Destination Width per Hop = r_dest_port_width_per_hop +
31 // l_dest_port_width_per_hop
32 // -Remote destination width is log_num_rports
33 // -Local destination width is num_lports
34 // -First flit format: <Dest-N> ... <Dest-2> <Dest-1>
35 // -This implementation assumes that virtual channel information is specified
36 // at the LSBs of packet id.
37 // -Termination condition: if dest of next hop is 0
38 
39 #include <nvhls_packet.h>
40 #include <nvhls_vector.h>
41 #include <Arbiter.h>
42 #include <hls_globals.h>
43 #include <fifo.h>
44 #include <one_hot_to_bin.h>
45 #include <nvhls_assert.h>
46 #include <crossbar.h>
47 
48 template <int NumLPorts, int NumRports, int NumVchannels, int BufferSize,
49  typename FlitType = Flit<64, 0, 0, 0, FlitId2bit, WormHole> >
50 class WHVCRouterBase : public sc_module {
51 public:
52  typedef FlitType Flit_t;
53  // Declare constants
54  enum {
55  num_lports = NumLPorts,
56  num_rports = NumRports,
57  num_ports = num_lports + num_rports,
58  num_vchannels = NumVchannels,
59  log_num_vchannels = nvhls::index_width<num_vchannels>::val,
60  log_num_lports = nvhls::index_width<num_lports>::val,
61  log_num_rports = nvhls::index_width<num_rports>::val,
62  log_num_ports = nvhls::index_width<num_ports>::val,
63  buffersize = BufferSize,
64  log_buffersize = nvhls::index_width<buffersize>::val,
65  log_buffersizeplus1 = nvhls::index_width<buffersize + 1>::val
66  };
67  typedef NVUINTW(log_buffersizeplus1) Credit_t;
68  typedef NVUINTW(1) Credit_ret_t;
69 
70  // Input / Output ports
71  Connections::In<Flit_t> in_port[num_ports];
72  Connections::Out<Flit_t> out_port[num_ports];
73 
74  // Credits
75  // Send out credit when buffer is popped
76  // Increment local credit when credits are read
77  // 1 credit counter per output port
78  Connections::In<Credit_ret_t> in_credit[num_ports * num_vchannels];
79  Connections::Out<Credit_ret_t> out_credit[num_ports * num_vchannels];
80  sc_in_clk clk;
81  sc_in<bool> rst;
82 
83  // Input FIFO Buffer
85 
86  // Credit registers to store credits for both producer and consumer
87  Credit_t credit_recv[num_ports * num_vchannels];
88  Credit_t credit_send[num_ports * num_vchannels];
89 
90  // Variable to register outputs
91  Flit_t flit_out[num_ports];
92 
93  // Constructor
94  SC_HAS_PROCESS(WHVCRouterBase);
95  WHVCRouterBase(sc_module_name name_) : sc_module(name_) {
96  SC_THREAD(process);
97  sensitive << clk.pos();
99  }
100 
101  // Function to receive credits from the consumers
102  void receive_credit() {
103  Credit_ret_t credit_in;
104 #pragma hls_unroll yes
105  for (int i = 0; i < num_ports * num_vchannels; i++) {
106  if (in_credit[i].PopNB(credit_in)) {
107  credit_recv[i] = credit_recv[i] + credit_in;
108  // DCOUT(sc_time_stamp() << ": " << name()
109  // << " Read credit from credit port-"
110  // << i << " " << credit_recv[i] << endl);
111  }
112  NVHLS_ASSERT_MSG(credit_recv[i] <= buffersize, "Total credits received cannot be larger than Buffer size");
113  }
114  }
115 
116  void send_credit() {
117 #pragma hls_unroll yes
118  for (int i = 0; i < num_ports * num_vchannels; i++) {
119  if (credit_send[i] > 0) {
120  Credit_ret_t credit_out = 1;
121  bool temp = out_credit[i].PushNB(credit_out);
122  if (temp) {
123  credit_send[i]--;
124  }
125  // DCOUT(sc_time_stamp() << ": " << name() << " Returning credit to port
126  // "
127  // << i << " credit_send=" << credit_send[i]
128  // << " Success: " << temp << endl);
129  }
130  }
131  }
132 
133  void fill_ififo() {
134  // Read input port if data is available and fill input buffers
135  Flit_t inflit[num_ports];
136 #pragma hls_unroll yes
137  for (int i = 0; i < num_ports; i++) {
138  if (in_port[i].PopNB(inflit[i])) {
139  DCOUT(sc_time_stamp() << ": " << name() << " Read input from port-" << i
140  << endl);
141  if (num_vchannels > 1) {
142  NVUINTW(log_num_vchannels) vcin_tmp = inflit[i].get_packet_id();
143  NVHLS_ASSERT_MSG(!ififo.isFull(i * num_vchannels + vcin_tmp), "Input fifo is full");
144  ififo.push(inflit[i], i * num_vchannels + vcin_tmp);
145  } else {
146  NVHLS_ASSERT_MSG(!ififo.isFull(i), "Input fifo is full");
147  ififo.push(inflit[i], i);
148  }
149  }
150  }
151  }
152 
153  void peek_ififo(Flit_t flit_in[num_ports],
154  NVUINTW(log_num_vchannels) vcin[num_ports],
155  NVUINTW(num_ports) in_valid) {
156 
157 #pragma hls_unroll yes
158  for (int i = 0; i < num_ports; i++) { // Iterating through the inputs here
159  // FIFO Read
160  if (in_valid[i]) {
161  flit_in[i] = ififo.peek(i * num_vchannels + vcin[i]);
162  DCOUT(sc_time_stamp()
163  << ": " << name() << hex << " Read from FIFO:"
164  << i * num_vchannels + vcin[i] << " Flit< " << flit_in[i].flit_id
165  << "," << flit_in[i].data.to_uint64() << ">" << dec << endl);
166  }
167  }
168  }
169 
170  void crossbar_traversal(Flit_t flit_in[num_ports], bool is_push[num_ports],
171  NVUINTW(log_num_ports) select_id[num_ports],
172  NVUINTW(log_num_vchannels) vcin[num_ports],
173  NVUINTW(log_num_vchannels) vcout[num_ports]) {
174 #pragma hls_unroll yes
175  for (int i = 0; i < num_ports; i++) { // Iterating through output ports here
176  if (is_push[i]) {
177  flit_out[i] = flit_in[select_id[i]];
178  vcout[i] = vcin[select_id[i]];
179  }
180  }
181  }
182 
183 
184  virtual void reset() { }
185  virtual void run() { }
186 
187  void process() {
188  for (int i = 0; i < num_ports; i++)
189  in_port[i].Reset();
190  for (int i = 0; i < num_ports; i++)
191  out_port[i].Reset();
192  for (int i = 0; i < num_ports * num_vchannels; i++)
193  out_credit[i].Reset();
194  for (int i = 0; i < num_ports * num_vchannels; i++)
195  in_credit[i].Reset();
196  ififo.reset();
197  reset();
198 
199  // Reset credit registers
200  for (int i = 0; i < num_ports * num_vchannels; i++) {
201  credit_send[i] = 0;
202  credit_recv[i] = buffersize;
203  }
204 
205  #pragma hls_pipeline_init_interval 1
206  while (1) {
207  wait();
208  run();
209  }
210  }
211 };
212 
213 // Specialization for SourceRouting
255 template <int NumLPorts, int NumRports, int NumVchannels, int BufferSize,
256  typename FlitType, int MaxHops>
257 class WHVCSourceRouter: public WHVCRouterBase<NumLPorts, NumRports, NumVchannels, BufferSize, FlitType> {
258 public:
259  // Declare constants
261  typedef FlitType Flit_t;
262  enum {
263  num_lports = BaseClass::num_lports,
264  num_rports = BaseClass::num_rports,
265  num_ports = BaseClass::num_ports,
266  num_vchannels = BaseClass::num_vchannels,
267  log_num_rports = BaseClass::log_num_rports,
268  log_num_ports = BaseClass::log_num_ports,
269  log_num_vchannels = BaseClass::log_num_vchannels,
270  dest_width_per_hop = log_num_rports + num_lports,
271  dest_width = MaxHops * dest_width_per_hop,
272  };
273 
274  WHVCSourceRouter(sc_module_name name_): BaseClass(name_) {
275 
276  }
277 
278  Arbiter<num_ports> arbiter[num_ports];
279 
280  // Store output destination for each port per virtual channel with 1hot
281  // encoding
282  NVUINTW(num_ports) out_dest[num_ports][num_vchannels];
283 
284  // Variable to block output port until previous push is successful
285  NVUINTW(num_ports) out_stall;
286 
287  // Variable that indicates if the output port is available to get new packet
288  bool is_get_new_packet[num_ports * num_vchannels];
289 
290  void inputvc_arbiter(NVUINTW(log_num_vchannels) vcin[num_ports],
291  NVUINTW(num_ports) & in_valid) {
292 #pragma hls_unroll yes
293  for (int i = 0; i < num_ports; i++) { // Iterating through the inputs here
294  vcin[i] = 0;
295  // Doing static arbitration across input VCs here. VC0 has
296  // highest priority. We are assuming that input and output VCs
297  // are same.
298  if (num_vchannels > 1) {
299  NVUINTW(num_vchannels) vcin_valid = 0;
300  NVUINTW(log_num_vchannels) vcin_local = 0;
301 #pragma hls_unroll yes
302  for (int j = 0; j < num_vchannels; j++) {
303  if ((!this->ififo.isEmpty(i * num_vchannels + j))) {
304  vcin_valid[num_vchannels - j - 1] = 1;
305  in_valid[i] = 1;
306  }
307  }
308  if (in_valid[i] == 1) {
309  vcin_local =
310  nvhls::leading_ones<num_vchannels, NVUINTW(num_vchannels),
311  NVUINTW(log_num_vchannels)>(vcin_valid);
312  vcin[i] = num_vchannels - vcin_local - 1;
313  }
314  } else {
315 #pragma hls_unroll yes
316  for (int i = 0; i < num_ports; i++) {
317  vcin[i] = 0;
318  if (!this->ififo.isEmpty(i)) {
319  in_valid[i] = 1;
320  }
321  }
322  }
323 
324  }
325  }
326  void compute_route(Flit_t flit_in[num_ports],
327  NVUINTW(log_num_vchannels) vcin[num_ports],
328  NVUINTW(num_ports) in_valid) {
329 
330 #pragma hls_unroll yes
331  for (int i = 0; i < num_ports; i++) { // Iterating through the inputs here
332  if (in_valid[i]) {
333  // Route Computation: For source routing just copy from header flit
334  if (flit_in[i].flit_id.isHeader()) {
335  NVUINTW(dest_width)
336  route = nvhls::get_slc<dest_width>(flit_in[i].data, 0);
337  NVUINTW(dest_width_per_hop)
338  out_dest_local = nvhls::get_slc<dest_width_per_hop>(route, 0);
339  NVUINTW(dest_width) next_dests_local = route >> dest_width_per_hop;
340  flit_in[i].data =
341  nvhls::set_slc(flit_in[i].data, next_dests_local, 0);
342  NVUINTW(num_lports)
343  ldest = nvhls::get_slc<num_lports>(out_dest_local, 0);
344  NVUINTW(log_num_rports)
345  rdest = nvhls::get_slc<log_num_rports>(out_dest_local, num_lports);
346  NVUINTW(num_rports) rdest_1hot = 0;
347  if (next_dests_local != 0) {
348  rdest_1hot[rdest] = 1;
349  }
350  out_dest[i][vcin[i]] =
351  (static_cast<NVUINTW(num_ports)>(rdest_1hot) << num_lports) |
352  ldest;
353  }
354  }
355  }
356  }
357 
358  void flit_output(bool is_push[num_ports],
359  NVUINTW(log_num_vchannels) vcout[num_ports]) {
360 
361 #pragma hls_unroll yes
362  for (int i = 0; i < num_ports; i++) { // Iterating over outputs here
363  if (is_push[i] == true || out_stall[i] == 1) {
364  bool temp = this->out_port[i].PushNB(this->flit_out[i]);
365  if (this->flit_out[i].flit_id.isTail()) {
366  is_get_new_packet[i * num_vchannels + vcout[i]] = true;
367  } else {
368  is_get_new_packet[i * num_vchannels + vcout[i]] = false;
369  }
370  if (temp == 0)
371  out_stall[i] = 1;
372  else {
373  out_stall[i] = 0;
374  this->credit_recv[i * num_vchannels + vcout[i]]--;
375  }
376  DCOUT(sc_time_stamp()
377  << ": " << this->name() << " OutPort " << i
378  << " Push success??: " << temp << " Decrementing Credit status "
379  << i * num_vchannels + vcout[i] << ": "
380  << this->credit_recv[i * num_vchannels + vcout[i]]
381  << " [Router] Out_stall: " << out_stall[i] << endl);
382  }
383  }
384  }
385 
386  void arbitration(Flit_t flit_in[num_ports], NVUINTW(num_ports) in_valid,
387  NVUINTW(log_num_vchannels) vcin[num_ports],
388  NVUINTW(num_ports) valid[num_ports],
389  NVUINTW(num_ports) select[num_ports],
390  NVUINTW(log_num_ports) select_id[num_ports]) {
391 
392 #pragma hls_unroll yes
393  for (int i = 0; i < num_ports; i++) { // Iterating through the outputs here
394  valid[i] = 0; // valid of ith output is set to 0 here
395  }
396 
397 #pragma hls_unroll yes
398  for (int i = 0; i < num_ports; i++) { // Iterating through the inputs here
399  if (in_valid[i]) {
400  bool not_head_flit = (!flit_in[i].flit_id.isHeader());
401 
402 #pragma hls_unroll yes
403  for (int k = 0; k < num_ports;
404  k++) { // Iterating through the outputs here
405  int out_idx = k * num_vchannels + vcin[i];
406 
407  // Set valid bit to 1 for local ports only if credits are available at
408  // the output port for the virtual channel chosen
409  // also make sure that the output is requested, and that it is not
410  // head flit, or output[vc] accepts new headers
411  valid[k][i] =
412  (((this->credit_recv[out_idx] != 0) && (out_dest[i][vcin[i]][k] == 1) &&
413  (is_get_new_packet[out_idx] || not_head_flit) &&
414  (out_stall[k] == 0))
415  ? 1
416  : 0);
417  // DCOUT(sc_time_stamp() << ": " << name() << " Input Port:" << i << "
418  // Output port: " << k << " VC: " << vcin[i] << " valid: "<<
419  // valid[k][i] << " OutStall: " << out_stall[k] << " Credit: " <<
420  // credit_recv[out_idx] << " GetnewPacket: " <<
421  // is_get_new_packet[out_idx] << hex << " Flit " << " <" <<
422  // flit_in[i].flit_id << "," << flit_in[i].data.to_uint64() << dec <<
423  // ">" << endl);
424  }
425  }
426  }
427 
428 #ifdef ENABLE_MULTICAST
429  // For Multicast, supress local output valid if remote output is invalid
430  NVUINTW((num_ports * num_vchannels))
431  is_multicast = 0; // Store if an input is unicast or multicast
432  NVUINTW(log_num_ports) remote_portid[num_ports];
433  NVUINTW(log_num_lports) local_portid[num_ports];
434 
435 #pragma hls_unroll yes
436  for (int i = 0; i < num_ports; i++) { // Iterating through the inputs here
437 #pragma hls_unroll yes
438  for (int l = 0; l < num_lports;
439  l++) { // Iterating through the outputs here
440 #pragma hls_unroll yes
441  for (int r = num_lports; r < num_ports; r++) {
442  if (out_dest[i][vcin[i]][l] && out_dest[i][vcin[i]][r]) {
443  is_multicast[i * num_vchannels + vcin[i]] = 1;
444  remote_portid[i] = r;
445  local_portid[i] = l;
446  if (!(valid[l][i] && valid[r][i])) {
447  valid[l][i] = 0;
448  valid[r][i] = 0; // valid of local port is 1 only is valid of
449  // remote port is 1
450  // DCOUT(sc_time_stamp() << ": " << name() << " Input Port:" << i
451  // << " Local port: " << l << " Remote port: " << r << " VC: " <<
452  // vcin[i] << " valid: "<< valid[l][i] << " Multicast: " <<
453  // is_multicast[i*num_vchannels + vcin[i]] << endl);
454  }
455  }
456  }
457  }
458  }
459 #endif
460 
461 // Arbitrate for output port if it is header flit
462 #pragma hls_unroll yes
463  for (int i = 0; i < num_ports; i++) { // Iterating through the outputs here
464  select[i] = 0;
465  if (valid[i] != 0) { // There is an input waiting to send to output
466  // i, credits are available at output
467  select[i] = arbiter[i].pick(valid[i]);
468 
469  NVUINTW(num_ports) select_temp = select[i];
470  NVUINTW(log_num_ports) select_id_temp;
471  one_hot_to_bin<num_ports, log_num_ports>(select_temp, select_id_temp);
472  select_id[i] = select_id_temp;
473  // DCOUT(sc_time_stamp() << ": " << name() << hex << " Output Port:" <<
474  // i
475  // << " Valid: " << valid[i].to_uint64()
476  // << " Select : " << select[i].to_int64() << dec << "
477  // Multicast: " <<
478  // is_multicast[(select_id[i]*num_vchannels+vcin[select_id[i]])]
479  // << endl);
480  }
481  }
482 
483 #ifdef ENABLE_MULTICAST
484 // For Multicast, set remote select = local select
485 #pragma hls_unroll yes
486  for (int i = 0; i < num_lports;
487  i++) { // Iterating through the remote outputs here
488  if (select[i] != 0 &&
489  is_multicast[(select_id[i] * num_vchannels + vcin[select_id[i]])] &&
490  valid[remote_portid[select_id[i]]][select_id[i]]) {
491  select[remote_portid[select_id[i]]] = select[i];
492  select_id[remote_portid[select_id[i]]] = select_id[i];
493  // DCOUT(sc_time_stamp() << ": " << name() << " Output Port:" << i << "
494  // Input port: " << select_id[i] << " Remote port: " <<
495  // remote_portid[select_id[i]] << " VC: " << vcin[select_id[i]] << "
496  // Remote Select: " << select[remote_portid[select_id[i]]] << " Local
497  // Select: " << select[i] << endl);
498  }
499  }
500 // For Multicast, if remote port is selected and not local port, reset remote
501 // port
502 #pragma hls_unroll yes
503  for (int i = num_lports; i < num_ports;
504  i++) { // Iterating through the remote outputs here
505  if (select[i] != 0 &&
506  is_multicast[(select_id[i] * num_vchannels + vcin[select_id[i]])] &&
507  (valid[i][select_id[local_portid[select_id[i]]]] == 0)) {
508  select[i] = 0;
509  // DCOUT("Set Select = 0 for Output port: " << i << endl);
510  // DCOUT(sc_time_stamp() << ": " << name() << " Output Port:" << i << "
511  // Input port: " << select_id[i] << " Remote port: " <<
512  // remote_portid[select_id[i]] << " VC: " << vcin[select_id[i]] << "
513  // Remote Select: " << select[i] << " Local Select: " <<
514  // select[local_portid[select_id[i]]] << endl);
515  }
516  }
517 #endif
518  }
519 
520  void reset() {
521  out_stall = 0;
522  for (int i = 0; i < num_ports * num_vchannels; i++) {
523  is_get_new_packet[i] = true;
524  }
525  }
526 
527 
528  void run() {
529  this->receive_credit();
530  this->fill_ififo();
531 
532  Flit_t flit_in[num_ports];
533  NVUINTW(log_num_vchannels) vcin[num_ports];
534  NVUINTW(num_ports) in_valid = 0;
535 
536  // pick a valid vc per input. VC0 has priority.
537  // output: vcin[x] - vc selcted for in port x, in_valid - bitmap of
538  // inports valid bits
539  inputvc_arbiter(vcin, in_valid);
540 
541  // read top flit for each selected vc per in port
542  // output: flit_in[x] - top flit on selected vc on port x
543  this->peek_ififo(flit_in, vcin, in_valid);
544 
545  // for each selected input, in case of valid header flit only, update
546  // out_dest[i][vcin[i]]
547  // side effect updating out_dest[x][vc] for each input port x with output
548  // port bitmap
549  compute_route(flit_in, vcin, in_valid);
550 
551  // Variable to hold valid input requests. Set valid[i][j] = 1 if input j
552  // is sending flit to output i
553  NVUINTW(num_ports) valid[num_ports], select[num_ports];
554  NVUINTW(log_num_ports) select_id[num_ports];
555 
556  // arbitrate for any top header flits on selected vcs
557  // outputs:
558  // valid[x] - bitmap of valid input ports to address output port x. valid
559  // means there is credit on output port(and vc), and no other packet in
560  // flight to that output vc
561  // select[x] - bitmap of selected input port (one hot) for output port x
562  // select_id[x] - selected input port for output port x
563  arbitration(flit_in, in_valid, vcin, valid, select, select_id);
564 
565  // decide which port is going to push data out
566  // side effect updating is_push[x] to indicate that output port x is going
567  // to push a flit out
568  NVUINTW(num_ports) is_popfifo = 0;
569  bool is_push[num_ports];
570 #pragma hls_unroll yes
571  for (int i = 0; i < num_ports;
572  i++) { // Iterating through output ports here
573  is_push[i] = false;
574  if (select[i] != 0) {
575  is_popfifo[select_id[i]] = 1;
576  is_push[i] = true;
577  // DCOUT(sc_time_stamp() << ": " << name() << " Port:" << i << "
578  // Select: "
579  // << select[i] << " select_id " << select_id[i]
580  // << " Valid:" << valid[i] << "PopFifo: " <<
581  // is_popfifo[select_id[i]] << endl);
582  }
583  }
584 
585 // pop input fifos and prepare credits to be returned to sources
586 #pragma hls_unroll yes
587  for (int i = 0; i < num_ports; i++) { // Iterating over inputs here
588  if (is_popfifo[i] == 1) {
589  this->ififo.incrHead(i * num_vchannels + vcin[i]);
590  // DCOUT(sc_time_stamp() << ": " << name() << " Popped FIFO of port-"
591  // << i
592  // << " VC-" << vcin[i] << endl);
593  this->credit_send[i * num_vchannels + vcin[i]]++;
594  NVHLS_ASSERT_MSG(this->credit_send[i * num_vchannels + vcin[i]] <= BaseClass::buffersize, "Total credits cannot be larger than buffer size");
595  }
596  }
597 
598  // fill_ififo();
599  this->send_credit();
600  NVUINTW(log_num_vchannels) vcout[num_ports];
601 
602  this->crossbar_traversal(flit_in, is_push, select_id, vcin, vcout);
603 
604  // sends out flits to be sent
605  // side effect: updating is_get_new_packet[x] when tail goes through port
606  // x
607  // and out_stall when push_nb fails
608  flit_output(is_push, vcout);
609  }
610 };
611 
612 #endif //__WHVCROUTER_H__
type1 set_slc(type1 X, type2 Y, const unsigned int i)
Function that replaces slice of bits.
Definition: nvhls_int.h:387
#define DCOUT(x)
Definition: hls_globals.h:72
type2 leading_ones(type1 X)
LeadingOne Detector.
Definition: nvhls_int.h:561
Wormhole Router with virtual channels.
Definition: WHVCRouter.h:257
Compute index width of a constant.
Definition: nvhls_int.h:285
#define NVHLS_ASSERT_MSG(X, MSG)
Definition: nvhls_assert.h:116
#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&#39;s reset_signal_is() and async_reset_signal_is() so that ENABLE_SYNC_RESET can select type.
Definition: nvhls_module.h:39
#define NVUINTW(width)
Definition: nvhls_types.h:35