MatchLib
Loading...
Searching...
No Matches
Scratchpad.h
1/*
2 * Copyright (c) 2016-2024, 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#ifndef SC_SCRATCHPAD
17#define SC_SCRATCHPAD
18
19
20#include <cstdio>
21#include <systemc.h>
22#include <nvhls_int.h>
23#include <nvhls_types.h>
24#include <hls_globals.h>
25#include <nvhls_connections.h>
26#include <crossbar.h>
27#include <mem_array.h>
28
29#include <Scratchpad/ScratchpadTypes.h>
30
100template <typename T, int N, int CAPACITY_IN_WORDS>
102 public:
103
104 static const int ADDR_WIDTH = nvhls::nbits<CAPACITY_IN_WORDS - 1>::val;
105 //------------Constants Here---------------------------
106 // Derived parameters
107 static const int NBANKS_LOG2 = nvhls::nbits<N - 1>::val;
108
109 //------------Local typedefs---------------------------
110 typedef NVUINTW(NBANKS_LOG2) bank_sel_t;
111 typedef NVUINTW(ADDR_WIDTH - NBANKS_LOG2) bank_addr_t;
112 struct bank_req_t {
113 bank_addr_t addr;
114 T wdata;
115 };
117 typedef cli_rsp_t<T, N> rsp_t;
118
119 //------------Local Variables Here---------------------
121 bank_req_t input_reqs[N];
122 bool input_reqs_valid[N];
123 bank_req_t bank_reqs[N];
124 bool bank_reqs_valid[N];
125 T bank_rsps_data[N];
126 bool bank_rsps_valid[N];
127 bool load_rsps_valid[N];
128 cli_rsp_t<T, N> load_rsp;
129 bank_sel_t bank_src_lane[N];
130 bank_sel_t bank_dst_lane[N];
131
132 void store(req_t req) {
133 rsp_t load_rsp;
134 req.opcode = STORE;
135 load_store(req, load_rsp);
136 }
137
138 rsp_t load(req_t req) {
139 rsp_t load_rsp;
140 req.opcode = LOAD;
141 load_store(req, load_rsp);
142 return load_rsp;
143 }
144
145 void load_store(req_t curr_cli_req, rsp_t& load_rsp) {
146 bool is_load;
147
148 is_load = (curr_cli_req.opcode == LOAD);
149
150 // Pre-process the bank requests and compute lane selects from addresses
151 #pragma hls_unroll yes
152 for (int i = 0; i < N; i++) {
153 // For each request, figure out the target bank and update its bank_req
154 // fields
155 bank_sel_t bank_sel;
156 bank_sel = nvhls::get_slc<NBANKS_LOG2>(curr_cli_req.addr[i], 0);
157 bank_src_lane[bank_sel] = i;
158
159 // Save the lane->bank mapping for the response xbar
160 bank_dst_lane[i] = bank_sel;
161
162#ifndef __SYNTHESIS__
163 for (int j=0; j < i; j++) {
164 if (bank_dst_lane[j] == bank_sel) {
165 std::cout << "Conflicting bank requests indexes are: "
166 << std::dec << i << " " << j << "\n";
167 }
168 NVHLS_ASSERT_MSG(bank_dst_lane[j] != bank_sel, "conflicting bank requests");
169 }
170#endif
171
172 // Convert from curr_cli_req to internal format
173 input_reqs_valid[i] = (curr_cli_req.valids[i] == true);
174 input_reqs[i].addr = nvhls::get_slc<ADDR_WIDTH - NBANKS_LOG2>(
175 curr_cli_req.addr[i], NBANKS_LOG2);
176 if (!is_load)
177 input_reqs[i].wdata = curr_cli_req.data[i];
178 }
179
180 // Bank request crossbar
181 crossbar<bank_req_t, N, N>(input_reqs, input_reqs_valid, bank_src_lane,
182 bank_reqs, bank_reqs_valid);
183
184 // Loop over scratchpad banks, execute load or store on each bank
185 #pragma hls_unroll yes
186 for (int i = 0; i < N; i++) {
187 if ((bank_reqs_valid[i] == true) && is_load) {
188 bank_rsps_valid[i] = true;
189 bank_rsps_data[i] = banks.read(bank_reqs[i].addr, i);
190 } else if ((bank_reqs_valid[i] == true) && !is_load) {
191 banks.write(bank_reqs[i].addr, i, bank_reqs[i].wdata);
192 bank_rsps_valid[i] = false;
193 } else {
194 bank_rsps_valid[i] = false;
195 }
196 }
197
198 // Bank response crossbar
199 crossbar<T, N, N>(bank_rsps_data, bank_rsps_valid, bank_dst_lane,
200 load_rsp.data, load_rsps_valid);
201 #pragma hls_unroll yes
202 for (int i = 0; i < N; i++) {
203 load_rsp.valids[i] = load_rsps_valid[i]; // sc_lv to bool conversion
204 }
205 }
206};
207
258template <typename T, int N, int CAPACITY_IN_WORDS>
259class Scratchpad : public sc_module {
260 public:
261 static const int ADDR_WIDTH = nvhls::nbits<CAPACITY_IN_WORDS - 1>::val;
262 sc_in_clk clk;
263 sc_in<bool> rst;
264 Connections::In<cli_req_t<T, ADDR_WIDTH, N> > cli_req;
265 Connections::Out<cli_rsp_t<T, N> > cli_rsp;
266
267 //------------Constants Here---------------------------
268 // Derived parameters
269 static const int NBANKS_LOG2 = nvhls::nbits<N - 1>::val;
270
271 //------------Local typedefs---------------------------
272 typedef NVUINTW(NBANKS_LOG2) bank_sel_t;
273 typedef NVUINTW(ADDR_WIDTH - NBANKS_LOG2) bank_addr_t;
274 struct bank_req_t {
275 bank_addr_t addr;
276 T wdata;
277 };
279 typedef cli_rsp_t<T, N> rsp_t;
280
282
283 //----------- Constructor -----------------------------
284 // -Allocate and declare sub-modules
285 // -Declare all SC_METHODs and SC_THREADs
286 SC_HAS_PROCESS(Scratchpad);
287 Scratchpad(sc_module_name name_) : sc_module(name_) {
288 SC_THREAD(run);
289 sensitive << clk.pos();
291 //DCOUT("Capacity (words): " << CAPACITY_IN_WORDS << ", banks: " << N
292 // << ", addr width: " << ADDR_WIDTH << endl);
293 }
294
295 void run() {
296
297 // Reset behavior
298 cli_req.Reset();
299 cli_rsp.Reset();
300 wait();
301
302 #pragma hls_pipeline_init_interval 1
303 #pragma pipeline_stall_mode flush
304 while (true) {
305
306 bool is_load;
307 is_load = false;
308
309 req_t curr_cli_req;
310 rsp_t load_rsp;
311
312 // Read client request
313 // (Implemented as a blocking read since there's no other work to do if no
314 // valid request in the channel)
315
316 curr_cli_req = cli_req.Pop();
317
318 scratchpad_class.load_store(curr_cli_req, load_rsp);
319 is_load = (curr_cli_req.opcode == LOAD);
320
321 // Write client responses
322 if (is_load) {
323 cli_rsp.Push(load_rsp);
324 }
325
326 wait();
327 }
328 }
329};
330
395template <typename WORD_TYPE, int NUM_BANKS, int CAPACITY_IN_WORDS>
397 typedef WORD_TYPE word_type;
398 static const int num_banks = NUM_BANKS;
399 static const int capacity_in_words = CAPACITY_IN_WORDS;
400
401 static const int num_inputs = num_banks; // Note: for Scratchpad num_banks must equal num_inputs
402 static const int words_per_bank = capacity_in_words / num_banks;
403
404
407
408 typedef typename mem_class_t::req_t base_req_t;
409 typedef typename mem_class_t::rsp_t base_rsp_t;
410
411 static const int addr_width = mem_class_t::ADDR_WIDTH;
412 static const int bank_sel_width = mem_class_t::NBANKS_LOG2;
413 typedef typename mem_class_t::bank_sel_t bank_sel_t;
414
415 typedef ac_int<addr_width, false> addr_t;
416
417 struct scratchpad_req_t : public base_req_t {
418 // Note that it is important to initialize all valids to false since unitialized valids
419 // may lead to pre-HLS versus post-HLS simulation mismatches.
420 // This initialization should probably be moved into the base class..
422 for (unsigned i=0; i < num_inputs; i++)
423 this->valids[i] = 0;
424 }
425
426 void set(unsigned idx, addr_t _addr, word_type _data=0) {
427 sc_assert(idx < num_inputs);
428 this->valids[idx] = 1;
429 this->addr[idx] = _addr;
430 this->data[idx] = _data;
431 }
432 };
433};
434
435#endif
Parameterized banked scratchpad memory implemented as a C++ class (i.e. not a SystemC module)
Definition Scratchpad.h:101
Parameterized banked scratchpad memory implemented as a SystemC module.
Definition Scratchpad.h:259
Abstract Memory Class.
Definition mem_array.h:83
#define NVHLS_ASSERT_MSG(X, MSG)
#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
#define NVHLS_NEG_RESET_SIGNAL_IS(port)
ENABLE_SYNC_RESET define: Select synchronous or asynchronous reset.
Traits class for Scratchpad and ScratchpadClass.
Definition Scratchpad.h:396
Compute number of bits to represent a constant.
Definition nvhls_int.h:118