16 #ifndef ARBITRATED_SCRATCHPAD_H 17 #define ARBITRATED_SCRATCHPAD_H 19 #include <nvhls_int.h> 20 #include <nvhls_types.h> 21 #include <nvhls_message.h> 24 #include <mem_array.h> 25 #include <arbitrated_crossbar.h> 26 #include <ArbitratedScratchpad/ArbitratedScratchpadTypes.h> 55 template <
typename DataType,
unsigned int CapacityInBytes,
56 unsigned int NumInputs,
unsigned int NumBanks,
57 unsigned int InputQueueLen>
63 static const int addr_width =
nvhls::nbits<CapacityInBytes - 1>::val;
64 static const int log2_nbanks =
nvhls::nbits<NumBanks - 1>::val;
65 static const int log2_inputs =
nvhls::nbits<NumInputs - 1>::val;
68 typedef NVUINTW(log2_nbanks) bank_sel_t;
69 typedef NVUINTW(addr_width - log2_nbanks) bank_addr_t;
70 typedef NVUINTW(log2_inputs) input_sel_t;
76 input_sel_t input_chan;
77 static const int width = 1 + addr_width-log2_nbanks + Wrapped<DataType>::width + log2_inputs;
79 template <
unsigned int Size>
80 void Marshall(Marshaller<Size>& m) {
90 static const int width = 1 + Wrapped<DataType>::width;
92 template <
unsigned int Size>
93 void Marshall(Marshaller<Size>& m) {
110 void compute_bank_request(req_t &curr_cli_req,
bank_req_t bank_req[NumInputs],
111 bank_sel_t bank_sel[NumInputs],
112 bool bank_req_valid[NumInputs]) {
115 #pragma hls_unroll yes 116 for (
unsigned in_chan = 0; in_chan < NumInputs; in_chan++) {
120 nvhls::get_slc<log2_nbanks>(curr_cli_req.addr[in_chan], 0);
123 bank_req[in_chan].do_store = (curr_cli_req.valids[in_chan] ==
true) &&
124 (curr_cli_req.type.val == CLITYPE_T::STORE);
125 bank_req[in_chan].addr =
nvhls::get_slc<addr_width - log2_nbanks>(
126 curr_cli_req.addr[in_chan], log2_nbanks);
127 if (bank_req[in_chan].do_store) {
128 bank_req[in_chan].wdata = curr_cli_req.data[in_chan];
132 input_sel_t input_idx = in_chan;
133 bank_req[in_chan].input_chan = input_idx;
136 bank_req_valid[in_chan] = (curr_cli_req.valids[in_chan] ==
true);
140 void banks_load_store(
bank_req_t bank_req[NumBanks],
141 bool bank_req_valid[NumBanks],
143 #pragma hls_unroll yes 144 for (
unsigned bank = 0; bank < NumBanks; bank++) {
145 if (bank_req_valid[bank] ==
true) {
146 if (!bank_req[bank].do_store) {
147 bank_rsp[bank].valid =
true;
148 bank_rsp[bank].rdata = banks.read(bank_req[bank].addr, bank);
150 banks.write(bank_req[bank].addr, bank, bank_req[bank].wdata);
151 bank_rsp[bank].valid =
false;
154 bank_rsp[bank].valid =
false;
162 void reset() { request_xbar.reset(); }
164 #ifdef HLS_ALGORITHMICC 165 void load_store(req_t &curr_cli_req, rsp_t &load_rsp,
166 bool input_ready[NumInputs]) {
168 bank_sel_t bank_sel[NumInputs];
169 bool bank_req_valid[NumInputs];
171 compute_bank_request(curr_cli_req, bank_req, bank_sel, bank_req_valid);
173 void load_store(
bank_req_t bank_req[NumInputs],
174 bank_sel_t bank_sel[NumInputs],
175 bool bank_req_valid[NumInputs],
176 rsp_t &load_rsp,
bool input_ready[NumInputs]) {
178 DCOUT(
"\tinputs:" << endl);
179 for (
unsigned i = 0; i < NumInputs; ++i) {
180 DCOUT(
"\t" << i <<
" :" 181 <<
" valid=" << bank_req_valid[i]
182 <<
" select=" << bank_sel[i]
183 <<
" addr=" << bank_req[i].addr
184 <<
" wdata=" << bank_req[i].wdata
185 <<
" load=" << !bank_req[i].do_store
186 <<
" store=" << bank_req[i].do_store
187 <<
" input=" << bank_req[i].input_chan << endl);
189 DCOUT(
"\t------" << endl);
192 bool bank_req_winner_valid[NumBanks];
193 request_xbar.
run(bank_req, bank_sel, bank_req_valid, bank_req_winner,
194 bank_req_winner_valid, input_ready);
196 DCOUT(
"\t\tbank winner transactions:" << endl);
197 for (
unsigned i = 0; i < NumBanks; ++i) {
198 DCOUT(
"\t\t" << i <<
" :" 199 <<
" valid=" << bank_req_winner_valid[i]
200 <<
" addr=" << bank_req_winner[i].addr
201 <<
" wdata=" << bank_req_winner[i].wdata
202 <<
" load=" << !bank_req_winner[i].do_store
203 <<
" store=" << bank_req_winner[i].do_store
204 <<
" input=" << bank_req_winner[i].input_chan << endl);
206 DCOUT(
"\t\t------" << endl);
207 DCOUT(
"\t\tinput_ready:" << endl);
208 for (
unsigned i = 0; i < NumInputs; ++i) {
209 DCOUT(
"\t\t" << i <<
" : ready=" << input_ready[i] << endl);
211 DCOUT(
"\t\t------" << endl);
214 banks_load_store(bank_req_winner, bank_req_winner_valid, bank_rsp);
217 DataType data_in[NumBanks];
218 bool valid_in[NumBanks];
219 bank_sel_t source[NumInputs];
220 bool valid_src[NumInputs];
221 DataType data_out[NumInputs];
222 bool valid_out[NumInputs];
224 #pragma hls_unroll yes 225 for (
unsigned out = 0; out < NumInputs; out++) {
226 valid_src[out] =
false;
229 #pragma hls_unroll yes 230 for (
unsigned bank = 0; bank < NumBanks; bank++) {
231 valid_in[bank] = bank_rsp[bank].valid;
232 data_in[bank] = bank_rsp[bank].rdata;
233 if (bank_rsp[bank].valid) {
234 source[bank_req_winner[bank].input_chan] = bank;
235 valid_src[bank_req_winner[bank].input_chan] =
true;
239 crossbar<DataType, NumBanks, NumInputs>(data_in, valid_in, source,
240 valid_src, data_out, valid_out);
242 #pragma hls_unroll yes 243 for (
unsigned out = 0; out < NumInputs; out++) {
244 load_rsp.valids[out] = valid_out[out];
245 load_rsp.data[out] = data_out[out];
251 #endif // end ARBITRATED_SCRATCHPAD_H
nvhls_t< W >::nvuint_t get_slc(type X, const unsigned int i)
Function that returns slice of bits.
Compute number of bits to represent a constant.
void run(DataType data_in[NumInputs], OutputIdx dest_in[NumInputs], bool valid_in[NumInputs], DataType data_out[NumOutputs], bool valid_out[NumOutputs], bool ready[NumInputs], InputIdx source[NumOutputs])
Top-Level function for Arbitrated Crossbar.
Scratchpad Memories with arbitration and queuing.
Crossbar with conflict arbitration and input queuing.