MatchLib
ReorderBuf.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 #ifndef __REORDERBUF_H__
18 #define __REORDERBUF_H__
19 
20 #include <fifo.h>
21 #include <nvhls_types.h>
22 #include <mem_array.h>
23 #include <nvhls_assert.h>
24 
67 template <typename Data, unsigned int Depth, unsigned int InFlight>
68 class ReorderBuf {
69 
70 public:
71  ReorderBuf(): idrep(0)
72  {
73  }
74 
75  typedef sc_uint<nvhls::index_width<InFlight>::val> Id;
76 
77 protected:
79  typedef FIFO<bool, Depth> VBits;
80  VBits vbits;
81 
82  typedef NVUINTW(InFlight) IdRepository;
83 
84  IdRepository idrep;
85  typedef typename VBits::FifoIdx EntryNum;
86 
88  Id2Entry id2entry;
89 
90  bool get_next_avail_id(Id& id, IdRepository& id_repository)
91  {
92  #pragma hls_unroll yes
93  for (int i=0; i<static_cast<int>(InFlight); ++i)
94  {
95  if (id_repository[i]==0)
96  {
97  id = i;
98  id_repository[i]=1;
99  return true;
100  }
101  }
102  return false;
103  }
104 
105 public:
106  bool canAcceptRequest()
107  {
108  return ((idrep != static_cast<IdRepository>(~0)) && !vbits.isFull());
109  }
110 
111  Id addRequest()
112  {
113  Id id;
114  bool success = get_next_avail_id(id, idrep);
115  NVHLS_ASSERT_MSG(success, "get_next_avail_id unsuccessful");
116 
117  id2entry.write(static_cast<typename Id2Entry::LocalIndex>(id), 0, vbits.get_tail());
118  vbits.push(false);
119 
120  return id;
121  }
122 
123  bool topResponseReady()
124  {
125  if (isEmpty()){
126  return false;
127  } else {
128  return vbits.peek();
129  }
130  }
131 
132  void addResponse(const Id& id, const Data& data)
133  {
134  EntryNum entryNum = id2entry.read(static_cast<typename Id2Entry::LocalIndex>(id), 0);
135  storage.write(entryNum, 0, data);
136  vbits.fifo_body.write(static_cast<typename VBits::FifoIdx>(entryNum), 0, true);
137  NVHLS_ASSERT_MSG(idrep[static_cast<int>(id)] == 1, "idrep[id]!=1");
138  idrep[static_cast<int>(id)]=0;
139  }
140 
141  Data popResponse()
142  {
143  NVHLS_ASSERT_MSG(topResponseReady(),"topResponseNotReady");
144 
145  Data result = storage.read( vbits.get_head(), 0);
146  vbits.incrHead();
147 
148  return result;
149  }
150 
151  void reset()
152  {
153  vbits.reset();
154  idrep = 0;
155  }
156 
157  bool isEmpty()
158  {
159  return vbits.isEmpty();
160  }
161 
162 };
163 
164 #endif
Reorder Buffer that allows out-of-order writes to queue and in-order reads.
Definition: ReorderBuf.h:68
#define NVHLS_ASSERT_MSG(X, MSG)
Definition: nvhls_assert.h:135