83 #include <boost/algorithm/string/replace.hpp> 111 : allocation_information(_HLSMgr->get_HLS(_function_id)->allocation_information),
112 TreeM(_HLSMgr->get_tree_manager()),
113 op_graph(_HLSMgr->CGetFunctionBehavior(_function_id)->CGetOpGraph(
FunctionBehavior::DFG)),
115 debug_level(_parameters->get_class_debug_level(
GET_CLASS(*this))),
116 has_resource_sharing_p(
true)
138 if(_parameters->isOption(OPT_context_switch))
140 auto omp_functions = GetPointer<OmpFunctions>(_HLSMgr->Rfuns);
142 if(omp_functions->kernel_functions.find(_function_id) != omp_functions->kernel_functions.end())
146 if(omp_functions->hierarchical_functions.find(_function_id) != omp_functions->hierarchical_functions.end())
150 if(omp_functions->parallelized_functions.find(_function_id) != omp_functions->parallelized_functions.end())
154 if(omp_functions->atomic_functions.find(_function_id) != omp_functions->atomic_functions.end())
175 const auto key = std::make_pair(unit, index);
200 return operations.find(std::make_pair(unit, index))->second;
207 return *(GetPointer<funit_obj>(
op_binding.at(statement_index)));
223 std::list<unsigned int> allocation_list;
228 allocation_list.push_back(alloc.first);
231 return allocation_list;
251 "Operation " +
TreeM->get_tree_node_const(statement_index)->ToString() +
" not assigned");
253 return GetPointer<funit_obj>(
op_binding.at(statement_index))->get_fu();
271 const auto FB = HLSMgr->CGetFunctionBehavior(HLS->
functionId);
274 const auto circuit = SM->
get_circ();
278 if(GetPointerS<functional_unit>(fu)->fu_template_name ==
"")
280 curr_lib_instance = GetPointer<functional_unit>(fu)->CM->get_circ();
284 const auto template_name = GetPointer<functional_unit>(fu)->fu_template_name;
285 const auto library_name = HLS->
HLS_D->get_technology_manager()->get_library(template_name);
287 GetPointerS<functional_unit>(GetPointerS<functional_unit_template>(
288 HLS->
HLS_D->get_technology_manager()->get_fu(template_name, library_name))
292 THROW_ASSERT(curr_lib_instance,
"structural description not provided: check the library given. Component: " +
293 GetPointerS<functional_unit>(fu)->functional_unit_name);
295 curr_lib_instance->
copy(curr_gate);
302 THROW_ASSERT(!name.empty(),
"cannot name the added gate if the name is empty");
310 SM->add_connection(clock_port, port_ck);
315 SM->add_connection(reset_port, port_rst);
317 GetPointerS<module>(circuit)->add_internal_object(curr_gate);
324 std::map<
unsigned int, std::list<structural_objectRef>>& var_call_sites_rel,
325 std::map<unsigned int, unsigned int>& reverse_memory_units)
329 const auto it_mu_end = memory_units.end();
330 for(
auto it_mu = memory_units.begin(); it_mu != it_mu_end; ++it_mu)
332 killing_vars.insert(it_mu->second);
333 reverse_memory_units[it_mu->second] = it_mu->first;
335 for(
const auto kv : killing_vars)
340 var_call_sites_rel[kv].push_back(curr_gate);
341 GetPointer<port_o>(port_proxy_in1)->set_is_memory(
false);
342 for(
const auto p_name :
343 {
"proxy_in2_",
"proxy_in2r_",
"proxy_in2w_",
"proxy_in3_",
"proxy_in3r_",
"proxy_in3w_",
"proxy_out1_",
344 "proxy_sel_LOAD_",
"proxy_sel_STORE_",
"proxy_in4r_",
"proxy_in4w_"})
349 GetPointerS<port_o>(port)->set_is_memory(
false);
358 std::map<std::string, std::list<structural_objectRef>>& fun_call_sites_rel,
359 std::map<std::string, unsigned int>& reverse_wrapped_units)
363 const auto it_mu_end = wrapped_units.end();
364 for(
auto it_mu = wrapped_units.begin(); it_mu != it_mu_end; ++it_mu)
366 killing_funs.insert(it_mu->second);
367 reverse_wrapped_units[it_mu->second] = it_mu->first;
369 for(
const auto& fun_name : killing_funs)
371 auto inPortSize =
static_cast<unsigned int>(GetPointer<module>(curr_gate)->get_in_port_size());
372 for(
unsigned int currentPort = 0; currentPort < inPortSize; ++currentPort)
375 if(!GetPointer<port_o>(curr_port)->get_is_memory())
379 std::string port_name = curr_port->
get_id();
382 size_t found = port_name.rfind(fun_name);
383 if(found != std::string::npos && found + fun_name.size() == port_name.size())
385 GetPointer<port_o>(curr_port)->set_is_memory(
false);
386 if(std::find(fun_call_sites_rel[fun_name].begin(), fun_call_sites_rel[fun_name].end(), curr_gate) ==
387 fun_call_sites_rel[fun_name].end())
389 fun_call_sites_rel[fun_name].push_back(curr_gate);
394 auto outPortSize =
static_cast<unsigned int>(GetPointer<module>(curr_gate)->get_out_port_size());
395 for(
unsigned int currentPort = 0; currentPort < outPortSize; ++currentPort)
398 if(!GetPointer<port_o>(curr_port)->get_is_memory())
402 std::string port_name = curr_port->
get_id();
403 size_t found = port_name.rfind(fun_name);
404 if(found != std::string::npos && found + fun_name.size() == port_name.size())
406 GetPointer<port_o>(curr_port)->set_is_memory(
false);
407 if(std::find(fun_call_sites_rel[fun_name].begin(), fun_call_sites_rel[fun_name].end(), curr_gate) ==
408 fun_call_sites_rel[fun_name].end())
410 fun_call_sites_rel[fun_name].push_back(curr_gate);
418 std::map<unsigned int, structural_objectRef>& mem_obj, std::map<unsigned int, unsigned int>& reverse_memory_units,
420 const hlsRef HLS,
unsigned int& _unique_id)
422 const auto circuit = SM->
get_circ();
423 for(
const auto& vcsr : var_call_sites_rel)
425 const auto& var = vcsr.first;
426 const auto& proxies = vcsr.second;
428 THROW_ASSERT(reverse_memory_units.count(var),
"var not found");
429 const auto storage_fu_id = reverse_memory_units.at(var);
430 THROW_ASSERT(mem_obj.count(storage_fu_id),
"storage_fu not found: " +
STR(storage_fu_id));
431 const auto storage_fu = mem_obj.at(storage_fu_id);
432 const auto storage_port_out = storage_fu->find_member(
"proxy_out1",
port_o_K, storage_fu);
433 THROW_ASSERT(storage_port_out,
"missing proxy_out1 port");
434 const auto storage_port_out_sign = [&]() {
438 GetPointerS<port_o>(storage_port_out)->get_ports_size(), circuit,
439 storage_port_out->get_typeRef());
441 return SM->
add_sign(
"S" + storage_port_out->get_id() +
"_" +
STR(var), circuit,
442 storage_port_out->get_typeRef());
446 const auto proxy_ports = [&]() {
447 std::vector<structural_objectRef> ports;
448 for(
const auto& pname : {
"proxy_in1",
"proxy_in2",
"proxy_in2r",
"proxy_in2w",
"proxy_in3",
"proxy_in3r",
449 "proxy_in3w",
"proxy_sel_LOAD",
"proxy_sel_STORE",
"proxy_in4r",
"proxy_in4w"})
451 const auto port = storage_fu->find_member(pname,
port_o_K, storage_fu);
454 ports.push_back(port);
459 std::map<structural_objectRef, std::list<structural_objectRef>,
jms_sorter> to_be_merged;
460 const auto var_suffix =
"_" +
STR(var);
461 for(
const auto& proxied_unit : proxies)
463 const auto port_out = proxied_unit->find_member(
"proxy_out1" + var_suffix,
port_o_K, proxied_unit);
464 THROW_ASSERT(port_out,
"missing proxied proxy_out1 port");
467 for(
const auto& pport : proxy_ports)
469 const auto port = proxied_unit->find_member(pport->get_id() + var_suffix,
port_o_K, proxied_unit);
472 to_be_merged[pport].push_back(port);
481 std::map<unsigned int, structural_objectRef>& fun_obj, std::map<std::string, unsigned int>& reverse_function_units,
483 const hlsRef HLS,
unsigned int& _unique_id)
485 const auto circuit = SM->
get_circ();
486 for(
const auto& fcsr : fun_call_sites_rel)
488 const auto&
fun = fcsr.first;
489 const auto& proxies = fcsr.second;
491 const auto wrapped_fu_unit_id = reverse_function_units.at(
fun);
492 THROW_ASSERT(fun_obj.count(wrapped_fu_unit_id),
"wrapped_fu_unit not found");
493 const auto wrapped_fu_unit = fun_obj.at(wrapped_fu_unit_id);
494 std::map<structural_objectRef, std::list<structural_objectRef>,
jms_sorter> to_be_merged;
496 const auto inPortSize = GetPointer<module>(wrapped_fu_unit)->get_in_port_size();
497 for(
auto currentPort = 0
U; currentPort < inPortSize; ++currentPort)
499 const auto curr_port = GetPointerS<module>(wrapped_fu_unit)->get_in_port(currentPort);
500 const auto port_name = curr_port->get_id();
503 for(
const auto& proxied_unit : proxies)
505 const auto port_proxy_in_i = proxied_unit->find_member(port_name +
"_" +
fun,
port_o_K, proxied_unit);
508 to_be_merged[curr_port].push_back(port_proxy_in_i);
513 const auto outPortSize = GetPointer<module>(wrapped_fu_unit)->get_out_port_size();
514 for(
auto currentPort = 0
U; currentPort < outPortSize; ++currentPort)
516 const auto wrapped_port_proxy_out_i = GetPointerS<module>(wrapped_fu_unit)->get_out_port(currentPort);
517 const auto port_name = wrapped_port_proxy_out_i->get_id();
521 for(
const auto& proxied_unit : proxies)
526 if(!wrapped_port_proxy_out_i_sign)
530 wrapped_port_proxy_out_i_sign =
532 GetPointer<port_o>(wrapped_port_proxy_out_i)->get_ports_size(), circuit,
533 wrapped_port_proxy_out_i->get_typeRef());
537 wrapped_port_proxy_out_i_sign = SM->
add_sign(wrapped_port_proxy_out_i->get_id() +
"_" +
fun,
538 circuit, wrapped_port_proxy_out_i->get_typeRef());
540 SM->
add_connection(wrapped_port_proxy_out_i_sign, wrapped_port_proxy_out_i);
542 SM->
add_connection(wrapped_port_proxy_out_i_sign, port_proxy_out_i);
556 const auto TechM = HLS->
HLS_D->get_technology_manager();
559 unsigned int unique_id = 0
U;
565 const auto circuit = SM->get_circ();
567 std::list<structural_objectRef> memory_modules;
570 const auto FB = HLSMgr->CGetFunctionBehavior(HLS->
functionId);
571 const auto function_parameters = FB->CGetBehavioralHelper()->get_parameters();
572 unsigned int sign_id = 0;
577 for(
const auto& function_parameter : function_parameters)
579 if(HLSMgr->Rmem->is_parm_decl_copied(function_parameter) &&
580 !HLSMgr->Rmem->is_parm_decl_stored(function_parameter))
585 "functional unit not available: check the library given. Component: " + std::string(
MEMCPY_STD));
586 const auto curr_gate =
add_gate(HLSMgr, HLS, fu_lib_unit,
"parameter_manager_" +
STR(function_parameter),
588 const auto curr_gate_m = GetPointerS<module>(curr_gate);
589 const auto port_obj = HLS->
Rconn->
get_port(function_parameter, conn_binding::IN);
592 SM->add_connection(in_par, src);
593 const auto dest = curr_gate_m->find_member(
"dest",
port_o_K, curr_gate);
595 const auto const_obj = SM->add_module_from_technology_library(
596 "memcpy_dest_" + HLSMgr->Rmem->get_symbol(function_parameter, HLS->
functionId)->get_symbol_name(),
598 const_obj->SetParameter(
"value",
599 HLSMgr->Rmem->get_symbol(function_parameter, HLS->
functionId)->get_symbol_name());
600 const auto name =
"out_const_memcpy_dest_" +
601 HLSMgr->Rmem->get_symbol(function_parameter, HLS->
functionId)->get_symbol_name();
602 const auto dest_sign = SM->add_sign(name, circuit, dest->get_typeRef());
606 SM->add_connection(dest_sign,
out_port);
607 SM->add_connection(dest, dest_sign);
608 const auto n = curr_gate_m->find_member(
"len",
port_o_K, curr_gate);
609 const auto n_obj = SM->add_constant(
610 "constant_len_" +
STR(function_parameter), circuit, n->get_typeRef(),
612 SM->add_connection(n, n_obj);
618 const auto delay_unit = [&]() {
619 const auto reset_type =
parameters->getOption<std::string>(OPT_reset_type);
623 const auto delay_gate =
add_gate(HLSMgr, HLS, delay_unit,
"start_delayed_" +
STR(function_parameter),
628 SM->add_connection(
sign, in_chain);
629 SM->add_connection(
sign, GetPointer<module>(delay_gate)->get_in_port(2));
632 if(in_chain == start_port)
634 SM->add_connection(in_chain, start_obj);
640 SM->add_connection(
sign, in_chain);
641 SM->add_connection(
sign, start_obj);
645 memory_modules.push_back(curr_gate);
647 else if(HLSMgr->Rmem->is_parm_decl_stored(function_parameter))
650 "---Managing parameter initialization: " +
STR(function_parameter));
651 auto bus_data_bitsize = HLSMgr->Rmem->get_bus_data_bitsize();
652 auto bus_addr_bitsize = HLSMgr->get_address_bitsize();
653 auto bus_size_bitsize = HLSMgr->Rmem->get_bus_size_bitsize();
654 unsigned long long bus_tag_bitsize = 0;
655 if(HLS->
Param->getOption<
bool>(OPT_parse_pragma) && HLS->
Param->isOption(OPT_context_switch))
657 bus_tag_bitsize = GetPointer<memory_cs>(HLSMgr->Rmem)->get_bus_tag_bitsize();
661 THROW_ASSERT(fu_lib_unit,
"functional unit not available: check the library given. Component: " +
663 const auto max_n_ports = FB->GetChannelsNumber();
664 const auto curr_gate =
add_gate(HLSMgr, HLS, fu_lib_unit,
"parameter_manager_" +
STR(function_parameter),
666 const auto port_obj = HLS->
Rconn->
get_port(function_parameter, conn_binding::IN);
668 const auto data = GetPointer<module>(curr_gate)->find_member(
"data",
port_o_K, curr_gate);
670 SM->add_connection(in_par, data);
672 const auto size = GetPointer<module>(curr_gate)->find_member(
"size",
port_o_K, curr_gate);
674 const auto size_const_obj = SM->add_module_from_technology_library(
675 "size_par_" + HLSMgr->Rmem->get_symbol(function_parameter, HLS->
functionId)->get_symbol_name(),
677 const std::string parameter_value =
684 size_const_obj->SetParameter(
"value", parameter_value);
685 const auto size_name =
686 "out_const_size_par_" + HLSMgr->Rmem->get_symbol(function_parameter, HLS->
functionId)->get_symbol_name();
687 const auto size_sign = SM->add_sign(size_name, circuit, size->get_typeRef());
688 const auto size_out_port = size_const_obj->find_member(
"out1",
port_o_K, size_const_obj);
690 size_out_port->type_resize(
STD_GET_SIZE(in_par->get_typeRef()));
691 SM->add_connection(size_sign, size_out_port);
692 SM->add_connection(size, size_sign);
694 const auto addr = GetPointer<module>(curr_gate)->find_member(
"addr",
port_o_K, curr_gate);
695 addr->type_resize(bus_addr_bitsize);
696 const auto const_obj = SM->add_module_from_technology_library(
697 "addr_par_" + HLSMgr->Rmem->get_symbol(function_parameter, HLS->
functionId)->get_symbol_name(),
699 const_obj->SetParameter(
"value",
700 HLSMgr->Rmem->get_symbol(function_parameter, HLS->
functionId)->get_symbol_name());
702 "out_const_addr_par_" + HLSMgr->Rmem->get_symbol(function_parameter, HLS->
functionId)->get_symbol_name();
703 const auto addr_sign = SM->add_sign(name, circuit, addr->get_typeRef());
706 out_port->type_resize(bus_addr_bitsize);
707 SM->add_connection(addr_sign,
out_port);
708 SM->add_connection(addr, addr_sign);
716 auto reset_type =
parameters->getOption<std::string>(OPT_reset_type);
717 if(reset_type ==
"sync")
719 delay_unit = TechM->get_fu(
flipflop_SR, LIBRARY_STD);
723 delay_unit = TechM->get_fu(
flipflop_AR, LIBRARY_STD);
727 clock_port, reset_port);
731 SM->add_connection(sign, in_chain);
732 SM->add_connection(sign, GetPointer<module>(delay_gate)->get_in_port(2));
733 in_chain = GetPointer<module>(delay_gate)->get_out_port(0);
736 if(in_chain == start_port)
738 SM->add_connection(in_chain, start_obj);
745 SM->add_connection(sign, in_chain);
746 SM->add_connection(sign, start_obj);
750 for(
unsigned int i = 0; i < GetPointer<module>(curr_gate)->get_in_port_size(); i++)
755 GetPointer<port_o>(port)->add_n_ports(static_cast<unsigned int>(max_n_ports), port);
759 for(
unsigned int i = 0; i < GetPointer<module>(curr_gate)->get_out_port_size(); i++)
764 GetPointer<port_o>(port)->add_n_ports(static_cast<unsigned int>(max_n_ports), port);
769 memory_modules.push_back(curr_gate);
775 SM->add_connection(in_chain, done_port);
786 controller_flow_circuit->
copy(curr_gate);
787 curr_gate->
set_id(
"ControlFlowChecker_i");
788 GetPointer<module>(circuit)->add_internal_object(curr_gate);
790 SM->add_connection(controller_flow_clock, clock_port);
792 SM->add_connection(controller_flow_reset, reset_port);
797 SM->add_connection(start_CFC, controller_flow_start);
802 SM->add_connection(done_CFC, controller_flow_done);
807 SM->add_connection(controller_present_state, controller_flow_present_state);
812 SM->add_connection(controller_next_state, controller_flow_next_state);
813 memory_modules.push_back(curr_gate);
816 const auto is_sparse_memory =
819 std::map<unsigned int, structural_objectRef> mem_obj;
820 for(
const auto& m : memory_units)
822 const auto fu_type_id = m.first;
828 name =
"array_" +
STR(var);
832 THROW_ERROR(
"Unit not currently supported: " + fun_unit_name);
835 THROW_ASSERT(fu_lib_unit,
"functional unit not available: check the library given. Component: " + fun_unit_name);
836 const auto is_splitted_memory = [&]() {
837 const auto& memory_type = GetPointerS<const functional_unit>(fu_lib_unit)->memory_type;
838 const auto& channels_type = GetPointerS<const functional_unit>(fu_lib_unit)->channels_type;
842 const auto is_sds_memory = [&]() {
843 const auto& memory_type = GetPointerS<const functional_unit>(fu_lib_unit)->memory_type;
850 HLSMgr->CGetFunctionBehavior(HLS->
functionId)->CGetBehavioralHelper()->PrintVariable(var));
851 const auto base_address = HLSMgr->Rmem->get_symbol(var, HLS->
functionId)->get_symbol_name();
852 const auto rangesize = HLSMgr->Rmem->get_rangesize(var);
856 const auto total_allocated =
get_number(fu_type_id);
857 const auto n_iterations =
std::max(1u, total_allocated);
858 for(
unsigned int num = 0; num < n_iterations; num += n_channels)
861 for(
unsigned int channel_index = 0; channel_index < n_channels && (num + channel_index < total_allocated);
864 auto key = std::make_pair(fu_type_id, num + channel_index);
868 operations_set.insert(opset.begin(), opset.end());
874 specialise_fu(HLSMgr, HLS, curr_gate, fu_type_id, operations_set, var);
876 is_sparse_memory, is_sds_memory);
878 mem_obj[fu_type_id] = curr_gate;
879 for(
unsigned int channel_index = 0; (channel_index < n_channels) && ((num + channel_index) < total_allocated);
885 if(!HLSMgr->Rmem->is_private_memory(var))
888 memory_modules.push_back(curr_gate);
893 std::map<unsigned int, unsigned int> reverse_memory_units;
894 std::map<std::string, unsigned int> reverse_function_units;
895 std::map<unsigned int, std::list<structural_objectRef>> var_call_sites_rel;
896 std::map<std::string, std::list<structural_objectRef>> fun_call_sites_rel;
897 std::map<unsigned int, structural_objectRef> fun_obj;
899 for(
auto wu = wrapped_units.begin(); wu != wrapped_units.end(); ++wu)
903 THROW_ASSERT(fu_lib_unit,
"functional unit not available: check the library given. Component: " +
905 const auto curr_gate =
910 specialise_fu(HLSMgr, HLS, curr_gate, wu->first, mapped_operations, 0);
912 fun_obj[wu->first] = curr_gate;
916 if(added_memory_element)
918 memory_modules.push_back(curr_gate);
927 std::list<std::pair<structural_objectRef, unsigned int>> proxy_memory_units_to_be_renamed_back;
928 std::list<std::pair<structural_objectRef, std::string>> proxy_function_units_to_be_renamed_back;
939 get(i, 0)->set_structural_obj(obj);
949 for(
unsigned int num = 0; num <
get_number(i); num++)
951 const auto module_obj =
get(i, num);
954 const auto name = module_obj->get_string();
961 else if(wrapped_units.find(i) != wrapped_units.end())
963 curr_gate = fun_obj[i];
968 const auto true_module_obj =
get(i, (num / n_channels) * n_channels);
969 curr_gate = true_module_obj->get_structural_obj();
974 specialise_fu(HLSMgr, HLS, curr_gate, i, mapped_operations, ar_var);
975 module_obj->set_structural_obj(curr_gate);
981 THROW_ASSERT(fu_lib_unit,
"functional unit not available: check the library given. Component: " +
983 curr_gate =
add_gate(HLSMgr, HLS, fu_lib_unit, name,
988 clock_port, reset_port);
990 std::string current_op;
991 if(mapped_operations.size())
998 has_resource_sharing_p =
true;
999 const auto site = *mapped_operations.begin();
1002 const auto callSiteMemorySym = HLSMgr->Rmem->get_symbol(vertex_node_id, HLS->
functionId);
1004 STR(callSiteMemorySym->get_address()));
1008 specialise_fu(HLSMgr, HLS, curr_gate, i, mapped_operations, ar_var);
1010 if(proxy_memory_units.find(i) != proxy_memory_units.end())
1012 proxy_memory_units_to_be_renamed_back.push_back(
1013 std::make_pair(curr_gate, proxy_memory_units.find(i)->second));
1014 std::string var_name =
"_" +
STR(proxy_memory_units.find(i)->second);
1017 const auto port_proxy_in1 = curr_gate->find_member(
"proxy_in1",
port_o_K, curr_gate);
1018 port_proxy_in1->set_id(port_proxy_in1->get_id() + var_name);
1022 const auto port_proxy_in2r = curr_gate->find_member(
"proxy_in2r",
port_o_K, curr_gate);
1023 const auto port_proxy_in2w = curr_gate->find_member(
"proxy_in2w",
port_o_K, curr_gate);
1024 const auto port_proxy_in3r = curr_gate->find_member(
"proxy_in3r",
port_o_K, curr_gate);
1025 const auto port_proxy_in3w = curr_gate->find_member(
"proxy_in3w",
port_o_K, curr_gate);
1026 const auto port_proxy_in4r = curr_gate->find_member(
"proxy_in4r",
port_o_K, curr_gate);
1027 const auto port_proxy_in4w = curr_gate->find_member(
"proxy_in4w",
port_o_K, curr_gate);
1028 port_proxy_in2r->set_id(port_proxy_in2r->get_id() + var_name);
1029 port_proxy_in2w->set_id(port_proxy_in2w->get_id() + var_name);
1030 port_proxy_in3r->set_id(port_proxy_in3r->get_id() + var_name);
1031 port_proxy_in3w->set_id(port_proxy_in3w->get_id() + var_name);
1032 port_proxy_in4r->set_id(port_proxy_in4r->get_id() + var_name);
1033 port_proxy_in4w->set_id(port_proxy_in4w->get_id() + var_name);
1037 const auto port_proxy_in2 = curr_gate->find_member(
"proxy_in2",
port_o_K, curr_gate);
1038 const auto port_proxy_in3 = curr_gate->find_member(
"proxy_in3",
port_o_K, curr_gate);
1039 port_proxy_in2->set_id(port_proxy_in2->get_id() + var_name);
1040 port_proxy_in3->set_id(port_proxy_in3->get_id() + var_name);
1042 const auto port_sel_LOAD = curr_gate->find_member(
"proxy_sel_LOAD",
port_o_K, curr_gate);
1043 const auto port_sel_STORE = curr_gate->find_member(
"proxy_sel_STORE",
port_o_K, curr_gate);
1044 const auto port_proxy_out1 = curr_gate->find_member(
"proxy_out1",
port_o_K, curr_gate);
1045 port_sel_LOAD->set_id(port_sel_LOAD->get_id() + var_name);
1046 port_sel_STORE->set_id(port_sel_STORE->get_id() + var_name);
1047 port_proxy_out1->set_id(port_proxy_out1->get_id() + var_name);
1051 if(proxy_function_units.find(i) != proxy_function_units.end())
1053 std::string fun_name =
"_" +
STR(proxy_function_units.find(i)->second);
1054 proxy_function_units_to_be_renamed_back.push_back(
1055 std::make_pair(curr_gate, proxy_function_units.find(i)->second));
1056 auto inPortSize =
static_cast<unsigned int>(GetPointer<module>(curr_gate)->get_in_port_size());
1057 for(
unsigned int currentPort = 0; currentPort < inPortSize; ++currentPort)
1060 if(!GetPointer<port_o>(curr_port)->get_is_memory())
1064 std::string port_name = curr_port->
get_id();
1067 GetPointer<port_o>(curr_port)->set_id(port_name + fun_name);
1070 auto outPortSize =
static_cast<unsigned int>(GetPointer<module>(curr_gate)->get_out_port_size());
1071 for(
unsigned int currentPort = 0; currentPort < outPortSize; ++currentPort)
1074 if(!GetPointer<port_o>(curr_port)->get_is_memory())
1078 std::string port_name = curr_port->
get_id();
1081 GetPointer<port_o>(curr_port)->set_id(port_name + fun_name);
1088 if(added_memory_element &&
1089 std::find(memory_modules.begin(), memory_modules.end(), curr_gate) == memory_modules.end())
1091 memory_modules.push_back(curr_gate);
1097 module_obj->set_structural_obj(curr_gate);
1105 "---Resources are not shared in function " +
1106 HLSMgr->CGetFunctionBehavior(HLS->
functionId)->CGetBehavioralHelper()->get_function_name() +
1107 ": function pipelining may come for free");
1110 const auto cg_man = HLSMgr->CGetCallGraphManager();
1111 const auto top_function_ids = cg_man->GetRootFunctions();
1112 if(top_function_ids.find(HLS->
functionId) != top_function_ids.end() && cg_man->ExistsAddressedFunction())
1114 const auto addressed_functions = cg_man->GetAddressedFunctions();
1115 const auto constBitZero =
1117 const auto signBitZero =
1119 SM->add_connection(signBitZero, constBitZero->find_member(
"out1",
port_o_K, constBitZero));
1121 for(
const auto& f_id : addressed_functions)
1124 if(HLSMgr->Rfuns->is_a_proxied_function(FUName))
1129 const auto FU = SM->add_module_from_technology_library(FUName +
"_i0", FUName,
WORK_LIBRARY, circuit, TechM);
1130 if(std::find(memory_modules.begin(), memory_modules.end(), FU) == memory_modules.end())
1132 memory_modules.push_back(FU);
1136 "---Considering additional top: " + FUName +
"@" +
STR(f_id));
1137 if(HLSMgr->Rfuns->has_proxied_shared_functions(f_id))
1139 auto proxied_shared_functions = HLSMgr->Rfuns->get_proxied_shared_functions(f_id);
1141 for(
const auto& name : proxied_shared_functions)
1157 SM->add_connection(fu_start, signBitZero);
1160 for(
const auto additional_parameter :
1161 HLSMgr->CGetFunctionBehavior(f_id)->CGetBehavioralHelper()->get_parameters())
1163 const auto parameterName =
1164 HLSMgr->CGetFunctionBehavior(f_id)->CGetBehavioralHelper()->PrintVariable(additional_parameter);
1166 const auto parameterPort = FU->find_member(parameterName,
port_o_K, FU);
1167 const auto constZeroParam = SM->add_module_from_technology_library(
1169 const auto constZeroOutPort = constZeroParam->find_member(
"out1",
port_o_K, constZeroParam);
1170 const auto parameter_value =
1176 constZeroParam->SetParameter(
"value", parameter_value);
1178 constZeroOutPort->type_resize(
STD_GET_SIZE(parameterPort->get_typeRef()));
1180 const auto signBitZeroParam = SM->add_sign(
"signZeroParam_" + FUName +
"_" + parameterName, SM->get_circ(),
1181 constZeroOutPort->get_typeRef());
1183 SM->add_connection(parameterPort, signBitZeroParam);
1184 SM->add_connection(constZeroOutPort, signBitZeroParam);
1190 if(
parameters->IsParameter(
"chained-memory-modules") &&
parameters->GetParameter<
int>(
"chained-memory-modules") == 1)
1201 for(
const auto& pmutbrb : proxy_memory_units_to_be_renamed_back)
1203 const auto curr_gate = pmutbrb.first;
1205 const auto var_name =
"_" +
STR(pmutbrb.second);
1206 for(
const auto& pname :
1207 {
"proxy_in1",
"proxy_in2",
"proxy_in2r",
"proxy_in2w",
"proxy_in3",
"proxy_in3r",
"proxy_in3w",
"proxy_in4r",
1208 "proxy_in4w",
"proxy_sel_LOAD",
"proxy_sel_STORE",
"proxy_out1"})
1210 const auto port = curr_gate->find_member(pname + var_name,
port_o_K, curr_gate);
1213 port->set_id(pname);
1221 for(
const auto& pfutbrb : proxy_function_units_to_be_renamed_back)
1223 const auto& curr_gate = pfutbrb.first;
1225 const auto fun_name =
"_" +
STR(pfutbrb.second);
1226 const auto inPortSize = GetPointerS<module>(curr_gate)->get_in_port_size();
1227 for(
auto currentPort = 0
U; currentPort < inPortSize; ++currentPort)
1229 const auto curr_port = GetPointerS<module>(curr_gate)->get_in_port(currentPort);
1230 const auto port_name = curr_port->get_id();
1233 const auto found = port_name.rfind(fun_name);
1234 if(found != std::string::npos)
1236 const auto orig_port_name = port_name.substr(0, found);
1237 GetPointerS<port_o>(curr_port)->set_id(orig_port_name);
1241 const auto outPortSize = GetPointerS<module>(curr_gate)->get_out_port_size();
1242 for(
auto currentPort = 0
U; currentPort < outPortSize; ++currentPort)
1244 const auto curr_port = GetPointerS<module>(curr_gate)->get_out_port(currentPort);
1245 const auto port_name = curr_port->get_id();
1248 const auto found = port_name.rfind(fun_name);
1249 if(found != std::string::npos)
1251 const auto orig_port_name = port_name.substr(0, found);
1252 GetPointerS<port_o>(curr_port)->set_id(orig_port_name);
1268 const auto fu_module = GetPointer<module>(curr_gate);
1269 const auto np = fu_module->get_NP_functionality();
1272 std::vector<std::string>
param;
1273 np->get_library_parameters(param);
1274 for(
const auto& p : param)
1277 curr_gate->find_member(p,
port_vector_o_K, curr_gate) || curr_gate->ExistsParameter(p),
1278 "parameter not yet specialized: " + p +
" for module " +
GET_TYPE_NAME(curr_gate));
1287 const auto circuit = SM->
get_circ();
1290 bool added_memory_element =
false;
1291 for(
unsigned int j = 0; j < GetPointer<module>(curr_gate)->get_in_port_size(); j++)
1293 const auto port_in = GetPointer<module>(curr_gate)->get_in_port(j);
1295 if(GetPointer<port_o>(port_in)->get_is_memory())
1297 added_memory_element =
true;
1301 for(
unsigned int j = 0; j < GetPointer<module>(curr_gate)->get_out_port_size(); j++)
1307 for(
unsigned int j = 0; j < GetPointer<module>(curr_gate)->get_in_out_port_size(); j++)
1313 return added_memory_element;
1317 const std::list<structural_objectRef>& memory_modules,
1320 std::map<std::string, structural_objectRef> from_ports;
1321 std::map<std::string, structural_objectRef> primary_outs;
1323 unsigned int sign_id = 0;
1324 for(
const auto& memory_module : memory_modules)
1326 for(
unsigned int j = 0; j < GetPointer<module>(memory_module)->get_in_port_size(); j++)
1329 if(GetPointer<port_o>(port_i)->get_is_memory() && (!GetPointer<port_o>(port_i)->get_is_global()) &&
1330 (!GetPointer<port_o>(port_i)->get_is_extern()))
1332 std::string port_name = GetPointer<port_o>(port_i)->get_id();
1333 THROW_ASSERT(port_name.substr(1, 3) ==
"in_",
"Expected the \"?in_\" prefix:" + port_name);
1334 std::string
key = port_name.substr(0, 1) + port_name.substr(4);
1336 THROW_ASSERT(!cir_port || GetPointer<port_o>(cir_port),
"should be a port or null");
1341 cir_port = SM->
add_port_vector(port_name, port_o::IN, GetPointer<port_o>(port_i)->get_ports_size(),
1354 "somewhere the signal " + key +
" should be produced");
1360 GetPointer<port_o>(port_i)->get_ports_size(), circuit, port_i->
get_typeRef());
1373 for(
unsigned int j = 0; j < GetPointer<module>(memory_module)->get_out_port_size(); j++)
1376 if(GetPointer<port_o>(port_i)->get_is_memory() && (!GetPointer<port_o>(port_i)->get_is_global()) &&
1377 (!GetPointer<port_o>(port_i)->get_is_extern()))
1379 std::string port_name = GetPointer<port_o>(port_i)->get_id();
1380 THROW_ASSERT(port_name.substr(1, 4) ==
"out_",
"Expected the \"?out_\" prefix: " + port_name);
1381 std::string
key = port_name.substr(0, 1) + port_name.substr(5);
1383 THROW_ASSERT(!cir_port || GetPointer<port_o>(cir_port),
"should be a port or null");
1388 cir_port = SM->
add_port_vector(port_name, port_o::OUT, GetPointer<port_o>(port_i)->get_ports_size(),
1396 primary_outs[port_name] = cir_port;
1398 from_ports[
key] = port_i;
1402 auto po_end = primary_outs.end();
1403 for(
auto po = primary_outs.begin(); po != po_end; ++po)
1405 THROW_ASSERT(from_ports.find(po->first.substr(0, 1) + po->first.substr(5)) != from_ports.end(),
1406 "Port source not present");
1407 SM->
add_connection(po->second, from_ports.find(po->first.substr(0, 1) + po->first.substr(5))->second);
1416 static const auto js_name =
"join_signal";
1417 static const auto ss_name =
"split_signal";
1418 static const auto bus_merger_res_name =
"bus_merger";
1419 const auto js_library = HLS->
HLS_D->get_technology_manager()->get_library(js_name);
1420 const auto ss_library = HLS->
HLS_D->get_technology_manager()->get_library(ss_name);
1421 const auto bm_library = HLS->
HLS_D->get_technology_manager()->get_library(bus_merger_res_name);
1423 for(
const auto& po : primary_outs)
1425 const auto& bus_port = po.first;
1427 const auto& merged_ports = po.second;
1428 const auto bus_merger_inst_name = bus_merger_res_name + bus_port->get_id() +
STR(_unique_id++) +
"_";
1431 if(merged_ports.size() == 1
U)
1433 out_port = merged_ports.front();
1434 THROW_ASSERT(out_port->
get_kind() == bus_port->get_kind(),
"Out port has type " + bus_port->get_kind_text() +
1435 " while internal port has type " +
1441 bus_merger_inst_name, bus_merger_res_name, bm_library, circuit, HLS->
HLS_D->get_technology_manager());
1442 const auto bm_in_port = GetPointerS<module>(bus_merger_mod)->get_in_port(0
U);
1443 GetPointerS<port_o>(bm_in_port)->add_n_ports(static_cast<unsigned int>(merged_ports.size()), bm_in_port);
1455 for(
const auto& merged_port : merged_ports)
1459 const auto sign_v_in = SM->
add_sign_vector(
"sig_in_vector_" + bus_merger_inst_name +
STR(in_id),
1460 GetPointerS<port_o>(merged_port)->get_ports_size(), circuit,
1464 js_library, circuit, HLS->
HLS_D->get_technology_manager());
1465 const auto js_in_port = GetPointerS<module>(js_mod)->get_in_port(0
U);
1466 GetPointerS<port_o>(js_in_port)
1467 ->add_n_ports(static_cast<unsigned int>(GetPointerS<port_o>(merged_port)->get_ports_size()),
1472 const auto js_out_port = GetPointerS<module>(js_mod)->get_out_port(0
U);
1477 bus_port->get_typeRef()->copy(sig_type);
1478 const auto sign_in = SM->
add_sign(
"sig_in_" + bus_merger_inst_name +
STR(in_id), circuit, sig_type);
1482 sign_in->type_resize(1
U, GetPointerS<port_o>(bus_port)->get_ports_size() *
1487 sign_in->type_resize(GetPointer<port_o>(bus_port)->get_ports_size() *
1491 SM->
add_connection(sign_in, GetPointer<port_o>(bm_in_port)->get_port(in_id));
1495 const auto sign_in =
1498 SM->
add_connection(sign_in, GetPointerS<port_o>(bm_in_port)->get_port(in_id));
1502 out_port = GetPointerS<module>(bus_merger_mod)->get_out_port(0);
1516 ss_name + bus_merger_inst_name, ss_name, ss_library, circuit, HLS->
HLS_D->get_technology_manager());
1518 bus_port->get_typeRef()->copy(sig_type);
1519 const auto sign_out = SM->
add_sign(
"sig_out_" + bus_merger_inst_name, circuit, sig_type);
1523 sign_out->type_resize(1, GetPointer<port_o>(bus_port)->get_ports_size() *
1528 sign_out->type_resize(GetPointer<port_o>(bus_port)->get_ports_size() *
1531 const auto ss_in_port = GetPointerS<module>(ss_mod)->get_in_port(0
U);
1537 out_port = GetPointerS<module>(ss_mod)->get_out_port(0
U);
1538 GetPointerS<port_o>(
out_port)->add_n_ports(
1539 static_cast<unsigned int>(GetPointerS<port_o>(bus_port)->get_ports_size()),
out_port);
1546 if(bus_port->get_owner() != circuit)
1552 GetPointerS<port_o>(bus_port)->get_ports_size(), circuit,
1571 const auto sign_out = SM->
add_sign(
"sig_out_" + bus_merger_inst_name, circuit, sig_type);
1585 const std::list<structural_objectRef>& memory_modules,
1587 unsigned int& _unique_id)
1589 std::map<structural_objectRef, std::list<structural_objectRef>,
jms_sorter> primary_outs;
1597 const auto port_v = GetPointerS<const port_o>(a);
1599 "Multiple ports: " +
STR(port_v->get_ports_size()) +
" in " + port_v->get_path());
1600 a = port_v->get_port(0
U);
1605 const auto port_v = GetPointerS<const port_o>(b);
1607 "Multiple ports: " +
STR(port_v->get_ports_size()) +
" in " + port_v->get_path());
1608 b = port_v->get_port(0
U);
1612 for(
const auto& memory_module : memory_modules)
1614 for(
unsigned int j = 0; j < GetPointer<module>(memory_module)->get_in_port_size(); ++j)
1617 if(GetPointer<port_o>(port_i)->get_is_memory() && (!GetPointer<port_o>(port_i)->get_is_global()) &&
1618 (!GetPointer<port_o>(port_i)->get_is_extern()))
1620 std::string port_name = GetPointer<port_o>(port_i)->get_id();
1622 THROW_ASSERT(!cir_port || GetPointer<port_o>(cir_port),
"should be a port or null");
1627 cir_port = SM->
add_port_vector(port_name, port_o::IN, GetPointer<port_o>(port_i)->get_ports_size(),
1641 vector_to_port(port_i, cir_port);
1646 GetPointerS<port_o>(port_i)->get_ports_size() > GetPointerS<port_o>(cir_port)->get_ports_size())
1648 const auto n_ports =
1649 GetPointerS<port_o>(port_i)->get_ports_size() - GetPointerS<port_o>(cir_port)->get_ports_size();
1650 GetPointerS<port_o>(cir_port)->add_n_ports(n_ports, cir_port);
1657 for(
unsigned int j = 0; j < GetPointer<module>(memory_module)->get_out_port_size(); j++)
1660 if(GetPointer<port_o>(port_i)->get_is_memory() && (!GetPointer<port_o>(port_i)->get_is_global()) &&
1661 (!GetPointer<port_o>(port_i)->get_is_extern()))
1663 const auto port_name = GetPointerS<port_o>(port_i)->get_id();
1665 THROW_ASSERT(!cir_port || GetPointer<port_o>(cir_port),
"should be a port or null");
1670 cir_port = SM->
add_port_vector(port_name, port_o::OUT, GetPointerS<port_o>(port_i)->get_ports_size(),
1683 vector_to_port(port_i, cir_port);
1688 GetPointerS<port_o>(port_i)->get_ports_size() > GetPointerS<port_o>(cir_port)->get_ports_size())
1691 GetPointerS<port_o>(port_i)->get_ports_size() - GetPointerS<port_o>(cir_port)->get_ports_size();
1692 GetPointerS<port_o>(cir_port)->add_n_ports(n_ports, cir_port);
1695 if(std::find(primary_outs[cir_port].begin(), primary_outs[cir_port].end(), port_i) ==
1696 primary_outs[cir_port].end())
1698 primary_outs[cir_port].push_back(port_i);
1711 const auto inPort = GetPointer<port_o>(port_in);
1712 const auto port_name = inPort->get_id();
1715 if(inPort->get_is_extern())
1718 if(inPort->get_is_global())
1720 THROW_ASSERT(!ext_port || GetPointer<port_o>(ext_port),
"should be a port or null");
1721 if(ext_port && GetPointerS<port_o>(ext_port)->get_port_direction() != dir)
1725 inPort->get_ports_size() > GetPointerS<port_o>(ext_port)->get_ports_size())
1727 const auto n_ports = inPort->get_ports_size() - GetPointerS<port_o>(ext_port)->get_ports_size();
1728 GetPointerS<port_o>(ext_port)->add_n_ports(n_ports, ext_port);
1752 inPort->get_ports_size() > GetPointerS<port_o>(ext_port)->get_ports_size())
1754 const auto n_ports = inPort->get_ports_size() - GetPointerS<port_o>(ext_port)->get_ports_size();
1755 GetPointer<port_o>(ext_port)->add_n_ports(n_ports, ext_port);
1763 ext_port = SM->
add_port_vector(
"ext_" + inPort->get_id() +
"_" + std::to_string(num), dir,
1764 inPort->get_ports_size(), circuit, port_in->
get_typeRef());
1768 ext_port = SM->
add_port(
"ext_" + inPort->get_id() +
"_" + std::to_string(num), dir, circuit,
1773 else if(inPort->get_is_global())
1776 THROW_ASSERT(!ext_port || GetPointer<port_o>(ext_port),
"should be a port or null");
1789 else if(inPort->get_port_interface() != port_o::port_interface::PI_DEFAULT)
1792 const auto fsymbol =
1793 HLSMgr->CGetFunctionBehavior(HLS->
functionId)->CGetBehavioralHelper()->GetMangledFunctionName();
1794 const auto func_arch = HLSMgr->module_arch->GetArchitecture(fsymbol);
1795 const auto is_dataflow_top =
1796 func_arch && func_arch->attrs.find(FunctionArchitecture::func_dataflow) != func_arch->attrs.end() &&
1797 func_arch->attrs.find(FunctionArchitecture::func_dataflow)->second ==
"top";
1798 if(is_dataflow_top &&
starts_with(port_name,
"_DF_bambu"))
1803 THROW_ASSERT(!ext_port || GetPointer<port_o>(ext_port),
"should be a port or null");
1804 if(ext_port && GetPointer<port_o>(ext_port)->get_port_direction() != dir)
1837 unsigned int fu,
const OpVertexSet& mapped_operations,
unsigned int ar)
1839 const auto FB = HLSMgr->CGetFunctionBehavior(HLS->
functionId);
1840 const auto memory_allocation_policy = FB->GetMemoryAllocationPolicy();
1841 auto bus_data_bitsize = HLSMgr->Rmem->get_bus_data_bitsize();
1842 auto bus_size_bitsize = HLSMgr->Rmem->get_bus_size_bitsize();
1843 const auto bus_addr_bitsize = HLSMgr->get_address_bitsize();
1844 const auto bus_tag_bitsize =
1845 HLS->
Param->isOption(OPT_context_switch) ? GetPointer<memory_cs>(HLSMgr->Rmem)->get_bus_tag_bitsize() : 0;
1846 auto* fu_module = GetPointer<module>(fu_obj);
1850 std::map<unsigned int, unsigned long long> required_variables;
1851 std::map<unsigned int, unsigned long long> num_elements;
1852 unsigned long long n_out_elements = 0;
1853 unsigned long long produced_variables = 1;
1859 bool has_misaligned_indirect_ref =
false;
1867 required_variables[0] = elmt_bitsize;
1868 if(HLSMgr->Rmem->is_private_memory(ar))
1870 bus_data_bitsize =
std::max(bus_data_bitsize, elmt_bitsize);
1872 required_variables[1] = bus_addr_bitsize;
1873 if(HLSMgr->Rmem->is_private_memory(ar))
1875 for(; elmt_bitsize >= (1u << bus_size_bitsize); ++bus_size_bitsize)
1879 required_variables[2] = bus_size_bitsize;
1880 produced_variables = elmt_bitsize;
1887 for(
const auto& mapped_operation : mapped_operations)
1890 " on BRAM = " + data->CGetOpNodeInfo(mapped_operation)->GetOperation() +
" " +
1892 const auto vars = HLSMgr->get_required_values(HLS->
functionId, mapped_operation);
1893 const auto out_var = HLSMgr->get_produced_value(HLS->
functionId, mapped_operation);
1896 THROW_ASSERT(std::get<0>(vars[0]),
"Expected a tree node in case of a value to store");
1897 required_variables[0] =
1902 has_misaligned_indirect_ref =
true;
1907 THROW_ASSERT(out_var,
"Expected a tree node in case of a value to load");
1908 produced_variables =
std::max(produced_variables,
1912 has_misaligned_indirect_ref =
true;
1917 if(fu_module->ExistsParameter(
"BRAM_BITSIZE"))
1919 auto bram_bitsize = HLSMgr->Rmem->get_bram_bitsize();
1920 if(HLSMgr->Rmem->is_private_memory(ar))
1922 auto accessed_bitsize =
std::max(required_variables[0], produced_variables);
1923 accessed_bitsize = ceil_pow2(accessed_bitsize);
1924 bram_bitsize = has_misaligned_indirect_ref ?
std::max(bram_bitsize, accessed_bitsize) :
1925 std::max(bram_bitsize, accessed_bitsize / 2);
1926 if(bram_bitsize > HLSMgr->Rmem->get_maxbram_bitsize())
1928 THROW_ERROR(
"incorrect operation mapping on memory module");
1931 fu_module->SetParameter(
"BRAM_BITSIZE",
STR(bram_bitsize));
1933 if(fu_module->ExistsParameter(
"BUS_PIPELINED"))
1935 const auto has_extern_mem =
1936 ((HLSMgr->Rmem->get_memory_address() - HLSMgr->base_address) > 0 &&
1940 fu_module->SetParameter(
"BUS_PIPELINED", has_extern_mem ?
"0" :
"1");
1947 for(
const auto& mapped_operation : mapped_operations)
1949 const auto vars = HLSMgr->get_required_values(HLS->
functionId, mapped_operation);
1951 "---Considering operation " +
1952 HLSMgr->get_tree_manager()
1953 ->get_tree_node_const(data->CGetOpNodeInfo(mapped_operation)->GetNodeId())
1955 const auto out_var = HLSMgr->get_produced_value(HLS->
functionId, mapped_operation);
1956 const auto fun_unit = GetPointerS<functional_unit>(fu_tech_obj);
1957 const auto& memory_ctrl_type = fun_unit->memory_ctrl_type;
1959 if(memory_ctrl_type !=
"")
1961 unsigned long long mem_var_size_in = 1;
1962 unsigned long long mem_var_size_out = 1;
1966 THROW_ASSERT(std::get<0>(vars[0]),
"Expected a tree node in case of a value to store");
1973 THROW_ASSERT(out_var,
"Expected a tree node in case of a value to load");
1974 mem_var_size_out =
std::max(mem_var_size_out,
1978 required_variables.insert(std::make_pair(0, 0));
1979 required_variables[0] =
std::max(required_variables[0], mem_var_size_in);
1980 required_variables[1] = bus_addr_bitsize;
1983 bus_data_bitsize =
std::max(bus_data_bitsize,
std::max(mem_var_size_in, mem_var_size_out));
1984 for(; bus_data_bitsize >= (1u << bus_size_bitsize); ++bus_size_bitsize)
1989 required_variables[2] = bus_size_bitsize;
1990 produced_variables =
std::max(produced_variables, mem_var_size_out);
1997 const auto np = fu_module->get_NP_functionality();
1999 const auto op_name = data->CGetOpNodeInfo(mapped_operation)->GetOperation();
2000 const auto is_float_expr = op_name.find(
FLOAT_EXPR) != std::string::npos;
2001 for(
auto i = 0
U; i < vars.size(); ++i)
2003 const auto& tree_var = std::get<0>(vars[i]);
2008 required_variables.insert(std::make_pair(i, 0));
2009 const auto var_node =
TreeM->CGetTreeReindex(tree_var);
2016 required_variables[i] =
std::max(required_variables[i], element_size);
2018 if(num_elements.find(i) == num_elements.end())
2020 num_elements[i] = size / element_size;
2024 THROW_ASSERT(num_elements.find(i)->second == size / element_size,
2025 "Performed a wrong module allocation");
2031 if(is_float_expr && is_flopoco)
2037 else if(bitsize > 32 && bitsize < 64)
2042 required_variables[i] =
std::max(required_variables[i], bitsize);
2047 std::vector<std::string>
param;
2048 np->get_library_parameters(param);
2049 auto it_end = param.end();
2050 for(
auto it = param.begin(); it != it_end; ++it)
2052 if(*it ==
"LSB_PARAMETER" && op_name ==
"pointer_plus_expr")
2054 unsigned int curr_LSB = 0;
2055 auto op0_tree_var = std::get<0>(vars[0]);
2064 if(value_bitsize <= 8)
2068 else if(value_bitsize == 16)
2072 else if(value_bitsize == 32)
2076 else if(value_bitsize == 64)
2080 else if(value_bitsize == 128)
2084 else if(value_bitsize == 256)
2094 auto op0 =
TreeM->get_tree_node_const(op0_tree_var);
2095 auto op1 =
TreeM->get_tree_node_const(std::get<0>(vars[1]));
2096 if(op0->get_kind() == ssa_name_K)
2098 auto ssa_var0 = GetPointer<ssa_name>(op0);
2099 if(!ssa_var0->bit_values.empty())
2101 auto tailZeros = 0u;
2102 const auto lengthBV = ssa_var0->bit_values.size();
2103 const auto& currBit = ssa_var0->bit_values.at(lengthBV - 1 - tailZeros);
2104 while(lengthBV > tailZeros && (currBit ==
'0' || currBit ==
'X'))
2108 if(tailZeros < curr_LSB)
2110 curr_LSB = tailZeros;
2122 if(op1->get_kind() == ssa_name_K)
2124 auto ssa_var1 = GetPointer<ssa_name>(op1);
2125 if(!ssa_var1->bit_values.empty())
2127 auto tailZeros = 0u;
2128 const auto lengthBV = ssa_var1->bit_values.size();
2129 const auto& currBit = ssa_var1->bit_values.at(lengthBV - 1 - tailZeros);
2130 while(lengthBV > tailZeros && (currBit ==
'0' || currBit ==
'X'))
2134 if(tailZeros < curr_LSB)
2136 curr_LSB = tailZeros;
2144 else if(op1->get_kind() == integer_cst_K)
2149 auto tailZeros = 0u;
2150 while((offset_value & (
integer_cst_t(1) << tailZeros)) == 0)
2154 if(tailZeros < curr_LSB)
2156 curr_LSB = tailZeros;
2164 if(fu_module->ExistsParameter(
"LSB_PARAMETER"))
2166 int lsb_parameter = std::stoi(fu_module->GetParameter(
"LSB_PARAMETER"));
2167 if(lsb_parameter < 0)
2169 lsb_parameter =
static_cast<int>(curr_LSB);
2173 lsb_parameter =
std::min(lsb_parameter, static_cast<int>(curr_LSB));
2175 fu_module->SetParameter(
"LSB_PARAMETER",
STR(lsb_parameter));
2179 fu_module->SetParameter(
"LSB_PARAMETER",
STR(curr_LSB));
2182 if(*it ==
"OFFSET_PARAMETER" && op_name ==
"bit_ior_concat_expr")
2184 auto index = data->CGetOpNodeInfo(mapped_operation)->GetNodeId();
2185 const auto ga_node =
TreeM->GetTreeNode(
index);
2186 const auto ga = GetPointer<gimple_assign>(ga_node);
2187 const auto ce = GetPointer<bit_ior_concat_expr>(
GET_NODE(ga->op1));
2189 fu_module->SetParameter(
"OFFSET_PARAMETER",
STR(offset_value));
2193 auto index = data->CGetOpNodeInfo(mapped_operation)->GetNodeId();
2194 std::string parameterName = HLSMgr->Rmem->get_symbol(
index, HLS->
functionId)->get_symbol_name();
2195 fu_module->SetParameter(
"unlock_address", parameterName);
2199 auto index = data->CGetOpNodeInfo(mapped_operation)->GetNodeId();
2200 const auto parameterAddressFileName =
"function_addresses_" +
STR(
index) +
".mem";
2201 std::ofstream parameterAddressFile(
GetPath(parameterAddressFileName));
2203 const auto call =
TreeM->CGetTreeNode(
index);
2204 const auto& calledFunction = GetPointerS<const gimple_call>(call)->
args[0];
2205 const auto& hasreturn_node = GetPointerS<const gimple_call>(call)->
args[1];
2208 const auto addrExpr =
GET_NODE(calledFunction);
2210 const auto alignment = HLSMgr->Rmem->get_parameter_alignment();
2211 unsigned long long int address = 0;
2212 address = HLSMgr->Rmem->compute_next_base_address(address,
index, alignment);
2213 auto paramList = GetPointerS<const function_type>(functionType)->prms;
2216 const auto node = GetPointerS<const tree_list>(
GET_CONST_NODE(paramList));
2219 const auto str_address =
convert_to_binary(address, HLSMgr->get_address_bitsize());
2220 parameterAddressFile << str_address <<
"\n";
2224 paramList = node->chan;
2226 const auto return_type = GetPointerS<const function_type>(functionType)->retn;
2227 if(return_type &&
GET_CONST_NODE(return_type)->get_kind() != void_type_K && hasreturn_value)
2229 const auto str_address =
convert_to_binary(address, HLSMgr->get_address_bitsize());
2230 parameterAddressFile << str_address <<
"\n";
2232 parameterAddressFile.close();
2233 fu_module->SetParameter(
"MEMORY_INIT_file",
"\"\"" +
GetPath(parameterAddressFileName) +
"\"\"");
2239 const auto out_node =
TreeM->CGetTreeNode(out_var);
2246 n_out_elements = size / element_size;
2247 produced_variables = element_size;
2256 std::vector<std::string>
param;
2257 np->get_library_parameters(param);
2258 auto it_end = param.end();
2259 for(
auto it = param.begin(); it != it_end; ++it)
2261 if(*it ==
"PRECISION")
2268 fu_module->SetParameter(
"PRECISION",
STR(sizetype));
2280 for(
unsigned int i = 0; i < fu_module->get_in_port_size(); i++)
2289 GetPointer<port_o>(port)->add_n_ports(static_cast<unsigned int>(max_n_ports), port);
2292 GetPointer<port_o>(port)->get_ports_size() == 0)
2294 GetPointer<port_o>(port)->add_n_ports(static_cast<unsigned int>(required_variables.size()), port);
2302 for(
auto l = required_variables.begin(); l != required_variables.end() && !is_multi_read_cond; ++l)
2304 unsigned long long n_elmts = 0;
2305 if(num_elements.find(l->first) != num_elements.end())
2307 n_elmts = num_elements.find(l->first)->second;
2309 auto bitsize_variable = l->second;
2310 auto piIndexLimit = 1
U;
2311 if(is_dual && l->first)
2315 for(
auto piOffset = 0
U; piOffset < piIndexLimit; ++piOffset)
2320 if(is_dual && l->first)
2329 for(
unsigned int i = 0; i < fu_module->get_out_port_size(); i++)
2338 GetPointer<port_o>(port)->add_n_ports(static_cast<unsigned int>(max_n_ports), port);
2343 if(offset < fu_module->get_out_port_size())
2348 if(is_multi_read_cond)
2359 auto* fun_unit = GetPointer<functional_unit>(fu_tech_obj);
2363 auto ops_end = Ops.end();
2364 for(
auto ops = Ops.begin(); ops != ops_end; ++ops)
2366 auto* curr_op = GetPointer<operation>(*ops);
2367 std::string pipe_parameters_str = curr_op->pipe_parameters;
2368 if(pipe_parameters_str !=
"")
2378 unsigned int ar,
const std::string& base_address,
2379 unsigned long long int rangesize,
bool is_memory_splitted,
2380 bool is_sparse_memory,
bool is_sds)
2382 const auto fu_module = GetPointer<module>(fu_obj);
2384 fu_module->SetParameter(
"address_space_begin",
STR(base_address));
2385 fu_module->SetParameter(
"address_space_rangesize",
STR(rangesize));
2386 fu_module->SetParameter(
"USE_SPARSE_MEMORY", is_sparse_memory ?
"1" :
"0");
2391 const auto init_filename =
"array_ref_" +
STR(ar) +
".mem";
2392 std::ofstream init_file_a(
GetPath(init_filename));
2393 std::ofstream init_file_b;
2394 if(is_memory_splitted)
2396 init_file_b.open(
GetPath(
"0_" + init_filename));
2398 unsigned long long vec_size = 0, elts_size = 0;
2399 const auto bitsize_align = is_sds ? 0ULL : std::stoull(fu_module->GetParameter(
"BRAM_BITSIZE"));
2401 THROW_ASSERT(vec_size,
"at least one element is expected");
2405 fu_module->SetParameter(
"ALIGNMENT",
STR(elts_size));
2407 if(is_memory_splitted)
2409 fu_module->SetParameter(
"MEMORY_INIT_file_a",
"\"\"" +
GetPath(init_filename) +
"\"\"");
2410 fu_module->SetParameter(
"MEMORY_INIT_file_b",
"\"\"" +
GetPath(
"0_" + init_filename) +
"\"\"");
2414 fu_module->SetParameter(
"MEMORY_INIT_file",
"\"\"" +
GetPath(init_filename) +
"\"\"");
2418 fu_module->SetParameter(
"n_elements",
STR(vec_size));
2419 fu_module->SetParameter(
"data_size",
STR(elts_size));
2420 fu_module->SetParameter(
"PRIVATE_MEMORY", HLSMgr->Rmem->is_private_memory(ar) ?
"1" :
"0");
2421 fu_module->SetParameter(
"READ_ONLY_MEMORY", HLSMgr->Rmem->is_read_only_variable(ar) ?
"1" :
"0");
2425 unsigned long long& vec_size,
unsigned long long& elts_size,
const memoryRef mem,
2429 const auto is_memory_splitted = init_file_b.good();
2430 init_file_b.seekp(std::ios_base::beg);
2432 const auto ar_node = TM->CGetTreeReindex(ar);
2434 const auto vd = GetPointer<const var_decl>(
GET_CONST_NODE(ar_node));
2437 init_node = vd->init;
2441 init_node = ar_node;
2444 unsigned long long element_align = 0;
2447 std::vector<unsigned long long> dims;
2450 vec_size = std::accumulate(dims.begin(), dims.end(), 1ULL,
2451 [](
unsigned long long a,
unsigned long long b) {
return a * b; });
2453 else if(GetPointer<const integer_type>(
GET_CONST_NODE(array_type_node)) ||
2480 bitsize_align = elts_size;
2487 const auto nbyte_on_memory = bitsize_align / 8;
2490 ((GetPointer<constructor>(
GET_NODE(init_node)) &&
2491 GetPointerS<constructor>(
GET_NODE(init_node))->list_of_idx_valu.size()) ||
2492 (GetPointer<string_cst>(
GET_NODE(init_node)) && GetPointerS<string_cst>(
GET_NODE(init_node))->strg.size()) ||
2493 (!GetPointer<constructor>(
GET_NODE(init_node)) && !GetPointer<string_cst>(
GET_NODE(init_node)))))
2495 std::vector<std::string> init_string;
2496 write_init(TM, ar_node, init_node, init_string, mem, element_align);
2497 if(is_sds && (element_align == 0 || elts_size == element_align))
2499 THROW_ASSERT(!is_memory_splitted,
"unexpected condition");
2500 for(
const auto& init_value : init_string)
2503 if(elts_size != init_value.size() && (init_value.size() % elts_size == 0))
2505 const auto n_elmts = init_value.size() / elts_size;
2508 init_file_a << init_value.substr(init_value.size() - elts_size -
index * elts_size, elts_size)
2514 init_file_a << init_value << std::endl;
2520 std::vector<std::string> eightbit_string;
2521 std::string bits_offset =
"";
2522 for(
unsigned int l = 0; l < init_string.size(); ++l)
2524 if(init_string[l].size() < 8 && init_string.size() == 1)
2526 std::string res = init_string[l];
2527 while(res.size() < 8)
2531 eightbit_string.push_back(res);
2535 std::string local_binary_string;
2536 size_t local_data_bitsize;
2537 size_t data_bitsize = init_string[l].size();
2538 if(bits_offset.size())
2540 if(static_cast<int>(data_bitsize) - 8 +
static_cast<int>(bits_offset.size()) >= 0)
2542 local_data_bitsize = data_bitsize - (8 - bits_offset.size());
2543 eightbit_string.push_back(
2544 init_string[l].substr(data_bitsize - (8 - bits_offset.size()), 8 - bits_offset.size()) +
2546 local_binary_string = init_string[l].substr(0, local_data_bitsize);
2551 local_data_bitsize = 0;
2552 bits_offset = init_string[l] + bits_offset;
2557 local_binary_string = init_string[l];
2558 local_data_bitsize = data_bitsize;
2560 for(
unsigned int base_index = 0; base_index < local_data_bitsize; base_index = base_index + 8)
2562 if((static_cast<int>(local_data_bitsize) - 8 - static_cast<int>(base_index)) >= 0)
2564 eightbit_string.push_back(local_binary_string.substr(local_data_bitsize - 8 - base_index, 8));
2568 bits_offset = local_binary_string.substr(0, local_data_bitsize - base_index);
2573 if(bits_offset.size())
2575 std::string tail_padding;
2576 for(
auto tail_padding_ind = bits_offset.size(); tail_padding_ind < 8; ++tail_padding_ind)
2578 tail_padding +=
"0";
2580 tail_padding = tail_padding + bits_offset;
2581 eightbit_string.push_back(tail_padding);
2583 if(eightbit_string.size() % nbyte_on_memory != 0)
2585 for(
size_t l = eightbit_string.size() % nbyte_on_memory; l < nbyte_on_memory; ++l)
2587 eightbit_string.push_back(
"00000000");
2590 if(static_cast<size_t>(
tree_helper::Size(array_type_node) / 8) > eightbit_string.size())
2592 size_t tail_bytes =
static_cast<size_t>(
tree_helper::Size(array_type_node) / 8) - eightbit_string.size();
2593 for(
size_t l = 0; l < tail_bytes; ++l)
2595 eightbit_string.push_back(
"00000000");
2599 std::string str_bit;
2600 bool is_even =
true;
2602 for(
unsigned int l = 0; l < eightbit_string.size();)
2605 for(counter = 0; counter < nbyte_on_memory && l < eightbit_string.size(); counter++, l++)
2607 str_bit = eightbit_string[l] + str_bit;
2609 if(is_even || !is_memory_splitted)
2611 init_file_a << str_bit << std::endl;
2615 init_file_b << str_bit << std::endl;
2619 if(!is_even && is_memory_splitted)
2621 bool need_newline_b =
false;
2622 for(
unsigned int l = 0; l < (nbyte_on_memory * 8); ++l)
2625 need_newline_b =
true;
2629 init_file_b << std::endl;
2638 THROW_ASSERT(!is_memory_splitted,
"unexpected condition");
2639 for(
unsigned int i = 0; i < vec_size; ++i)
2641 for(
unsigned int j = 0; j < elts_size; ++j)
2645 init_file_a << std::endl;
2651 bool is_even =
true;
2652 bool need_newline_a =
false;
2653 bool need_newline_b =
false;
2654 for(
unsigned int i = 0; i < vec_size; ++i)
2656 for(
unsigned int j = 0; j < elts_size; ++j)
2658 if(is_even || !is_memory_splitted)
2661 need_newline_a =
true;
2666 need_newline_b =
true;
2669 if(counter % (nbyte_on_memory * 8) == 0)
2671 if(is_even || !is_memory_splitted)
2673 init_file_a << std::endl;
2674 need_newline_a =
false;
2678 init_file_b << std::endl;
2679 need_newline_b =
false;
2685 if(counter % (nbyte_on_memory * 8) != 0)
2687 for(
auto l = counter % (nbyte_on_memory * 8); l < (nbyte_on_memory * 8); ++l)
2689 if(is_even || !is_memory_splitted)
2692 need_newline_a =
true;
2697 need_newline_b =
true;
2702 if(!is_even && is_memory_splitted)
2704 for(
unsigned int l = 0; l < (nbyte_on_memory * 8); ++l)
2707 need_newline_b =
true;
2712 init_file_a << std::endl;
2716 init_file_b << std::endl;
2723 std::vector<std::string>& init_file,
const memoryRef mem,
unsigned long long element_align)
2725 std::string trimmed_value;
2728 switch(init_node->get_kind())
2733 const auto rc = GetPointerS<const real_cst>(init_node);
2734 std::string C_value = rc->valr;
2736 init_file.push_back(trimmed_value);
2746 precision =
std::min(precision, element_align);
2748 for(
auto ind = 1
U; ind <= precision; ind++)
2750 trimmed_value.push_back(((
integer_cst_t(1) << (precision - ind)) & ull_value) ?
'1' :
'0');
2752 init_file.push_back(trimmed_value);
2758 const auto cc = GetPointerS<const complex_cst>(init_node);
2759 write_init(TreeM, var_node, cc->real, init_file, mem, precision / 2);
2760 write_init(TreeM, var_node, cc->imag, init_file, mem, precision / 2);
2765 const auto co = GetPointerS<const constructor>(init_node);
2766 bool designated_initializers_used =
false;
2767 bool is_struct =
false;
2768 bool is_union =
false;
2769 unsigned long long union_size = 0;
2770 std::vector<tree_nodeRef>* field_list =
nullptr;
2772 if(co->list_of_idx_valu.size() &&
GET_NODE(co->list_of_idx_valu.front().first)->get_kind() == field_decl_K)
2774 auto iv_it = co->list_of_idx_valu.begin();
2775 const auto iv_end = co->list_of_idx_valu.end();
2776 const auto scpe =
GET_NODE(GetPointerS<field_decl>(
GET_NODE(iv_it->first))->scpe);
2778 if(scpe->get_kind() == record_type_K)
2780 field_list = &GetPointerS<record_type>(scpe)->list_of_flds;
2784 else if(scpe->get_kind() == union_type_K)
2786 field_list = &GetPointerS<union_type>(scpe)->list_of_flds;
2792 THROW_ERROR(
"expected a record_type or a union_type");
2794 auto fl_it = field_list->begin();
2795 const auto fl_end = field_list->end();
2796 for(; fl_it != fl_end && iv_it != iv_end; ++iv_it, ++fl_it)
2803 if(fl_it != fl_end && is_struct)
2805 designated_initializers_used =
true;
2809 const auto main_element_align = element_align;
2810 if(designated_initializers_used)
2813 auto fli = field_list->begin();
2814 const auto flend = field_list->end();
2815 auto iv_it = co->list_of_idx_valu.begin();
2816 const auto iv_end = co->list_of_idx_valu.end();
2817 for(; fli != flend; ++fli)
2819 if(!GetPointer<field_decl>(
GET_NODE(*fli)))
2823 const auto is_bitfield = GetPointer<field_decl>(
GET_NODE(*fli))->is_bitfield();
2826 while(inext != flend && !GetPointer<field_decl>(
GET_NODE(*inext)))
2840 write_init(TreeM, iv_it->first, iv_it->second, init_file, mem, element_align);
2845 write_init(TreeM, *fli, *fli, init_file, mem, element_align);
2851 element_align = main_element_align;
2857 unsigned long long int nbits;
2860 const auto idx_next_fd = GetPointerS<field_decl>(
GET_NODE(*inext));
2868 const auto idx_curr_fd = GetPointer<field_decl>(
GET_NODE(*fli));
2876 init_file.push_back(std::string(nbits,
'0'));
2883 auto iv_it = co->list_of_idx_valu.begin();
2884 const auto iv_end = co->list_of_idx_valu.end();
2885 for(; iv_it != iv_end; ++iv_it)
2887 if(is_struct && !GetPointer<field_decl>(
GET_NODE(iv_it->first)))
2891 const auto is_bitfield = is_struct && GetPointer<field_decl>(
GET_NODE(iv_it->first))->is_bitfield();
2892 auto iv_next = iv_it;
2894 while(iv_next != iv_end && is_struct && !GetPointer<field_decl>(
GET_NODE(iv_next->first)))
2898 if(is_struct && is_bitfield)
2904 write_init(TreeM, iv_it->first, iv_it->second, init_file, mem, element_align);
2905 if(is_struct && is_bitfield)
2908 element_align = main_element_align;
2911 if(is_struct && !is_bitfield)
2914 unsigned long long int nbits;
2915 if(iv_next != iv_end)
2917 const auto idx_next_fd = GetPointerS<field_decl>(
GET_NODE(iv_next->first));
2926 const auto idx_curr_fd = GetPointerS<field_decl>(
GET_NODE(iv_it->first));
2933 init_file.push_back(std::string(nbits,
'0'));
2939 THROW_ASSERT(co->list_of_idx_valu.size() == 1,
"just one initializer is possible");
2942 const auto nbits = union_size - field_decl_size;
2946 init_file.push_back(std::string(nbits,
'0'));
2954 unsigned long long size_of_data;
2955 std::vector<unsigned long long> dims;
2959 size_of_data =
std::min(size_of_data, element_align);
2961 auto num_elements = dims[0];
2962 if(num_elements < co->list_of_idx_valu.size())
2964 THROW_ERROR(
"C description not supported: Array with undefined size or not correctly initialized " +
2965 STR(co->list_of_idx_valu.size()) +
"-" +
STR(num_elements));
2967 THROW_ASSERT(num_elements >= static_cast<unsigned long long>(co->list_of_idx_valu.size()),
"");
2968 num_elements -=
static_cast<unsigned long long>(co->list_of_idx_valu.size());
2969 init_file.insert(init_file.end(), num_elements, std::string(size_of_data,
'0'));
2975 const auto sc = GetPointerS<const string_cst>(init_node);
2976 const auto string_value = [&]() {
2978 const char* c_str = sc->strg.c_str();
2981 if(c_str[
index] ==
'\\' && c_str[
index + 1] ==
'0')
2988 tmp += c_str[
index];
2991 boost::replace_all(tmp,
"\\a",
"\a");
2992 boost::replace_all(tmp,
"\\b",
"\b");
2993 boost::replace_all(tmp,
"\\t",
"\t");
2994 boost::replace_all(tmp,
"\\n",
"\n");
2995 boost::replace_all(tmp,
"\\v",
"\v");
2996 boost::replace_all(tmp,
"\\f",
"\f");
2997 boost::replace_all(tmp,
"\\r",
"\r");
2998 boost::replace_all(tmp,
"\\'",
"'");
2999 boost::replace_all(tmp,
"\\\"",
"\"");
3000 boost::replace_all(tmp,
"\\\\",
"\\");
3003 unsigned long long elmt_bitsize;
3004 std::vector<unsigned long long> dims;
3007 if(elmt_bitsize != 8)
3009 THROW_ERROR(
"non-standard 8-bit char conversion not supported");
3011 for(
const auto j : string_value)
3013 auto ull_value =
static_cast<unsigned long int>(j);
3015 for(
auto ind = 0
U; ind < elmt_bitsize; ++ind)
3017 trimmed_value = trimmed_value + (((1LLU << (elmt_bitsize - ind - 1)) & ull_value) ?
'1' :
'0');
3019 init_file.push_back(trimmed_value);
3022 init_file.push_back(std::string(elmt_bitsize,
'0'));
3027 unsigned long long size_of_data;
3029 THROW_ASSERT(size_of_data == elmt_bitsize,
"something wrong happened");
3030 auto num_elements = std::accumulate(dims.begin(), dims.end(), 1ULL,
3031 [](
unsigned long long a,
unsigned long long b) {
return a * b; });
3033 if(num_elements < (string_value.size() + 1))
3035 THROW_ERROR(
"C description not supported: string with undefined size or not correctly initialized " +
3036 STR(string_value.size() + 1) +
"-" +
STR(num_elements));
3038 num_elements -= string_value.size() + 1;
3039 init_file.insert(init_file.end(), num_elements, std::string(size_of_data,
'0'));
3042 case view_convert_expr_K:
3045 const auto ue = GetPointerS<unary_expr>(init_node);
3046 if(GetPointer<addr_expr>(
GET_NODE(ue->op)))
3048 write_init(TreeM, ue->op, ue->op, init_file, mem, element_align);
3050 else if(GetPointer<integer_cst>(
GET_NODE(ue->op)))
3052 const auto precision =
3054 write_init(TreeM, ue->op, ue->op, init_file, mem, precision);
3058 THROW_ERROR(
"Something unexpected happened: " +
STR(init_node->index) +
" | " +
3059 GET_NODE(ue->op)->get_kind_text());
3065 auto* ae = GetPointerS<addr_expr>(init_node);
3068 unsigned long long int ull_value = 0;
3070 switch(addr_expr_op->get_kind())
3083 const auto ar = GetPointerS<array_ref>(addr_expr_op);
3084 if(GetPointer<integer_cst>(
GET_NODE(ar->op1)))
3086 switch(
GET_NODE(ar->op0)->get_kind())
3102 case aggr_init_expr_K:
3103 case case_label_expr_K:
3105 case identifier_node_K:
3106 case statement_list_K:
3108 case target_mem_ref_K:
3109 case target_mem_ref461_K:
3129 case function_decl_K:
3131 case namespace_decl_K:
3133 case translation_unit_decl_K:
3137 case template_decl_K:
3139 THROW_ERROR(
"addr_expr-array_ref[0] pattern not supported: " +
3140 std::string(addr_expr_op->get_kind_text()) +
" @" +
STR(addr_expr_op_idx));
3145 THROW_ERROR(
"addr_expr-array_ref[0] pattern not supported: " +
3146 std::string(addr_expr_op->get_kind_text()) +
" @" +
STR(addr_expr_op_idx));
3150 case function_decl_K:
3158 if(addr_expr_op->get_kind() == mem_ref_K)
3160 const auto mr = GetPointerS<mem_ref>(addr_expr_op);
3161 const auto op1 =
GET_NODE(mr->op1);
3162 if(op1->get_kind() == integer_cst_K)
3180 std::string(addr_expr_op->get_kind_text()) +
" @" +
STR(addr_expr_op_idx));
3185 THROW_ERROR(
"addr_expr pattern not supported: " + std::string(addr_expr_op->get_kind_text()) +
3186 " @" +
STR(addr_expr_op_idx));
3191 THROW_ERROR(
"addr_expr pattern not supported: " + std::string(addr_expr_op->get_kind_text()) +
3192 " @" +
STR(addr_expr_op_idx));
3197 THROW_ERROR(
"addr_expr pattern not supported: " + std::string(addr_expr_op->get_kind_text()) +
" @" +
3198 STR(addr_expr_op_idx));
3202 case array_range_ref_K:
3204 case bit_field_ref_K:
3207 case aggr_init_expr_K:
3208 case case_label_expr_K:
3210 case component_ref_K:
3214 case dot_prod_expr_K:
3215 case ternary_plus_expr_K:
3216 case ternary_pm_expr_K:
3217 case ternary_mp_expr_K:
3218 case ternary_mm_expr_K:
3221 case insertvalue_expr_K:
3222 case insertelement_expr_K:
3223 case bit_ior_concat_expr_K:
3225 case identifier_node_K:
3228 case namespace_decl_K:
3229 case obj_type_ref_K:
3233 case statement_list_K:
3235 case target_mem_ref_K:
3236 case target_mem_ref461_K:
3237 case translation_unit_decl_K:
3238 case template_decl_K:
3244 case vec_cond_expr_K:
3245 case vec_perm_expr_K:
3249 case with_cleanup_expr_K:
3258 THROW_ERROR(
"addr_expr pattern not supported: " + std::string(addr_expr_op->get_kind_text()) +
" @" +
3259 STR(addr_expr_op_idx));
3261 for(
unsigned int ind = 0; ind < precision; ind++)
3263 trimmed_value = trimmed_value + (((1LLU << (precision - ind - 1)) & ull_value) ?
'1' :
'0');
3265 init_file.push_back(trimmed_value);
3274 init_file.push_back(std::string(field_decl_size,
'0'));
3280 const auto vc = GetPointerS<vector_cst>(init_node);
3281 for(
const auto& i : vc->list_of_valu)
3283 write_init(TreeM, i, i, init_file, mem, element_align);
3291 case aggr_init_expr_K:
3292 case case_label_expr_K:
3293 case identifier_node_K:
3296 case statement_list_K:
3297 case target_mem_ref_K:
3298 case target_mem_ref461_K:
3302 case function_decl_K:
3304 case namespace_decl_K:
3307 case translation_unit_decl_K:
3308 case template_decl_K:
3314 case alignof_expr_K:
3316 case bit_not_expr_K:
3319 case cleanup_point_expr_K:
3321 case convert_expr_K:
3323 case fix_ceil_expr_K:
3324 case fix_floor_expr_K:
3325 case fix_round_expr_K:
3326 case fix_trunc_expr_K:
3328 case imagpart_expr_K:
3329 case indirect_ref_K:
3330 case misaligned_indirect_ref_K:
3333 case non_lvalue_expr_K:
3334 case realpart_expr_K:
3335 case reference_expr_K:
3336 case reinterpret_cast_expr_K:
3338 case static_cast_expr_K:
3341 case truth_not_expr_K:
3344 case reduc_max_expr_K:
3345 case reduc_min_expr_K:
3346 case reduc_plus_expr_K:
3347 case vec_unpack_hi_expr_K:
3348 case vec_unpack_lo_expr_K:
3349 case vec_unpack_float_hi_expr_K:
3350 case vec_unpack_float_lo_expr_K:
3361 THROW_ERROR(
"elements not yet supported: " + init_node->get_kind_text() + init_node->ToString() +
3362 (var_node ?
STR(var_node) :
""));
3368 THROW_ASSERT(GetPointer<addr_expr>(exp) || GetPointer<ssa_name>(exp),
"Input must be a ssa_name or an addr_expr");
3369 auto* sa = GetPointer<ssa_name>(
exp);
3376 auto* var = GetPointer<decl_node>(
GET_NODE(sa->var));
3377 THROW_ASSERT(var,
"Call expression does not point to a declaration node");
3378 pt = GetPointer<pointer_type>(
GET_NODE(var->type));
3382 pt = GetPointer<pointer_type>(
GET_NODE(sa->type));
3385 THROW_ASSERT(pt,
"Declaration node has not information about pointer_type");
3387 "Pointer type has not information about pointed function_type");
3392 auto* AE = GetPointer<addr_expr>(
exp);
3393 auto*
FD = GetPointer<function_decl>(
GET_NODE(AE->op));
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
std::string convert_fp_to_string(std::string num, unsigned long long precision)
convert a real number stored in a string into a string of bits with a given precision ...
tree_nodeRef ptd
ptd field points to the node for the type pointed to.
static void propagate_memory_parameters(const structural_objectRef src, const structural_managerRef tgt)
Propagates the memory parameters from the source (innermost) module to the target (outermost) one...
void add_connection(structural_objectRef src, structural_objectRef dest)
Create a connection between a source structural object and a destination structural object...
#define CHANNELS_TYPE_MEM_ACC_N1
#define PRESENT_STATE_PORT_NAME
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
static bool IsUnionType(const tree_nodeConstRef &type)
Return if treenode is an union.
static bool IsComplexType(const tree_nodeConstRef &type)
Return if treenode is a complex.
Data structure representing the entire HLS information.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
void check_parametrization(structural_objectRef curr_gate)
check the module parametrization
int debug_level
The debug level.
static std::string name_function(const tree_managerConstRef &tm, const unsigned int index)
Return the name of the function.
#define GET_TYPE(data, vertex_index)
Helper macro returning the type associated with a node.
static unsigned long long AccessedMaximumBitsize(const tree_nodeConstRef &type_node, unsigned long long bitsize)
return the maximum bitsize associated with the elements accessible through type_node ...
refcount< structural_type_descriptor > structural_type_descriptorRef
RefCount type definition of the structural_type_descriptor class structure.
#define PRINT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
#define NEXT_STATE_PORT_NAME
generic_objRef get(const vertex v) const
Returns reference to funit object associated with this vertex.
#define FLOAT_EXPR
constant string identifying integer to float conversions
#define DEBUG_LEVEL_PEDANTIC
very verbose debugging print is performed.
#define CHANNELS_TYPE_MEM_ACC_NN
structural_managerRef datapath
Store the datapath description.
Structure representing the most relevant information about the type of a structural object...
tree_nodeRef getFunctionType(tree_nodeRef exp)
#define CASE_BINARY_EXPRESSION
This macro collects all case labels for binary_expr objects.
const ParameterConstRef Param
class containing all the parameters
const std::string & get_id() const
Return the identifier associated with the structural_object.
std::map< unsigned int, unsigned int > allocation_map
map between functional unit id and number of units allocated
refcount< fu_binding > fu_bindingRef
RefCount type definition of the fu_binding class structure.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
char base
This version is stamped on May 10, 2016.
const structural_objectRef get_circ() const
Get a reference to circ field.
static bool IsArrayEquivType(const tree_nodeConstRef &type)
Return true if treenode is an array or it is equivalent to an array (record recursively having a sing...
static bool is_a_misaligned_vector(const tree_managerConstRef &TM, const unsigned int index)
Return true if the treenode index is a a misaligned access to a vector data object.
static fu_bindingRef create_fu_binding(const HLS_managerConstRef _HLSMgr, const unsigned int _function_id, const ParameterConstRef _parameters)
create_fu_binding: factory method for fu_binding
Datastructure to represent a memory symbol in HLS.
mathematical utility function not provided by standard libraries
#define INDENT_OUT_MEX(outLevel, curOutLevel, mex)
generic_objRef get_port(unsigned int var, direction_type dir)
Returns reference to generic object associated to a given variable, for a specific port direction...
unsigned int get_assign(const vertex &v) const
Returns the functional unit assigned to the vertex.
static tree_nodeConstRef CGetElements(const tree_nodeConstRef &type)
Given an array or a vector return the element type.
#define GET_NAME(data, vertex_index)
Helper macro returning the name associated with a node.
const structural_objectRef get_out_sign() const
Gets structural_object of output signal associated to this object.
const HLS_deviceRef HLS_D
reference to the information representing the target for the synthesis
structural_objectRef add_gate(const HLS_managerRef HLSMgr, const hlsRef HLS, const technology_nodeRef fu, const std::string &name, const OpVertexSet &ops, structural_objectRef clock_port, structural_objectRef reset_port) const
Add an instance of the current port.
const funit_obj & operator[](const vertex &v)
Redefinition of the [] operator.
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...
#define BUILTIN_WAIT_CALL
constant defining the builtin wait call intrinsic function
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.
#define MEMORY_TYPE_SYNCHRONOUS_SDS_BUS
#define GET_INDEX_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
#define LIBRARY_STD_FU
standard library where all standard HLS resources are defined
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)
const tree_managerConstRef TreeM
information about the tree data-structure
void set_structural_obj(const structural_objectRef &SM_)
Sets structural_object associated to this object.
Class specification of the manager of the technology library data structures.
all objects that need to be stored in memory are allocated on an external memory
std::string NumberToBinaryString(const T number, const size_t precision=0)
Function which print number in binary format.
unsigned long long int get_base_address(unsigned int var, unsigned int funId) const
Get the current base address of the given variable.
std::string get_fu_name(vertex const &v) const
Returns the name of the functional unit.
#define OUTPUT_LEVEL_MINIMUM
minimum debugging print is performed.
static bool IsEnumType(const tree_nodeConstRef &type)
Return if treenode index is an enumeral type.
bool operator()(const structural_objectRef &a, const structural_objectRef &b) const
#define GET_TYPE_NAME(structural_obj)
Macro returning the string name of a type.
Derived class to add module scheduler, mem_ctrl_parallel and bind correctly the channels.
std::map< std::pair< unsigned int, unsigned int >, generic_objRef > unique_table
map between unit and allocated objects
#define MEMORY_TYPE_ASYNCHRONOUS
#define TYPE_LOAD
Constant string identifying a memory load operation.
static void write_init(const tree_managerConstRef TreeM, tree_nodeRef var_node, tree_nodeRef init_node, std::vector< std::string > &init_file, const memoryRef mem, unsigned long long element_precision)
A set of operation vertices.
void kill_proxy_function_units(std::map< unsigned int, std::string > &wrapped_units, structural_objectRef curr_gate, std::map< std::string, std::list< structural_objectRef >> &fun_call_sites_rel, std::map< std::string, unsigned int > &reverse_wrapped_units)
virtual enum kind get_kind() const =0
Virtual function returning the type of the actual class.
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
static void add_memory_parameter(const structural_managerRef SM, const std::string &name, const std::string &value)
Adds the given memory parameter to the corresponding object.
void kill_proxy_memory_units(std::map< unsigned int, unsigned int > &memory_units, structural_objectRef curr_gate, std::map< unsigned int, std::list< structural_objectRef >> &var_call_sites_rel, std::map< unsigned int, unsigned int > &reverse_memory_units)
fix port properties for proxy memory ports
s_type type
The type of the port or the signal.
port_direction
Enumerative type describing the direction of a port.
bool is_assigned(const vertex &v) const
return true in case the vertex has been previously assigned
std::string ToString(ActorGraphBackend_Type actor_graph_backend_type)
Header include.
void specialize_memory_unit(const HLS_managerRef HLSMgr, const hlsRef HLS, structural_objectRef fu_obj, unsigned int ar, const std::string &base_address, unsigned long long rangesize, bool is_memory_splitted, bool is_sparse_memory, bool is_sds)
Specialize a memory unit.
#define CLOCK_PORT_NAME
standard name for ports
static void fill_array_ref_memory(std::ostream &init_file_a, std::ostream &init_file_b, unsigned int ar, unsigned long long &vec_size, unsigned long long &elts_size, const memoryRef mem, tree_managerConstRef TM, bool is_sds, unsigned long long bitsize_align)
fill the memory of the array ref
bool is_all_regs_without_enable()
return true when all registers are without write enable: pipelining comes for free ...
#define MEMORY_TYPE_SYNCHRONOUS_UNALIGNED
bool registered_inputs
true when the module has registered inputs
const OpNodeInfoConstRef CGetOpNodeInfo(const vertex node) const
Returns the info associated with a node.
virtual std::string get_kind_text() const =0
Virtual function used to get the string name of a structural_object instance.
std::string convert_to_binary(G _value, unsigned long long precision)
fu_bindingRef Rfu
Store the refcounted functional unit binding of the operations.
bool starts_with(const std::string &str, const std::string &pattern)
const OpGraphConstRef op_graph
The operation graph.
Data structure used to store the register binding of variables.
static unsigned long long Size(const tree_nodeConstRef &tn)
Return the size of a tree object.
std::map< std::pair< unsigned int, unsigned int >, OpVertexSet > operations
reverse map that associated each functional unit with the set of operations that are executed ...
std::set< Key, Compare, Alloc > OrderedSetStd
void manage_killing_memory_proxies(std::map< unsigned int, structural_objectRef > &mem_obj, std::map< unsigned int, unsigned int > &reverse_memory_units, std::map< unsigned int, std::list< structural_objectRef >> &var_call_sites_rel, const structural_managerRef SM, const hlsRef HLS, unsigned int &_unique_id)
connect proxies with storage components
static bool IsBooleanType(const tree_nodeConstRef &type)
Return true if the treenode is of bool type.
unsigned map[NUM_VERTICES]
unsigned int get_number(unsigned int unit) const
Returns number of functional unit allocated.
Data structure used to store the interconnection binding of datapath elements.
#define CASE_QUATERNARY_EXPRESSION
This macro collects all case labels for quaternary_expr objects.
#define CASE_UNARY_EXPRESSION
This macro collects all case labels for unary_expr objects.
all global variables, static variables and strings are allocated on BRAMs
This class writes different HDL based descriptions (VHDL, Verilog, SystemC) starting from a structura...
Class specification of the data structures used to manage technology information. ...
const std::string get_path() const
Return a unique identifier of the structural object.
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.
static bool resize_if_busport(unsigned long long bus_size_bitsize, unsigned long long bus_addr_bitsize, unsigned long long bus_data_bitsize, unsigned long long bus_tag_bitsize, structural_objectRef port)
auxiliary function used to resize the bus ports with respect to their associated bus size ...
static integer_cst_t get_integer_cst_value(const integer_cst *ic)
Convert a integer_cst in a long long value.
void update_allocation(unsigned int unit, unsigned int number)
Update number of allocated units.
int output_level
verbosity level of the class
void bind(const vertex &v, unsigned int unit, unsigned int index=std::numeric_limits< unsigned int >::max())
Binds an operation vertex to a functional unit.
#define flipflop_AR
flipflop with asynchronous reset
redefinition of set to manage ordered/unordered structures
#define LIBRARY_STD
standard library where all built-in ports are defined.
Datastructure to describe functions allocation in high-level synthesis.
#define TYPE_STORE
Constant string identifying a memory store operation.
#define MEMORY_TYPE_SYNCHRONOUS_SDS
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
utility function used to read files.
static bool IsVectorType(const tree_nodeConstRef &type)
Return true if the treenode is a vector.
unsigned offset[NUM_VERTICES+1]
virtual ~fu_binding()
Destructor.
constexpr T get_aligned_bitsize(T bitsize)
static void fix_port_properties(structural_objectRef port_i, structural_objectRef cir_port)
copy the port properties from port_i to cir_port
static std::string GetFUName(const std::string &fname, const HLS_managerRef HLSMgr)
Return FU used to implement given function.
#define GET_CONST_NODE(t)
virtual enum so_kind get_kind() const =0
Virtual function used to find the real type of a structural_object instance.
Classes specification of the tree_node data structures.
static std::string NormalizeTypename(const std::string &id)
Return normalized name of types and variables.
This file collects some utility functions and macros.
Base class to allocate memories in high-level synthesis.
#define DEBUG_LEVEL_NONE
no debugging print is performed.
reg_bindingRef Rreg
Store the refcounted register binding of the variables.
std::list< unsigned int > get_allocation_list() const
Returns the set of allocated unit.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
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)
struct definition of the pointer_type tree node.
static const unsigned int UNKNOWN
The value used to identified unknown functional unit.
Class representing functional units in the datapath.
void type_resize(unsigned long long new_bit_size)
Just resize the size of the bits of the object.
#define CASE_TYPE_NODES
This macro collects all case labels for type objects.
This file collects some utility functions.
void specialise_fu(const HLS_managerRef HLSMgr, const hlsRef HLS, structural_objectRef fu_obj, unsigned int fu, const OpVertexSet &operations, unsigned int ar)
Specialize the functional unit based on variables associated with the corresponding operations...
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.
void set_ports_are_swapped(vertex v, bool condition)
specify if vertex v have or not its ports swapped
AllocationInformationRef allocation_information
allocation manager. Used to retrieve the string name of the functional units.
for each memory at maximum n parallel direct accesses and one indirect access
static tree_nodeConstRef GetBaseVariable(const tree_nodeConstRef &mem)
Retrun the base variable of a memory access.
This class describes all classes used to represent a structural object.
virtual bool manage_module_ports(const HLS_managerRef HLSMgr, const hlsRef HLS, const structural_managerRef SM, const structural_objectRef curr_gate, unsigned int num)
bool has_resource_sharing_p
useful to know for automatic pipelining
const structural_type_descriptorRef & get_typeRef() const
Return the type descriptor of the structural_object.
structural_managerRef control_flow_checker
Store the description of the control flow checker.
std::string GetPath(std::filesystem::path path)
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)
std::map< unsigned int, generic_objRef > op_binding
operation binding
struct definition of the type node structures.
Class specification of the tree_reindex support class.
#define CASE_FAKE_NODES
This macro collects all case labels for fake or empty nodes.
void set_id(const std::string &s)
Set the identifier associated with the structural_object.
static structural_objectRef add_sign(std::string id, structural_objectRef owner, structural_type_descriptorRef sign_type, unsigned int treenode=0)
Create a new signal.
bool has_base_address(unsigned int var) const
Check if there is a base address for the given variable.
Data structure used to store the functional-unit binding of the vertexes.
#define WORK_LIBRARY
working library.
#define INFINITE_UINT
UNSIGNED INT representing infinite.
virtual void copy(structural_objectRef dest) const
Perform a copy of the structural object.
void manage_killing_function_proxies(std::map< unsigned int, structural_objectRef > &fun_obj, std::map< std::string, unsigned int > &reverse_function_units, std::map< std::string, std::list< structural_objectRef >> &fun_call_sites_rel, const structural_managerRef SM, const hlsRef HLS, unsigned int &_unique_id)
static void change_port_direction(structural_objectRef port_object, port_o::port_direction pdir, structural_objectRef owner)
Change the direction of the port.
int original[DIMENSION_Y][DIMENSION_X]
refcount< structural_object > structural_objectRef
RefCount type definition of the structural_object class structure.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
static tree_nodeConstRef CGetType(const tree_nodeConstRef &node)
Return the treenode of the type of node.
static bool IsStructType(const tree_nodeConstRef &type)
Return true if treenode is a record.
#define DONE_PORT_NAME_CFC
this class is used to manage the command-line or XML options.
#define CASE_CPP_NODES
This macro collects all case labels for cpp nodes.
static void manage_memory_ports_chained(const structural_managerRef SM, const std::list< structural_objectRef > &memory_modules, const structural_objectRef circuit)
Manage the connections between memory ports.
unsigned int functionId
this is the identifier of the function to be implemented
Class implementation of the structural_manager.
This class describes a generic component.
OpVertexSet get_operations(unsigned int unit, unsigned int index) const
Return the operations that are executed by the given functional unit.
unsigned counter[N_THREADS]
Class managing the functional-unit binding.
Class specification of the manager for each library.
static void resize_std_port(unsigned long long bitsize_variable, unsigned long long n_elements, int debug_level, structural_objectRef port)
auxiliary function used to resize the standard ports
#define CASE_GIMPLE_NODES
This macro collects all cases labels for gimple nodes.
static integer_cst_t GetConstValue(const tree_nodeConstRef &tn, bool is_signed=true)
Get value from integer constant.
const ParameterConstRef parameters
The set of input parameters.
std::vector< technology_nodeRef > operation_vec
Type definition of a vector of functional_unit.
int fun(float *A, float *invA, float *b, float *x, float *I)
#define GET_INDEX_CONST_NODE(t)
Datastructure to describe functions allocation in high-level synthesis.
Base class for all register into datapath.
#define flipflop_SR
flipflop with synchronous reset
static bool IsPointerType(const tree_nodeConstRef &type)
Return true if treenode index is a pointer.
CustomOrderedSet< vertex > ports_are_swapped
port assignment: ports are swapped predicate
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.
conn_bindingRef Rconn
Store the refcounted interconnection of datapath elements.
Datastructure to represent memory information in high-level synthesis.
#define PROXY_LIBRARY
proxy library
fu_binding(const HLS_managerConstRef _HLSMgr, const unsigned int function_id, const ParameterConstRef parameters)
Constructor.
unsigned int get_index(const vertex &v) const
Returns the index of functional unit assigned to the vertex.
#define CASE_TERNARY_EXPRESSION
This macro collects all case labels for ternary_expr objects.
Class specification of the manager of the tree structures extracted from the raw file.
refcount< generic_obj > generic_objRef
RefCount definition for generic_obj class.
HLS specialization of generic_device.
#define START_PORT_NAME_CFC
void copy(structural_type_descriptorRef dest)
Method that copies the contents of the current structural_type_descriptorRef into another structural_...
static bool IsRealType(const tree_nodeConstRef &type)
Return true if the treenode is of real type.
#define STD_GET_SIZE(structural_obj)
Macro returning the size of a type.
static structural_objectRef add_sign_vector(std::string id, unsigned int n_signs, structural_objectRef owner, structural_type_descriptorRef sign_type, unsigned int treenode=0)
static void get_array_dim_and_bitsize(const tree_managerConstRef &TM, const unsigned int index, std::vector< unsigned long long > &dims, unsigned long long &elts_bitsize)
Return the dimension of the array.
#define CASE_PRAGMA_NODES
This macro collects all case labels for pragma objects.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...