MatchLib
All Classes Namespaces Files Functions Modules Pages
Arbiter.h
1/*
2 * Copyright (c) 2017-2020, 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
18#ifndef __ARBITER_H__
19#define __ARBITER_H__
20
21#include <systemc.h>
22#include <nvhls_int.h>
23#include <nvhls_assert.h>
24
25enum arbiter_type { Static, Roundrobin };
26
27
60template <unsigned int size_, arbiter_type ArbiterType = Roundrobin>
61class Arbiter {
62 public:
63 typedef NVUINTW(size_) Mask;
64
65 protected:
66 enum _ {
67 UNROLLED_SIZE = 2 * size_ - 1,
68 log_unrolled_size = nvhls::log2_ceil<UNROLLED_SIZE>::val,
70 //-1 because there is no reason to duplicate LSB
71 };
72
73 typedef NVUINTW(UNROLLED_SIZE) UnrolledMask;
74 Mask next;
75
76 public:
77 Arbiter() { reset(); };
78
79 // reset the state
80 inline void reset() { next = ~static_cast<Mask>(0); }
81
82 // picks the next element
83 // input : valid mask
84 // output : select mask
85 // side effect : updates internal state of next select
86 Mask pick(const Mask& valid) {
87 if (valid == 0) {
88 return 0;
89 }
90 UnrolledMask unrolled_valid = static_cast<UnrolledMask>(0);
91 unrolled_valid =
92 nvhls::set_slc(unrolled_valid, nvhls::get_slc<size_ - 1>(valid, 1), 0) |
93 nvhls::set_slc(unrolled_valid, valid, size_ - 1);
94
95 UnrolledMask unrolled_next = static_cast<UnrolledMask>(0);
96 NVUINTW(size_ - 1) temp = ~static_cast<NVUINTW(size_ - 1)>(0);
97 unrolled_next = nvhls::set_slc(unrolled_next, next, size_ - 1) |
98 nvhls::set_slc(unrolled_next, temp, 0);
99
100 UnrolledMask priority(unrolled_next & unrolled_valid);
101
102 NVUINTW(log_unrolled_size) first_one_idx, num_zeros;
103 UnrolledMask unrolled_choice = static_cast<UnrolledMask>(0);
104
105 Mask choice = static_cast<Mask>(0);
106 Mask choice_temp = static_cast<Mask>(0);
107 if (priority != 0) {
108 first_one_idx = nvhls::leading_ones<UNROLLED_SIZE, UnrolledMask,
109 NVUINTW(log_unrolled_size)>(priority);
110 unrolled_choice[first_one_idx] = 1;
111 choice_temp[0] = unrolled_choice[size_ - 1];
112 NVUINTW(size_ - 1)
113 temp2 = (nvhls::get_slc<UNROLLED_SIZE - size_>(unrolled_choice, size_)) |
114 (nvhls::get_slc<size_ - 1>(unrolled_choice, 0));
115 choice = nvhls::set_slc(choice_temp, temp2, 1);
116
117 if (first_one_idx != (size_ - 1)) {
118 next[size_ - 1] = 0;
119#pragma hls_unroll yes
120 for (unsigned i = size_ - 2; i > 0; --i) {
121 next[i] = next[i + 1] | choice[i + 1];
122 }
123 } else {
124 next = ~static_cast<Mask>(0);
125 }
126 }
127 // assert valid!=0 => (valid&choice)!=0
128 //NVHLS_ASSERT_MSG(valid!=0, "Arbiter input is zero and output is non-zero");
129 return choice;
130 }
131};
132
137template<>
138class Arbiter<1, Roundrobin> {
139 public:
140 typedef NVUINT1 Mask;
141
142 public:
143 Arbiter() { reset(); };
144
145 // reset the state
146 inline void reset() { }
147
148 // picks the next element
149 Mask pick(const Mask& valid) {
150 if (valid !=0) {
151 return static_cast<Mask>(1);
152 } else {
153 return static_cast<Mask>(0);
154 }
155 }
156};
157
158
166template <unsigned int size_>
167class Arbiter<size_, Static> {
168 public:
169 typedef NVUINTW(size_) Mask;
170
171 protected:
172 enum _ { log_size = nvhls::log2_ceil<size_>::val };
173
174 public:
175 // picks the next element
176 // input : valid mask
177 // output : select mask
178 // side effect : updates internal state of next select
179 Mask pick(const Mask& valid) {
180 Mask select = static_cast<Mask>(0);
181 NVUINTW(log_size) first_one_idx;
182 if (valid != 0) {
183 first_one_idx =
185 select[first_one_idx] = 1;
186 }
187 return select;
188 }
189};
190
191
192#endif // __ARBITER_H__
A generalized implementation of generic n-way roundrobin arbiter.
Definition Arbiter.h:61
#define NVUINTW(width)
Definition nvhls_types.h:35
nvhls_t< W >::nvuint_t get_slc(type X, const unsigned int i)
Function that returns slice of bits.
Definition nvhls_int.h:437
type1 set_slc(type1 X, type2 Y, const unsigned int i)
Function that replaces slice of bits.
Definition nvhls_int.h:387
type2 leading_ones(type1 X)
LeadingOne Detector.
Definition nvhls_int.h:561
Compute Celing of log2 of a constant.
Definition nvhls_int.h:174