PandA-2024.02
fu_binding_cs.cpp
Go to the documentation of this file.
1 /*
2  *
3  * _/_/_/ _/_/ _/ _/ _/_/_/ _/_/
4  * _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/
5  * _/_/_/ _/_/_/_/ _/ _/_/ _/ _/ _/_/_/_/
6  * _/ _/ _/ _/ _/ _/ _/ _/ _/
7  * _/ _/ _/ _/ _/ _/_/_/ _/ _/
8  *
9  * ***********************************************
10  * PandA Project
11  * URL: http://panda.dei.polimi.it
12  * Politecnico di Milano - DEIB
13  * System Architectures Group
14  * ***********************************************
15  * Copyright (c) 2016-2024 Politecnico di Milano
16  *
17  * This file is part of the PandA framework.
18  *
19  * The PandA framework is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program. If not, see <http://www.gnu.org/licenses/>.
31  *
32  */
39 #include "fu_binding_cs.hpp"
40 
41 #include "Parameter.hpp"
42 #include "custom_map.hpp"
43 #include "custom_set.hpp"
44 #include "dbgPrintHelper.hpp"
45 #include "hls.hpp"
46 #include "hls_device.hpp"
47 #include "hls_manager.hpp"
48 #include "math_function.hpp"
49 #include "memory.hpp"
50 #include "memory_cs.hpp"
51 #include "omp_functions.hpp"
52 #include "reg_binding_cs.hpp"
53 #include "structural_manager.hpp"
54 #include "structural_objects.hpp"
55 #include "technology_manager.hpp"
56 #include "utility.hpp"
57 
58 #include <cmath>
59 #include <string>
60 
61 fu_binding_cs::fu_binding_cs(const HLS_managerConstRef _HLSMgr, const unsigned int _function_id,
62  const ParameterConstRef _parameters)
63  : fu_binding(_HLSMgr, _function_id, _parameters)
64 {
65  debug_level = _parameters->get_class_debug_level(GET_CLASS(*this));
66 }
67 
69 
70 void fu_binding_cs::add_to_SM(const HLS_managerRef HLSMgr, const hlsRef HLS, structural_objectRef clock_port,
71  structural_objectRef reset_port)
72 {
73  auto omp_functions = GetPointer<OmpFunctions>(HLSMgr->Rfuns);
74  if(omp_functions->kernel_functions.find(HLS->functionId) != omp_functions->kernel_functions.end())
75  {
76  instantiate_component_kernel(HLSMgr, HLS, clock_port, reset_port);
77  }
78  fu_binding::add_to_SM(HLSMgr, HLS, clock_port, reset_port);
79  if(omp_functions->kernel_functions.find(HLS->functionId) != omp_functions->kernel_functions.end())
80  {
82  }
83  else if(omp_functions->atomic_functions.find(HLS->functionId) != omp_functions->atomic_functions.end() ||
84  omp_functions->parallelized_functions.find(HLS->functionId) != omp_functions->parallelized_functions.end())
85  {
86  connect_selector(HLS);
88  }
89 }
90 
92  structural_objectRef clock_port, structural_objectRef reset_port)
93 {
94  const structural_managerRef SM = HLS->datapath;
95  const structural_objectRef circuit = SM->get_circ();
96  std::string scheduler_model = "scheduler";
97  std::string scheduler_name = "scheduler_kernel";
98  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - Start adding scheduler");
99  std::string sche_library = HLS->HLS_D->get_technology_manager()->get_library(scheduler_model);
101  scheduler_name, scheduler_model, sche_library, circuit, HLS->HLS_D->get_technology_manager());
102  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - Added Scheduler");
103 
104  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Starting setting parameter scheduler!");
105  GetPointer<module>(scheduler_mod)
106  ->SetParameter("NUM_TASKS", STR(parameters->getOption<unsigned int>(OPT_context_switch)));
107  auto addr_acc = ceil_log2(parameters->getOption<unsigned long long>(OPT_num_accelerators));
108  if(!addr_acc)
109  {
110  addr_acc = 1;
111  }
112  GetPointer<module>(scheduler_mod)->SetParameter("ADDR_ACC", STR(addr_acc));
113  GetPointer<module>(scheduler_mod)->SetParameter("KERN_NUM", "KERN_NUM"); // taken from datapath
114  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Parameter scheduler setted!");
115 
116  structural_objectRef clock_scheduler = scheduler_mod->find_member(CLOCK_PORT_NAME, port_o_K, scheduler_mod);
117  SM->add_connection(clock_port, clock_scheduler);
118  PRINT_DBG_MEX(DEBUG_LEVEL_VERBOSE, debug_level, " - Added clock sche");
119 
120  structural_objectRef reset_scheduler = scheduler_mod->find_member(RESET_PORT_NAME, port_o_K, scheduler_mod);
121  SM->add_connection(reset_port, reset_scheduler);
122  PRINT_DBG_MEX(DEBUG_LEVEL_VERBOSE, debug_level, " - Added reset sche");
123 
124  structural_objectRef done_scheduler = scheduler_mod->find_member(DONE_SCHEDULER, port_o_K, scheduler_mod);
125  structural_objectRef done_datapath = circuit->find_member(DONE_SCHEDULER, port_o_K, circuit);
126  SM->add_connection(done_datapath, done_scheduler);
127  PRINT_DBG_MEX(DEBUG_LEVEL_VERBOSE, debug_level, " - Added done sche");
128 
129  structural_objectRef start_port_scheduler =
130  scheduler_mod->find_member(STR(START_PORT_NAME) + "_task", port_o_K, scheduler_mod);
131  structural_objectRef start_port_datapath = circuit->find_member(STR(START_PORT_NAME) + "_task", port_o_K, circuit);
132  SM->add_connection(start_port_datapath, start_port_scheduler);
133  PRINT_DBG_MEX(DEBUG_LEVEL_VERBOSE, debug_level, " - Added start sche");
134 
135  structural_objectRef task_pool_end_scheduler =
136  scheduler_mod->find_member(STR(TASKS_POOL_END), port_o_K, scheduler_mod);
137  structural_objectRef task_pool_end_datapath = circuit->find_member(STR(TASKS_POOL_END), port_o_K, circuit);
138  SM->add_connection(task_pool_end_datapath, task_pool_end_scheduler);
139  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - Added task_pool_end sche");
140 
141  structural_objectRef done_request_scheduler = scheduler_mod->find_member(STR(DONE_REQUEST), port_o_K, scheduler_mod);
142  structural_objectRef done_request_datapath = circuit->find_member(STR(DONE_REQUEST), port_o_K, circuit);
143  SM->add_connection(done_request_scheduler, done_request_datapath);
144  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - Added done_request sche");
145 
146  resize_scheduler_ports(HLSMgr, scheduler_mod);
147 }
148 
150 {
151  for(unsigned int j = 0; j < GetPointer<module>(scheduler_mod)->get_in_port_size(); j++) // resize input port
152  {
153  structural_objectRef port_i = GetPointer<module>(scheduler_mod)->get_in_port(j);
154  if(GetPointer<port_o>(port_i)->get_is_memory())
155  {
156  resize_dimension_bus_port(HLSMgr, port_i);
157  }
158  }
159  for(unsigned int j = 0; j < GetPointer<module>(scheduler_mod)->get_out_port_size(); j++) // resize output port
160  {
161  structural_objectRef port_i = GetPointer<module>(scheduler_mod)->get_out_port(j);
162  if(GetPointer<port_o>(port_i)->get_is_memory())
163  {
164  resize_dimension_bus_port(HLSMgr, port_i);
165  }
166  }
167 }
168 
170 {
171  auto bus_data_bitsize = HLSMgr->Rmem->get_bus_data_bitsize();
172  auto bus_addr_bitsize = HLSMgr->get_address_bitsize();
173  auto bus_size_bitsize = HLSMgr->Rmem->get_bus_size_bitsize();
174  auto bus_tag_bitsize = GetPointer<memory_cs>(HLSMgr->Rmem)->get_bus_tag_bitsize();
175 
176  if(GetPointer<port_o>(port)->get_is_data_bus())
177  {
178  port->type_resize(bus_data_bitsize);
179  }
180  else if(GetPointer<port_o>(port)->get_is_addr_bus())
181  {
182  port->type_resize(bus_addr_bitsize);
183  }
184  else if(GetPointer<port_o>(port)->get_is_size_bus())
185  {
186  port->type_resize(bus_size_bitsize);
187  }
188  else if(GetPointer<port_o>(port)->get_is_tag_bus())
189  {
190  port->type_resize(bus_tag_bitsize);
191  }
192 }
193 
195 {
196  const structural_managerRef SM = HLS->datapath;
197  const structural_objectRef circuit = SM->get_circ();
198  structural_objectRef port_selector_datapath = circuit->find_member(SELECTOR_REGISTER_FILE, port_o_K, circuit);
199  for(unsigned int i = 0; i < GetPointer<module>(circuit)->get_internal_objects_size(); i++)
200  {
201  structural_objectRef curr_gate = GetPointer<module>(circuit)->get_internal_object(i);
202  const structural_objectRef port_selector_module =
203  curr_gate->find_member(STR(SELECTOR_REGISTER_FILE), port_o_K, curr_gate);
204  if(port_selector_module != nullptr)
205  {
206  SM->add_connection(port_selector_datapath, port_selector_module);
207  }
208  }
209 }
210 
212 {
213  const structural_managerRef SM = HLS->datapath;
214  const structural_objectRef circuit = SM->get_circ();
215  auto num_slots =
216  ceil_log2(parameters->getOption<unsigned long long int>(OPT_context_switch)); // resize selector-port
217  if(!num_slots)
218  {
219  num_slots = 1;
220  }
222  structural_type_descriptorRef(new structural_type_descriptor("bool", static_cast<unsigned>(num_slots)));
223 
224  structural_objectRef scheduler_mod = circuit->find_member("scheduler_kernel", component_o_K, circuit);
225  structural_objectRef port_selector =
226  scheduler_mod->find_member(STR(SELECTOR_REGISTER_FILE), port_o_K, scheduler_mod);
227  port_selector->type_resize(static_cast<unsigned>(num_slots));
228  structural_objectRef selector_regFile_scheduler =
229  scheduler_mod->find_member(STR(SELECTOR_REGISTER_FILE), port_o_K, scheduler_mod);
230  structural_objectRef selector_regFile_datapath =
231  circuit->find_member(STR(SELECTOR_REGISTER_FILE), port_o_K, circuit);
232  structural_objectRef selector_regFile_sign =
233  SM->add_sign(STR(SELECTOR_REGISTER_FILE) + "_signal", circuit, port_type);
234  SM->add_connection(selector_regFile_scheduler, selector_regFile_sign);
235  SM->add_connection(selector_regFile_sign, selector_regFile_datapath);
236 
237  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - Added selector");
238  for(unsigned int i = 0; i < GetPointer<module>(circuit)->get_internal_objects_size(); i++)
239  {
240  structural_objectRef curr_gate = GetPointer<module>(circuit)->get_internal_object(i);
241  if(curr_gate->get_id() != "scheduler_kernel")
242  {
243  const structural_objectRef port_selector_module =
244  curr_gate->find_member(STR(SELECTOR_REGISTER_FILE), port_o_K, curr_gate);
245  if(port_selector_module != nullptr)
246  {
247  SM->add_connection(selector_regFile_sign, port_selector_module);
248  }
249  }
250  }
251  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - Connected register");
252 }
253 
255 {
256  const structural_managerRef SM = HLS->datapath;
257  const structural_objectRef circuit = SM->get_circ();
258  for(unsigned int i = 0; i < GetPointer<module>(circuit)->get_internal_objects_size(); i++)
259  {
260  structural_objectRef curr_gate = GetPointer<module>(circuit)->get_internal_object(i);
261  if(curr_gate->ExistsParameter("TAG_MEM_REQ"))
262  {
263  unsigned long long int tag_num = 0;
264  auto addr_tasks = ceil_log2(parameters->getOption<unsigned long long int>(OPT_context_switch));
265  if(!addr_tasks)
266  {
267  addr_tasks = 1;
268  }
269  auto addr_acc = ceil_log2(parameters->getOption<unsigned long long>(OPT_num_accelerators));
270  if(!addr_acc)
271  {
272  addr_acc = 1;
273  }
274  const auto bit_atomic = addr_tasks + addr_acc;
275  if(bit_atomic >= 64)
276  {
277  THROW_ERROR("too large tag value for TAG_MEM_REQ");
278  }
279  tag_num = 1ULL << bit_atomic;
280  curr_gate->SetParameter("TAG_MEM_REQ", STR(tag_num));
281  }
282  }
283 }
284 
286  const std::list<structural_objectRef>& memory_modules,
287  const structural_objectRef circuit, const hlsRef HLS,
288  unsigned int& _unique_id)
289 {
290  auto omp_functions = GetPointer<OmpFunctions>(HLSMgr->Rfuns);
291  if(omp_functions->kernel_functions.find(HLS->functionId) != omp_functions->kernel_functions.end())
292  {
293  manage_memory_port_kernel(SM, memory_modules, circuit, HLS, _unique_id);
294  }
295  else if(omp_functions->hierarchical_functions.find(HLS->functionId) != omp_functions->hierarchical_functions.end())
296  {
297  manage_memory_port_hierarchical(SM, memory_modules, circuit, HLS, _unique_id);
298  }
299  else
300  {
301  fu_binding::manage_memory_ports_parallel_chained(HLSMgr, SM, memory_modules, circuit, HLS, _unique_id);
302  }
303 }
304 
306  const std::list<structural_objectRef>& memory_modules,
307  const structural_objectRef circuit, const hlsRef HLS,
308  unsigned int& _unique_id)
309 {
310  std::map<structural_objectRef, std::list<structural_objectRef>, jms_sorter> primary_outs;
311  structural_objectRef cir_port;
312  structural_objectRef sche_port;
313  structural_objectRef scheduler = circuit->find_member("scheduler_kernel", component_o_K, circuit);
314  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - Connecting memory_port of scheduler");
315  for(unsigned int j = 0; j < GetPointer<module>(scheduler)->get_in_port_size();
316  j++) // connect input scheduler with datapath input
317  {
318  structural_objectRef port_i = GetPointer<module>(scheduler)->get_in_port(j);
319  std::string port_name = GetPointer<port_o>(port_i)->get_id();
320  if(GetPointer<port_o>(port_i)->get_is_memory() && GetPointer<port_o>(port_i)->get_is_global() &&
321  GetPointer<port_o>(port_i)->get_is_extern() && port_name.substr(0, 3) == "IN_")
322  {
323  cir_port =
324  circuit->find_member(port_name.erase(0, 3), port_i->get_kind(), circuit); // erase IN_ from port name
325  THROW_ASSERT(!cir_port || GetPointer<port_o>(cir_port), "should be a port or null");
326  if(!cir_port)
327  {
328  if(port_i->get_kind() == port_vector_o_K)
329  {
330  cir_port = SM->add_port_vector(port_name, port_o::IN, GetPointer<port_o>(port_i)->get_ports_size(),
331  circuit, port_i->get_typeRef());
332  }
333  else
334  {
335  cir_port = SM->add_port(port_name, port_o::IN, circuit, port_i->get_typeRef());
336  }
337  port_o::fix_port_properties(port_i, cir_port);
338  SM->add_connection(cir_port, port_i);
339  }
340  else
341  {
342  SM->add_connection(cir_port, port_i);
343  }
344  }
345  }
346 
347  for(const auto& memory_module : memory_modules) // connect scheduler with memory_modules
348  {
349  for(unsigned int j = 0; j < GetPointer<const module>(memory_module)->get_in_port_size(); j++)
350  {
351  structural_objectRef scheMemorySign;
352  structural_objectRef port_i = GetPointer<module>(memory_module)->get_in_port(j);
353  if(GetPointer<port_o>(port_i)->get_is_memory() && GetPointer<port_o>(port_i)->get_is_global() &&
354  GetPointer<port_o>(port_i)->get_is_extern())
355  {
356  std::string port_name = GetPointer<port_o>(port_i)->get_id();
357  sche_port = scheduler->find_member(port_name, port_i->get_kind(), scheduler);
358  scheMemorySign = GetPointer<port_o>(sche_port)->get_connected_signal();
359  if(scheMemorySign == nullptr)
360  {
361  scheMemorySign = SM->add_sign(port_name + "_signal", circuit, port_i->get_typeRef());
362  SM->add_connection(sche_port, scheMemorySign); // connect port scheduler with signal only one time
363  }
364  THROW_ASSERT(GetPointer<port_o>(sche_port), "should be a port");
365  SM->add_connection(scheMemorySign, port_i);
366  }
367  }
368 
369  for(unsigned int j = 0; j < GetPointer<const module>(memory_module)->get_out_port_size();
370  j++) // connect memory_modules out with scheduler by jms
371  {
372  structural_objectRef port_i = GetPointer<const module>(memory_module)->get_out_port(j);
373  if(GetPointer<port_o>(port_i)->get_is_memory() && !GetPointer<port_o>(port_i)->get_is_global() &&
374  !GetPointer<port_o>(port_i)->get_is_extern())
375  {
376  std::string port_name = GetPointer<port_o>(port_i)->get_id();
377  sche_port = scheduler->find_member(port_name, port_i->get_kind(), scheduler);
378  THROW_ASSERT(!sche_port || GetPointer<port_o>(sche_port), "should be a port");
379  if(std::find(primary_outs[sche_port].begin(), primary_outs[sche_port].end(), port_i) ==
380  primary_outs[sche_port].end())
381  {
382  primary_outs[sche_port].push_back(port_i);
383  }
384  }
385  }
386  }
387  join_merge_split(SM, HLS, primary_outs, circuit, _unique_id);
388 
389  for(unsigned int j = 0; j < GetPointer<module>(scheduler)->get_out_port_size();
390  j++) // connect scheduler out with datapath out
391  {
392  structural_objectRef port_i = GetPointer<module>(scheduler)->get_out_port(j);
393  std::string port_name = GetPointer<port_o>(port_i)->get_id();
394  if(GetPointer<port_o>(port_i)->get_is_memory() && !GetPointer<port_o>(port_i)->get_is_global() &&
395  !GetPointer<port_o>(port_i)->get_is_extern() && port_name.substr(0, 4) == "OUT_")
396  {
397  cir_port =
398  circuit->find_member(port_name.erase(0, 4), port_i->get_kind(), circuit); // erase OUT_ from port name
399  THROW_ASSERT(!cir_port || GetPointer<port_o>(cir_port), "should be a port or null");
400  if(!cir_port)
401  {
402  if(port_i->get_kind() == port_vector_o_K)
403  {
404  cir_port = SM->add_port_vector(port_name, port_o::OUT, GetPointer<port_o>(port_i)->get_ports_size(),
405  circuit, port_i->get_typeRef());
406  }
407  else
408  {
409  cir_port = SM->add_port(port_name, port_o::OUT, circuit, port_i->get_typeRef());
410  }
411  port_o::fix_port_properties(port_i, cir_port);
412  }
413  SM->add_connection(port_i, cir_port);
414  }
415  }
416  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - Connected memory_port of scheduler");
417 }
418 
420  const std::list<structural_objectRef>& memory_modules,
421  const structural_objectRef circuit, const hlsRef HLS,
422  unsigned int& _unique_id)
423 {
424  std::map<structural_objectRef, std::list<structural_objectRef>, jms_sorter> primary_outs;
425  structural_objectRef cir_port;
426  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - Start merging, splitting for hierarchical");
427  for(const auto& memory_module : memory_modules)
428  {
429  for(unsigned int j = 0; j < GetPointer<const module>(memory_module)->get_in_port_size(); j++)
430  {
431  structural_objectRef port_i = GetPointer<const module>(memory_module)->get_in_port(j);
432  if(GetPointer<port_o>(port_i)->get_is_memory() && GetPointer<port_o>(port_i)->get_is_global() &&
433  GetPointer<port_o>(port_i)->get_is_extern())
434  {
435  std::string port_name = GetPointer<port_o>(port_i)->get_id();
436  cir_port = circuit->find_member(port_name, port_i->get_kind(), circuit);
437  THROW_ASSERT(!cir_port || GetPointer<port_o>(cir_port), "should be a port or null");
438  if(!cir_port)
439  {
440  cir_port =
441  SM->add_port_vector(port_name, port_o::IN, parameters->getOption<unsigned int>(OPT_channels_number),
442  circuit, port_i->get_typeRef());
443  port_o::fix_port_properties(port_i, cir_port);
444  }
445  if(port_i->get_kind() == port_vector_o_K) // connecting a port vector
446  {
447  SM->add_connection(GetPointer<port_o>(cir_port)->get_port(0),
448  GetPointer<port_o>(port_i)->get_port(0)); // connect first port
449  if(GetPointer<port_o>(port_i)->get_ports_size() > 1) // More than 1 channel
450  {
451  for(unsigned int num_chan = 1; num_chan < parameters->getOption<unsigned int>(OPT_channels_number);
452  num_chan++)
453  {
454  SM->add_connection(
455  GetPointer<port_o>(cir_port)->get_port(num_chan),
456  GetPointer<port_o>(port_i)->get_port(num_chan)); // connect other port one by one
457  }
458  }
459  }
460  else
461  {
462  SM->add_connection(GetPointer<port_o>(cir_port)->get_port(0), port_i); // connect a normal port
463  }
464  }
465  }
466 
467  for(unsigned int j = 0; j < GetPointer<const module>(memory_module)->get_out_port_size(); j++)
468  {
469  structural_objectRef port_i = GetPointer<const module>(memory_module)->get_out_port(j);
470  if(GetPointer<port_o>(port_i)->get_is_memory() && !GetPointer<port_o>(port_i)->get_is_global() &&
471  !GetPointer<port_o>(port_i)->get_is_extern())
472  {
473  std::string port_name = GetPointer<port_o>(port_i)->get_id();
474  cir_port = circuit->find_member(port_name, port_i->get_kind(), circuit);
475  THROW_ASSERT(!cir_port || GetPointer<port_o>(cir_port), "should be a port or null");
476  if(!cir_port)
477  {
478  cir_port =
479  SM->add_port_vector(port_name, port_o::OUT, parameters->getOption<unsigned int>(OPT_channels_number),
480  circuit, port_i->get_typeRef());
481  port_o::fix_port_properties(port_i, cir_port);
482  }
483  if(port_i->get_kind() == port_vector_o_K) // connecting a port vector
484  {
485  if(std::find(primary_outs[GetPointer<port_o>(cir_port)->get_port(0)].begin(),
486  primary_outs[GetPointer<port_o>(cir_port)->get_port(0)].end(),
487  GetPointer<port_o>(port_i)->get_port(0)) ==
488  primary_outs[GetPointer<port_o>(cir_port)->get_port(0)].end())
489  {
490  primary_outs[GetPointer<port_o>(cir_port)->get_port(0)].push_back(
491  GetPointer<port_o>(port_i)->get_port(0)); // merge first cell of vector
492  }
493  if(GetPointer<port_o>(port_i)->get_ports_size() > 1) // More than 1 channel
494  {
495  for(unsigned int num_chan = 1; num_chan < parameters->getOption<unsigned int>(OPT_channels_number);
496  num_chan++)
497  {
498  SM->add_connection(
499  GetPointer<port_o>(port_i)->get_port(num_chan),
500  GetPointer<port_o>(cir_port)->get_port(num_chan)); // connect other port one by one
501  }
502  }
503  }
504  else if(std::find(primary_outs[GetPointer<port_o>(cir_port)->get_port(0)].begin(),
505  primary_outs[GetPointer<port_o>(cir_port)->get_port(0)].end(),
506  port_i) == primary_outs[GetPointer<port_o>(cir_port)->get_port(0)].end())
507  {
508  primary_outs[GetPointer<port_o>(cir_port)->get_port(0)].push_back(port_i); // merge normal port
509  }
510  }
511  }
512  }
513  join_merge_split(SM, HLS, primary_outs, circuit, _unique_id);
514  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - End merging, splitting for hierarchical");
515 }
516 
519  unsigned int _dir, structural_objectRef circuit, unsigned int num)
520 {
521  if(_dir == port_o::IO)
522  {
523  THROW_ERROR("port declared as IO not accepted in context switch");
524  }
525  else
526  {
527  auto omp_functions = GetPointer<OmpFunctions>(HLSMgr->Rfuns);
528  if(omp_functions->kernel_functions.find(HLS->functionId) != omp_functions->kernel_functions.end() ||
529  omp_functions->hierarchical_functions.find(HLS->functionId) != omp_functions->hierarchical_functions.end())
530  {
531  if(!GetPointer<port_o>(port_in)->get_is_memory())
532  { // if not a memory port then use standard method
533  fu_binding::manage_extern_global_port(HLSMgr, HLS, SM, port_in, _dir, circuit, num);
534  }
535  // otherwise do nothing because memory port are managed by method manage_memory_port called after
536  }
537  else
538  {
539  fu_binding::manage_extern_global_port(HLSMgr, HLS, SM, port_in, _dir, circuit, num);
540  }
541  }
542 }
void add_connection(structural_objectRef src, structural_objectRef dest)
Create a connection between a source structural object and a destination structural object...
#define TASKS_POOL_END
void manage_memory_ports_parallel_chained(const HLS_managerRef HLSMgr, const structural_managerRef SM, const std::list< structural_objectRef > &memory_modules, const structural_objectRef circuit, const hlsRef HLS, unsigned int &_unique_id) override
decide based on function what function to call in order to connect appropriately the datapath memory_...
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
Data structure representing the entire HLS information.
int debug_level
The debug level.
Definition: fu_binding.hpp:121
#define DONE_SCHEDULER
refcount< structural_type_descriptor > structural_type_descriptorRef
RefCount type definition of the structural_type_descriptor class structure.
File containing functions and utilities to support the printing of debug messagges.
#define PRINT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
#define DONE_REQUEST
structural_managerRef datapath
Store the datapath description.
Definition: hls.hpp:155
#define START_PORT_NAME
Structure representing the most relevant information about the type of a structural object...
const std::string & get_id() const
Return the identifier associated with the structural_object.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
const structural_objectRef get_circ() const
Get a reference to circ field.
void add_to_SM(const HLS_managerRef HLSMgr, const hlsRef HLS, structural_objectRef clock_port, structural_objectRef reset_port) override
Call different method that instantiate the new component for each function_type.
void manage_extern_global_port(const HLS_managerRef HLSMgr, const hlsRef HLS, const structural_managerRef SM, structural_objectRef port_in, unsigned int dir, structural_objectRef circuit, unsigned int num) override
manage_extern_global_port based on function attach the input of memory modules
mathematical utility function not provided by standard libraries
~fu_binding_cs() override
Destructor.
void resize_dimension_bus_port(const HLS_managerRef HLSMgr, structural_objectRef port)
for each port resize it using vector size
const HLS_deviceRef HLS_D
reference to the information representing the target for the synthesis
Definition: hls.hpp:107
virtual structural_objectRef find_member(const std::string &id, so_kind type, const structural_objectRef owner) const =0
Return the object named id of a given type which belongs to or it is associated with the object...
virtual void add_to_SM(const HLS_managerRef HLSMgr, const hlsRef HLS, structural_objectRef clock_port, structural_objectRef reset_port)
Instance the functional unit inside the structural representation of the datapath.
Definition: fu_binding.cpp:551
virtual void manage_extern_global_port(const HLS_managerRef HLSMgr, const hlsRef HLS, const structural_managerRef SM, structural_objectRef port_in, unsigned int dir, structural_objectRef circuit, unsigned int num)
Class specification of the manager of the technology library data structures.
redefinition of map to manage ordered/unordered structures
Derived class to add module scheduler, mem_ctrl_parallel and bind correctly the channels.
#define STR(s)
Macro which performs a lexical_cast to a string.
#define CLOCK_PORT_NAME
standard name for ports
T ceil_log2(T x)
Return the smallest n such that 2**n >= X.
void set_atomic_memory_parameter(const hlsRef HLS)
set_atomic_memory_parameter need to set in order to have memory operation defined as atomic ...
void manage_memory_port_kernel(const structural_managerRef SM, const std::list< structural_objectRef > &memory_modules, const structural_objectRef circuit, const hlsRef HLS, unsigned int &_unique_id)
manage_memory_port_kernel connect correctly memory port when in kernel function
static structural_objectRef add_port(const std::string &id, port_o::port_direction pdir, structural_objectRef owner, structural_type_descriptorRef type_descr, unsigned int treenode=0)
Create a new port.
redefinition of set to manage ordered/unordered structures
fu_binding_cs(const HLS_managerConstRef _HLSMgr, const unsigned int function_id, const ParameterConstRef parameters)
static void fix_port_properties(structural_objectRef port_i, structural_objectRef cir_port)
copy the port properties from port_i to cir_port
void instantiate_component_kernel(const HLS_managerRef HLSMgr, const hlsRef HLS, structural_objectRef clock_port, structural_objectRef reset_port)
instantiate_component_kernel
void SetParameter(const std::string &name, const std::string &value)
Set a parameter value.
void connect_selector(const hlsRef HLS)
connect_selector in function not kernel connect selector with all the module that have the right port...
virtual enum so_kind get_kind() const =0
Virtual function used to find the real type of a structural_object instance.
This file collects some utility functions and macros.
void connect_selector_kernel(const hlsRef HLS)
connect_selector_kernel, kernel take selector from scheduler
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
Definition: exceptions.hpp:263
virtual void manage_memory_ports_parallel_chained(const HLS_managerRef HLSMgr, const structural_managerRef SM, const std::list< structural_objectRef > &memory_modules, const structural_objectRef circuit, const hlsRef HLS, unsigned int &unique_id)
void type_resize(unsigned long long new_bit_size)
Just resize the size of the bits of the object.
structural_objectRef add_module_from_technology_library(const std::string &id, const std::string &fu_name, const std::string &library_name, const structural_objectRef owner, const technology_managerConstRef TM)
Create a new object starting from a library component.
This class describes all classes used to represent a structural object.
const structural_type_descriptorRef & get_typeRef() const
Return the type descriptor of the structural_object.
static void join_merge_split(const structural_managerRef SM, const hlsRef HLS, std::map< structural_objectRef, std::list< structural_objectRef >, jms_sorter > &primary_outs, const structural_objectRef circuit, unsigned int &unique_id)
static structural_objectRef add_sign(std::string id, structural_objectRef owner, structural_type_descriptorRef sign_type, unsigned int treenode=0)
Create a new signal.
void manage_memory_port_hierarchical(const structural_managerRef SM, const std::list< structural_objectRef > &memory_modules, const structural_objectRef circuit, const hlsRef HLS, unsigned int &_unique_id)
manage_memory_port_hierarchical connect correctly memory port when in hierarchical function ...
bool ExistsParameter(std::string name) const
Check if a parameter has been specified.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
this class is used to manage the command-line or XML options.
#define SELECTOR_REGISTER_FILE
unsigned int functionId
this is the identifier of the function to be implemented
Definition: hls.hpp:87
#define RESET_PORT_NAME
Class implementation of the structural_manager.
Class managing the functional-unit binding.
Definition: fu_binding.hpp:90
const ParameterConstRef parameters
The set of input parameters.
Definition: fu_binding.hpp:118
Datastructure to describe functions allocation in high-level synthesis.
#define DEBUG_LEVEL_VERBOSE
verbose debugging print is performed.
Data structure definition for high-level synthesis flow.
static structural_objectRef add_port_vector(std::string id, port_o::port_direction pdir, unsigned int n_ports, structural_objectRef owner, structural_type_descriptorRef type_descr, unsigned int treenode=0)
Create a new port_vector.
Datastructure to represent memory information in high-level synthesis.
void resize_scheduler_ports(const HLS_managerRef HLSMgr, structural_objectRef scheduler_mod)
for each port decide its vector size
HLS specialization of generic_device.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...
Definition: exceptions.hpp:289

Generated on Mon Feb 12 2024 13:02:53 for PandA-2024.02 by doxygen 1.8.13