52 #include "config_HAVE_EXPERIMENTAL.hpp" 53 #include "config_HAVE_FLOPOCO.hpp" 97 const auto p = GetPointer<port_o>(port);
98 return p->get_is_memory() or p->get_is_global() or p->get_is_extern() or
99 p->get_port_interface() != port_o::port_interface::PI_DEFAULT;
104 if(op_name ==
"mult_expr" || op_name ==
"widen_mult_expr" || op_name ==
"dot_prod_expr")
114 static inline std::string
encode_op_type(
const std::string& op_name,
const std::string& fu_supported_types)
116 return op_name +
":" + fu_supported_types;
119 static inline std::string
encode_op_type_prec(
const std::string& op_name,
const std::string& fu_supported_types,
120 node_kind_prec_infoRef node_info)
122 std::string op_type =
encode_op_type(op_name, fu_supported_types);
123 const size_t n_ins = node_info->input_prec.size();
124 for(
size_t ind = 0; ind < n_ins; ++ind)
126 if(node_info->base128_input_nelem[ind] == 0)
128 op_type +=
":" +
STR(node_info->input_prec[ind]);
132 op_type +=
":" +
STR(node_info->input_prec[ind]) +
":" +
STR(node_info->base128_input_nelem[ind]);
135 if(node_info->base128_output_nelem == 0)
137 op_type +=
":" +
STR(node_info->output_prec);
141 op_type +=
":" +
STR(node_info->output_prec) +
":" +
STR(node_info->base128_output_nelem);
147 const DesignFlowManagerConstRef _design_flow_manager,
const HLSFlowStep_Type _hls_flow_step_type)
148 :
HLSFunctionStep(_parameters, _HLSMgr, _funId, _design_flow_manager, _hls_flow_step_type)
177 switch(relationship_type)
181 if(!
parameters->getOption<
int>(OPT_gcc_openmp_simd))
210 if(!
parameters->getOption<
int>(OPT_gcc_openmp_simd))
212 const auto frontend_flow_step_factory = GetPointer<const FrontendFlowStepFactory>(
217 const auto design_flow_step =
219 design_flow_graph->CGetDesignFlowStepInfo(frontend_step)->design_flow_step :
220 frontend_flow_step_factory->CreateFunctionFrontendFlowStep(FrontendFlowStepType::BIT_VALUE,
funId);
221 relationship.insert(design_flow_step);
228 const std::string& bambu_provided_resource_)
231 std::string function_name;
232 bool build_proxy =
false;
233 bool build_wrapper =
false;
235 if(
HLSMgr->Rfuns->is_a_proxied_function(bambu_provided_resource))
237 if(
HLSMgr->Rfuns->is_a_shared_function(
funId, bambu_provided_resource))
240 build_wrapper =
true;
245 "expected a proxy module");
252 function_name = bambu_provided_resource;
256 "functional unit not yet synthesized: " + function_name +
"(" + library_name +
")");
257 current_fu = libraryManager->
get_fu(function_name);
258 THROW_ASSERT(current_fu,
"functional unit not yet synthesized: " + function_name +
"(" + library_name +
")");
259 const std::vector<technology_nodeRef>& op_vec = GetPointer<functional_unit>(current_fu)->get_operations();
260 bool has_current_op =
false;
262 std::string op_name = curr_op->
get_name();
263 for(
const auto& op_it : op_vec)
265 if(GetPointer<operation>(op_it)->get_name() == op_name)
267 has_current_op =
true;
274 auto* cop = GetPointer<operation>(op);
275 auto* ref_op = GetPointer<operation>(op_vec[0]);
276 cop->operation_name = op_name;
277 cop->time_m = ref_op->time_m;
278 #if HAVE_EXPERIMENTAL 279 cop->power_m = ref_op->power_m;
282 cop->bounded = ref_op->bounded;
285 GetPointer<functional_unit>(current_fu)->
add(op);
289 for(
const auto& op_it : op_vec)
291 if(GetPointer<operation>(op_it)->get_name() == op_name)
294 THROW_ASSERT(fu_ob,
"Functional unit not found for " + bambu_provided_resource);
295 auto* op_ob = GetPointer<operation>(fu_ob->get_operation(bambu_provided_resource));
296 GetPointer<operation>(op_it)->bounded = op_ob->bounded;
324 if(port_ck and clock)
331 if(port_rst and reset)
338 const std::string& orig_library_name)
342 "functional unit not yet synthesized: " + orig_fun_name +
"(" + orig_library_name +
")");
344 THROW_ASSERT(orig_fun,
"functional unit not yet synthesized: " + orig_fun_name +
"(" + orig_library_name +
")");
348 orig_top_obj->
set_id(orig_fun_name +
"_i");
349 const module* orig_fu_module = GetPointer<module>(orig_top_obj);
359 std::vector<structural_objectRef> op_ports;
360 for(
const auto& o : ops)
362 const std::string op_name = GetPointer<operation>(o)->get_name();
365 const std::string sel_port_name =
"sel_" + op_name;
375 wrapper_SM->add_port(sel_port_name, port_o::IN, wrapper_obj, bool_signal_type);
378 op_ports.push_back(new_sel_port);
383 wrapper_SM->add_sign(
"proxy_selector____out_sel", wrapper_obj, bool_signal_type);
384 if(!op_ports.empty())
388 wrapper_obj,
HLS->
HLS_D->get_technology_manager());
390 auto* port = GetPointer<port_o>(or_in);
391 port->add_n_ports(static_cast<unsigned int>(op_ports.size()), or_in);
392 unsigned int port_n = 0;
393 for(
const auto& p : op_ports)
395 wrapper_SM->add_connection(p, port->get_port(port_n));
399 wrapper_SM->add_connection(or_out, selector_signal);
402 auto inPortSize =
static_cast<unsigned int>(orig_fu_module->
get_in_port_size());
403 for(
unsigned int port_id = 0; port_id < inPortSize; port_id++)
406 const std::string port_name = curr_port->
get_id();
413 wrapper_SM->add_connection(wrapper_mem_port, wrapped_mem_port);
416 const std::string proxy_port_name =
PROXY_PREFIX + port_name;
418 const auto addwDataMux = [&](
const std::string
offset) {
430 HLS->
HLS_D->get_technology_manager());
432 GetPointer<port_o>(mux_in1)->type_resize(bitwidth_size);
434 GetPointer<port_o>(mux_in2)->type_resize(bitwidth_size);
436 GetPointer<port_o>(mux_out)->type_resize(bitwidth_size);
439 const std::string tmp_signal_name =
"muxed_in_" + port_name +
offset;
440 structural_objectRef proxied_in_signal = wrapper_SM->add_sign(tmp_signal_name, wrapper_obj, mux_out_type);
447 GetPointer<port_o>(proxied_call_port)->type_resize(bitwidth_size);
453 GetPointer<port_o>(local_call_port)->type_resize(bitwidth_size);
455 wrapper_SM->add_connection(mux_sel, selector_signal);
456 wrapper_SM->add_connection(mux_in1, local_call_port);
457 wrapper_SM->add_connection(mux_in2, proxied_call_port);
458 wrapper_SM->add_connection(mux_out, proxied_in_signal);
459 wrapper_SM->add_connection(proxied_in_signal, wrapped_fu_port);
468 for(
unsigned int pindex = 0; pindex < GetPointer<port_o>(curr_port)->get_ports_size(); ++pindex)
470 addwDataMux(
STR(pindex));
475 auto outPortSize =
static_cast<unsigned int>(orig_fu_module->
get_out_port_size());
476 for(
unsigned int currentPort = 0; currentPort < outPortSize; ++currentPort)
479 const std::string port_name = curr_port->
get_id();
484 wrapper_SM->add_connection(wrapper_mem_port, wrapped_mem_port);
487 const std::string proxy_port_name =
PROXY_PREFIX + port_name;
488 const auto addwData = [&](
const std::string
offset) {
506 GetPointer<port_o>(local_port)->type_resize(bitwidth_size);
507 GetPointer<port_o>(proxied_port)->type_resize(bitwidth_size);
508 const std::string tmp_signal_name =
"tmp_out_" + port_name +
offset;
509 structural_objectRef out_signal_tmp = wrapper_SM->add_sign(tmp_signal_name, wrapper_obj, wrapped_port_type);
510 wrapper_SM->add_connection(wrapped_fu_port, out_signal_tmp);
511 wrapper_SM->add_connection(out_signal_tmp, local_port);
512 wrapper_SM->add_connection(out_signal_tmp, proxied_port);
520 for(
unsigned int pindex = 0; pindex < GetPointer<port_o>(curr_port)->get_ports_size(); ++pindex)
522 addwData(
STR(pindex));
531 const std::string& orig_fun_name)
537 auto* fu_module = GetPointer<module>(fu_obj);
546 GetPointer<module>(wrapper_top)->set_description(
"Proxy wrapper for function: " + wrapped_fu_name);
547 GetPointer<module>(wrapper_top)->set_copyright(fu_module->get_copyright());
548 GetPointer<module>(wrapper_top)->set_authors(fu_module->get_authors());
549 GetPointer<module>(wrapper_top)->set_license(fu_module->get_license());
550 GetPointer<module>(wrapper_top)->set_multi_unit_multiplicity(fu_module->get_multi_unit_multiplicity());
557 auto inPortSize =
static_cast<unsigned int>(fu_module->get_in_port_size());
558 for(
unsigned int currentPort = 0; currentPort < inPortSize; ++currentPort)
561 const std::string port_name = curr_port->
get_id();
571 generated_port = CM->
add_port(port_name, port_o::IN, wrapper_top, curr_port->
get_typeRef());
573 curr_port->
copy(generated_port);
576 for(
unsigned int currentPort = 0; currentPort < inPortSize; ++currentPort)
581 const std::string port_name = curr_port->
get_id();
585 const std::string proxy_port_name =
PROXY_PREFIX + port_name;
593 proxy_generated_port = CM->
add_port(proxy_port_name, port_o::IN, wrapper_top, curr_port->
get_typeRef());
595 curr_port->
copy(proxy_generated_port);
596 GetPointer<port_o>(proxy_generated_port)->set_id(proxy_port_name);
601 auto outPortSize =
static_cast<unsigned int>(fu_module->get_out_port_size());
602 for(
unsigned int currentPort = 0; currentPort < outPortSize; ++currentPort)
605 const std::string port_name = curr_port->
get_id();
615 generated_port = CM->
add_port(port_name, port_o::OUT, wrapper_top, curr_port->
get_typeRef());
617 curr_port->
copy(generated_port);
620 for(
unsigned int currentPort = 0; currentPort < outPortSize; ++currentPort)
634 proxy_generated_port = CM->
add_port(proxy_port_name, port_o::OUT, wrapper_top, curr_port->
get_typeRef());
636 curr_port->
copy(proxy_generated_port);
637 GetPointer<port_o>(proxy_generated_port)->set_id(proxy_port_name);
643 orig_np_library.replace(0, orig_fun_name.size(), wrapped_fu_name);
646 fu_obj->set_owner(wrapper_top);
647 GetPointer<module>(wrapper_top)->add_internal_object(fu_obj);
649 " - Created proxy wrapper " + wrapped_fu_name +
" and added to library " +
PROXY_LIBRARY);
652 auto* wrapper_fu = GetPointer<functional_unit>(wrapper_tn);
653 auto* orig_fu = GetPointer<functional_unit>(techNode_obj);
654 wrapper_fu->ordered_attributes = orig_fu->ordered_attributes;
655 wrapper_fu->attributes = orig_fu->attributes;
656 wrapper_fu->clock_period = orig_fu->clock_period;
657 wrapper_fu->clock_period_resource_fraction = orig_fu->clock_period_resource_fraction;
658 wrapper_fu->area_m = orig_fu->area_m;
659 wrapper_fu->fu_template_name = orig_fu->fu_template_name;
660 wrapper_fu->fu_template_parameters = orig_fu->fu_template_parameters;
661 wrapper_fu->characterizing_constant_value = orig_fu->characterizing_constant_value;
662 wrapper_fu->memory_type = orig_fu->memory_type;
663 wrapper_fu->channels_type = orig_fu->channels_type;
664 wrapper_fu->memory_ctrl_type = orig_fu->memory_ctrl_type;
665 wrapper_fu->bram_load_latency = orig_fu->bram_load_latency;
667 for(
const auto& op : ops)
669 auto* current_op = GetPointer<operation>(op);
670 std::string op_name = current_op->
get_name();
672 auto* proxy_op = GetPointer<operation>(wrapper_fu->get_operation(op_name));
673 proxy_op->time_m = current_op->time_m;
674 proxy_op->commutative = current_op->commutative;
675 proxy_op->bounded = current_op->bounded;
676 proxy_op->supported_types = current_op->supported_types;
677 proxy_op->pipe_parameters = current_op->pipe_parameters;
681 auto* wrapper_fictious_op = GetPointer<operation>(wrapper_fu->get_operation(wrapped_fu_name));
693 auto* fu_module = GetPointer<module>(
top);
694 auto inPortSize =
static_cast<unsigned int>(fu_module->get_in_port_size());
695 auto outPortSize =
static_cast<unsigned int>(fu_module->get_out_port_size());
700 std::string sel_guard;
701 for(
const auto& op : ops)
703 auto* current_op = GetPointer<operation>(op);
704 std::string op_name = current_op->get_name();
709 std::string sel_port_name =
"sel_" + op_name;
713 CM->
add_port(sel_port_name, port_o::IN, top, b_type);
715 if(sel_guard.empty())
717 sel_guard = sel_port_name;
721 sel_guard =
"(" + sel_guard +
"|" + sel_port_name +
")";
725 std::string verilog_description;
726 for(
unsigned int currentPort = 0; currentPort < inPortSize; ++currentPort)
733 std::string port_name = curr_port->
get_id();
736 if(verilog_description.size())
738 verilog_description +=
"\n";
742 verilog_description = verilog_description +
"assign " +
PROXY_PREFIX + port_name +
" = " +
747 verilog_description = verilog_description +
"assign " +
PROXY_PREFIX + port_name +
" = " + sel_guard +
752 for(
unsigned int currentPort = 0; currentPort < outPortSize; ++currentPort)
759 std::string port_name = curr_port->
get_id();
760 if(verilog_description.size())
762 verilog_description +=
"\n";
764 verilog_description =
775 auto* fu_module = GetPointer<module>(
top);
776 auto inPortSize =
static_cast<unsigned int>(fu_module->get_in_port_size());
777 auto outPortSize =
static_cast<unsigned int>(fu_module->get_out_port_size());
782 std::string sel_guard;
783 for(
const auto& op : ops)
785 auto* current_op = GetPointer<operation>(op);
786 std::string op_name = current_op->get_name();
791 std::string sel_port_name =
"sel_" + op_name;
795 CM->
add_port(sel_port_name, port_o::IN, top, b_type);
797 if(sel_guard.empty())
803 sel_guard = sel_guard +
" or " +
fix_identifier(sel_port_name, writer);
807 sel_guard =
"(" + sel_guard +
") = '1'";
809 std::string VHDL_description;
810 VHDL_description +=
"begin";
811 for(
unsigned int currentPort = 0; currentPort < inPortSize; ++currentPort)
818 std::string port_name = curr_port->
get_id();
821 if(VHDL_description.size())
823 VHDL_description +=
"\n";
834 " <= " +
fix_identifier(port_name, writer) +
" when (" + sel_guard +
") else " +
839 for(
unsigned int currentPort = 0; currentPort < outPortSize; ++currentPort)
846 std::string port_name = curr_port->
get_id();
847 if(VHDL_description.size())
849 VHDL_description +=
"\n";
851 VHDL_description = VHDL_description +
fix_identifier(port_name, writer) +
879 const std::string& orig_fun_name)
881 const std::string proxied_fu_name =
PROXY_PREFIX + orig_fun_name;
885 auto* fu_module = GetPointer<module>(fu_obj);
894 GetPointer<module>(
top)->set_description(
"Proxy module for function: " + proxied_fu_name);
895 GetPointer<module>(
top)->set_copyright(fu_module->get_copyright());
896 GetPointer<module>(
top)->set_authors(fu_module->get_authors());
897 GetPointer<module>(
top)->set_license(fu_module->get_license());
898 GetPointer<module>(
top)->set_multi_unit_multiplicity(fu_module->get_multi_unit_multiplicity());
928 auto inPortSize =
static_cast<unsigned int>(fu_module->get_in_port_size());
929 auto outPortSize =
static_cast<unsigned int>(fu_module->get_out_port_size());
931 for(
unsigned int currentPort = 0; currentPort < inPortSize; ++currentPort)
939 const std::string port_name = curr_port->
get_id();
957 curr_port->
copy(generated_port);
961 for(
unsigned int currentPort = 0; currentPort < outPortSize; ++currentPort)
973 const std::string port_name = curr_port->
get_id();
983 curr_port->
copy(generated_port);
986 for(
unsigned int currentPort = 0; currentPort < inPortSize; ++currentPort)
994 const std::string port_name = curr_port->
get_id();
1004 const std::string proxied_port_name =
PROXY_PREFIX + port_name;
1012 proxy_generated_port = CM->
add_port(proxied_port_name, port_o::OUT, top, curr_port->
get_typeRef());
1014 curr_port->
copy(proxy_generated_port);
1015 GetPointer<port_o>(proxy_generated_port)->set_port_direction(port_o::OUT);
1016 GetPointer<port_o>(proxy_generated_port)->set_is_memory(
true);
1017 GetPointer<port_o>(proxy_generated_port)->set_id(proxied_port_name);
1021 for(
unsigned int currentPort = 0; currentPort < outPortSize; ++currentPort)
1037 proxy_generated_port =
1042 proxy_generated_port = CM->
add_port(proxied_port_name, port_o::IN, top, curr_port->
get_typeRef());
1044 curr_port->
copy(proxy_generated_port);
1045 GetPointer<port_o>(proxy_generated_port)->set_port_direction(port_o::IN);
1046 GetPointer<port_o>(proxy_generated_port)->set_is_memory(
true);
1047 GetPointer<port_o>(proxy_generated_port)->set_id(proxied_port_name);
1052 orig_np_library.replace(0, orig_fun_name.size(), proxied_fu_name);
1056 " - Created proxy module " + proxied_fu_name +
" and added to library " +
PROXY_LIBRARY);
1059 auto* proxy_fu = GetPointer<functional_unit>(proxy_tn);
1060 auto* orig_fu = GetPointer<functional_unit>(techNode_obj);
1061 proxy_fu->ordered_attributes = orig_fu->ordered_attributes;
1062 proxy_fu->attributes = orig_fu->attributes;
1063 proxy_fu->clock_period = orig_fu->clock_period;
1064 proxy_fu->clock_period_resource_fraction = orig_fu->clock_period_resource_fraction;
1065 proxy_fu->area_m = orig_fu->area_m;
1066 proxy_fu->fu_template_name = orig_fu->fu_template_name;
1067 proxy_fu->fu_template_parameters = orig_fu->fu_template_parameters;
1068 proxy_fu->characterizing_constant_value = orig_fu->characterizing_constant_value;
1069 proxy_fu->memory_type = orig_fu->memory_type;
1070 proxy_fu->channels_type = orig_fu->channels_type;
1071 proxy_fu->memory_ctrl_type = orig_fu->memory_ctrl_type;
1072 proxy_fu->bram_load_latency = orig_fu->bram_load_latency;
1074 for(
const auto& op : ops)
1076 auto* current_op = GetPointer<operation>(op);
1077 std::string op_name = current_op->
get_name();
1079 auto* proxy_op = GetPointer<operation>(proxy_fu->get_operation(op_name));
1080 proxy_op->time_m = current_op->time_m;
1081 proxy_op->commutative = current_op->commutative;
1082 proxy_op->bounded = current_op->bounded;
1083 proxy_op->supported_types = current_op->supported_types;
1084 proxy_op->pipe_parameters = current_op->pipe_parameters;
1088 auto* proxy_fictious_op = GetPointer<operation>(proxy_fu->get_operation(proxied_fu_name));
1098 bool proxy_constrained)
1101 "Specialized unit: " + (cur_fu->
get_name()) +
" in position: " +
STR(pos) +
1102 (proxy_constrained ?
"(proxy)" :
""));
1111 else if(proxy_constrained)
1118 "Constrained " +
STR(pos) +
"=" + cur_fu->
get_name() +
"->" +
STR(tech_constrain_value));
1127 std::string required_prec =
"";
1128 std::string template_suffix =
"";
1129 const size_t n_ins = node_info->input_prec.size();
1130 for(
size_t ind = 0; ind < n_ins; ++ind)
1132 if(node_info->base128_input_nelem[ind] == 0)
1134 required_prec +=
STR(node_info->input_prec[ind]) +
" ";
1135 template_suffix +=
STR(node_info->input_prec[ind]) +
"_";
1139 required_prec +=
STR(node_info->input_prec[ind]) +
" " +
STR(node_info->base128_input_nelem[ind]) +
" ";
1140 template_suffix +=
STR(node_info->input_prec[ind]) +
"_" +
STR(node_info->base128_input_nelem[ind]) +
"_";
1143 if(node_info->base128_output_nelem == 0)
1145 required_prec +=
STR(node_info->output_prec);
1146 template_suffix +=
STR(node_info->output_prec);
1150 required_prec +=
STR(node_info->output_prec) +
" " +
STR(node_info->base128_output_nelem);
1151 template_suffix +=
STR(node_info->output_prec) +
"_" +
STR(node_info->base128_output_nelem);
1153 std::string fu_template_parameters = GetPointer<functional_unit>(current_fu)->fu_template_parameters;
1154 if(!
starts_with(fu_template_parameters, required_prec))
1157 "---Not support required precision " +
STR(required_prec) +
"(" + fu_template_parameters +
")");
1163 "- fu_template_parameters: \"" + fu_template_parameters +
"\"");
1166 template_suffix, node_info->input_prec.size() > 1 ? node_info->input_prec[1] : node_info->input_prec[0]);
1169 if(pipeline_id.size())
1171 required_prec +=
" " + pipeline_id;
1174 if(required_prec != fu_template_parameters)
1177 "---" + required_prec +
" vs. " + fu_template_parameters);
1181 if(pipeline_id.empty())
1185 THROW_WARNING(
"No functional unit exists for the given clock period: the fastest unit will be used as " 1186 "multi-cycle unit (" +
1187 GetPointer<functional_unit>(current_fu)->fu_template_name +
1195 const std::string& memory_ctrl_type,
const std::string& channels_type)
1197 const auto& memory_type = GetPointer<functional_unit>(current_fu)->memory_type;
1198 const auto& bram_load_latency = GetPointer<functional_unit>(current_fu)->bram_load_latency;
1201 if(memory_type.size())
1207 if(channels_type.size() &&
1214 #if !HAVE_EXPERIMENTAL 1215 if(GetPointer<functional_unit>(current_fu)->functional_unit_name ==
"MEMORY_CTRL_P1N")
1221 const auto channel_type_to_be_used =
HLSMgr->CGetFunctionBehavior(
funId)->GetChannelsType();
1222 if(channels_type.size())
1224 switch(channel_type_to_be_used)
1265 bool are_operations_bounded = memory_ctrl_type.size();
1267 const auto it_o_end = Operations.end();
1268 for(
auto it_o = Operations.begin(); it_o_end != it_o && are_operations_bounded; ++it_o)
1270 if(!GetPointer<operation>(*it_o)->is_bounded())
1272 are_operations_bounded =
false;
1276 if(Has_extern_allocated_data && are_operations_bounded && memory_ctrl_type.size())
1280 if(!Has_extern_allocated_data && !are_operations_bounded && memory_ctrl_type.size())
1285 if(memory_ctrl_type.size() &&
parameters->getOption<std::string>(OPT_memory_controller_type) != memory_ctrl_type)
1289 if(bram_load_latency.size())
1291 if(bram_load_latency ==
"2" &&
parameters->getOption<std::string>(OPT_bram_high_latency).size())
1295 if(bram_load_latency ==
"3" &&
parameters->getOption<std::string>(OPT_bram_high_latency) !=
"_3")
1299 if(bram_load_latency ==
"4" &&
parameters->getOption<std::string>(OPT_bram_high_latency) !=
"_4")
1303 if(bram_load_latency !=
"2" && bram_load_latency !=
"3" && bram_load_latency !=
"4")
1313 if(node_info->node_kind.size() && !curr_op->
is_type_supported(node_info->node_kind))
1319 if(!curr_op->
is_type_supported(node_info->node_kind, node_info->input_prec, node_info->base128_input_nelem))
1329 if(
HLSMgr->Rfuns->is_a_proxied_function(fu_name))
1338 if(!
HLSMgr->Rfuns->is_a_shared_function(
funId, original_function_name))
1346 const auto original_function_name = fu_name.substr(
sizeof(
PROXY_PREFIX) - 1);
1347 if(!
HLSMgr->Rfuns->is_a_proxied_shared_function(
funId, original_function_name))
1357 std::string& bambu_provided_resource,
bool skip_flopoco_resources,
1360 if(structManager_obj)
1363 auto*
mod = GetPointer<module>(modobj);
1365 if(
mod->get_generated())
1371 if(skip_flopoco_resources)
1378 if(skip_softfloat_resources)
1390 else if(GetPointer<functional_unit>(current_fu)->fu_template_name.size())
1392 std::string tfname = GetPointer<functional_unit>(current_fu)->fu_template_name;
1394 if(!tfu || !GetPointer<functional_unit_template>(tfu) || !GetPointer<functional_unit_template>(tfu)->FU ||
1395 !GetPointer<functional_unit>(GetPointer<functional_unit_template>(tfu)->FU)->CM)
1399 structural_managerRef tcm = GetPointer<functional_unit>(GetPointer<functional_unit_template>(tfu)->FU)->CM;
1401 auto* tmod = GetPointer<module>(tmodobj);
1422 const auto FB =
HLSMgr->CGetFunctionBehavior(
funId);
1423 const auto TM =
HLSMgr->get_tree_manager();
1424 const auto function_vars =
HLSMgr->Rmem->get_function_vars(
funId);
1425 const auto clock_period = HLS_C->get_clock_period_resource_fraction() * HLS_C->get_clock_period();
1426 const auto channels_number = FB->GetChannelsNumber();
1427 const auto memory_allocation_policy = FB->GetMemoryAllocationPolicy();
1438 "-->Module allocation information for function " +
1439 HLSMgr->CGetFunctionBehavior(
funId)->CGetBehavioralHelper()->get_function_name() +
":");
1440 unsigned long long int base_address =
HLSMgr->base_address;
1441 const auto Has_extern_allocated_data =
1442 ((
HLSMgr->Rmem->get_memory_address() - base_address) > 0 &&
1449 bool skip_flopoco_resources =
false;
1451 bool skip_flopoco_resources =
true;
1453 bool skip_softfloat_resources =
true;
1456 skip_flopoco_resources =
true;
1457 skip_softfloat_resources =
false;
1459 auto& tech_vec = HLS_C->tech_constraints;
1460 const auto& binding_constraints = HLS_C->binding_constraints;
1465 const auto op_graph_size = boost::num_vertices(*cfg);
1472 std::map<std::string, technology_nodeRef> new_fu;
1473 bool gimple_return_allocated_p =
false;
1474 unsigned int gimple_return_current_id = 0;
1475 BOOST_FOREACH(
vertex v, boost::vertices(*g))
1478 const auto node_id = g->CGetOpNodeInfo(v)->GetNodeId();
1479 const auto node_operation = [&]() -> std::string {
1488 return GetPointer<const gimple_node>(TM->CGetTreeNode(node_id))->
operation;
1491 "-->Processing operation: " + current_op +
" - " +
GET_NAME(g, v) +
1493 " - " + TM->CGetTreeNode(node_id)->ToString() :
1498 const auto curr_tn = TM->CGetTreeNode(node_id);
1499 const auto me = GetPointer<const gimple_assign>(curr_tn);
1500 THROW_ASSERT(me,
"only gimple_assign's are allowed as memory operations");
1511 if(!var || (!function_vars.count(var->
index) &&
1512 (!
HLSMgr->Rmem->has_proxied_internal_variables(
funId) ||
1515 if(vertex_to_analyse_partition.find(current_op) == vertex_to_analyse_partition.end())
1517 vertex_to_analyse_partition.insert(std::make_pair(current_op,
OpVertexSet(g)));
1519 vertex_to_analyse_partition.at(current_op).insert(v);
1521 "<--Operation " + current_op +
" queued for allocation");
1525 "Not existing memory unit associated with the variable");
1532 "---Operation " + current_op +
" named " +
GET_NAME(g, v) +
" mapped onto " +
1538 if(!gimple_return_allocated_p)
1541 gimple_return_current_id = current_size;
1549 gimple_return_allocated_p =
true;
1557 gimple_return_current_id);
1559 "---Operation " + current_op +
" named " +
GET_NAME(g, v) +
" mapped onto " +
1561 " in position " +
STR(gimple_return_current_id));
1574 const auto& modify_node = g->CGetOpNodeInfo(v)->node;
1575 const auto gms = GetPointerS<const gimple_assign>(
GET_CONST_NODE(modify_node));
1612 const auto& modify_node = g->CGetOpNodeInfo(v)->node;
1613 const auto gms = GetPointerS<const gimple_assign>(
GET_CONST_NODE(modify_node));
1630 const auto& modify_node = g->CGetOpNodeInfo(v)->node;
1631 const auto gms = GetPointerS<const gimple_assign>(
GET_CONST_NODE(modify_node));
1632 const auto ebe = GetPointerS<const extract_bit_expr>(
GET_CONST_NODE(gms->op1));
1653 const auto modify_node = g->CGetOpNodeInfo(v)->node;
1654 const auto gms = GetPointerS<const gimple_assign>(
GET_CONST_NODE(modify_node));
1655 const auto ne = GetPointerS<const nop_expr>(
GET_CONST_NODE(gms->op1));
1672 const auto vector_boolR =
1675 const auto vector_boolL =
1678 const auto vector_intL =
1681 const auto vector_unsignedL =
1684 const auto vector_intR =
1687 const auto vector_unsignedR =
1691 if((unsignedR || is_a_pointerR || boolR) && (unsignedL || is_a_pointerL || boolL))
1695 else if((intR || enumR) && (unsignedL || is_a_pointerL || boolL))
1699 else if((unsignedR || is_a_pointerR || boolR) && (intL || enumL))
1703 else if((intR || enumR) && (intL || enumL))
1707 else if(is_realR && is_realL)
1709 if(!skip_flopoco_resources)
1713 else if(!skip_softfloat_resources)
1721 THROW_ERROR(
"missing resource for floating point to floating point conversion");
1724 else if(vector_boolR && vector_intL)
1728 else if(vector_boolR && vector_unsignedL)
1732 else if(vector_unsignedR && vector_boolL)
1736 else if(vector_unsignedR && vector_unsignedL)
1740 else if(vector_intR && vector_unsignedL)
1744 else if(vector_unsignedR && vector_intL)
1748 else if(vector_intR && vector_intL)
1754 THROW_ERROR(std::string(
"Nop_Expr pattern not supported ") +
STR(modify_node) +
" - Left type is " +
1755 STR(left_type) +
" - Right type is " +
STR(right_type));
1760 const auto modify_node = g->CGetOpNodeInfo(v)->node;
1761 const auto gms = GetPointerS<const gimple_assign>(
GET_CONST_NODE(modify_node));
1762 const auto ce = GetPointerS<const convert_expr>(
GET_CONST_NODE(gms->op1));
1775 if((unsignedR || is_a_pointerR || boolR) && (unsignedL || is_a_pointerL || boolL))
1779 else if(intR && (unsignedL || is_a_pointerL || boolL))
1783 else if((unsignedR || is_a_pointerR || boolR) && intL)
1787 else if(intR && intL)
1794 ". Left type is " +
STR(left_type) +
" - Right type is " +
STR(right_type));
1821 else if(current_op ==
ENTRY)
1825 else if(current_op ==
EXIT)
1829 else if(current_op ==
NOP)
1843 const auto& modify_node = g->CGetOpNodeInfo(v)->node;
1844 const auto gms = GetPointerS<const gimple_assign>(
GET_CONST_NODE(modify_node));
1845 const auto vce = GetPointerS<const view_convert_expr>(
GET_CONST_NODE(gms->op1));
1866 std::string(
"Not found ") + current_op +
" in library " +
TechM->
get_library(current_op));
1870 const auto current_id = current_size;
1872 "Something of wrong happen");
1899 " . Operation " + current_op +
" mapped onto " + current_fu->
get_name() +
1903 else if(binding_constraints.find(
GET_NAME(g, v)) != binding_constraints.end())
1906 const auto& [fu_name, constraint] = binding_constraints.at(
GET_NAME(g, v));
1907 const auto& [fu_library, fu_index] = constraint;
1909 if(fu_name_to_id.find(
key) != fu_name_to_id.end())
1911 if(fu_name_to_id[
key].find(fu_index) != fu_name_to_id[
key].end())
1914 std::pair<std::string, unsigned int>(current_op, fu_name_to_id[
key][fu_index]);
1919 fu_name_to_id[
key][fu_index] = current_size;
1921 THROW_ASSERT(current_fu, std::string(
"Not found") + fu_name +
" in library " + fu_library);
1925 std::pair<std::string, unsigned int>(current_op, current_size);
1929 if(tech_vec.find(
key) != tech_vec.end())
1957 fu_name_to_id[
key][fu_index] = current_size;
1959 THROW_ASSERT(current_fu, std::string(
"Not found") + fu_name +
" in library " + fu_library);
1966 if(tech_vec.find(
key) != tech_vec.end())
1993 if(vertex_to_analyse_partition.find(current_op) == vertex_to_analyse_partition.end())
1995 vertex_to_analyse_partition.insert(std::pair<std::string, OpVertexSet>(current_op,
OpVertexSet(g)));
1997 vertex_to_analyse_partition.at(current_op).insert(v);
1999 "---Operation " + current_op +
" queued for allocation");
2006 for(
const auto& tv : tech_vec)
2009 "---Resource constraint on " + tv.first +
": " +
STR(tv.second));
2012 std::string bambu_provided_resource;
2018 if(lib_name ==
"STD_COMMON")
2023 for(
const auto& fu : library->get_library_fu())
2026 if(GetPointer<functional_unit_template>(current_fu))
2031 const auto& fu_channels_type = GetPointer<functional_unit>(current_fu)->channels_type;
2032 const auto& fu_memory_ctrl_type = GetPointer<functional_unit>(current_fu)->memory_ctrl_type;
2034 "-->Considering functional unit: " + current_fu->
get_name());
2057 const auto tech_constrain_it =
2058 GetPointer<functional_unit>(current_fu)->fu_template_name.size() ?
2059 tech_vec.find(
ENCODE_FU_LIB(GetPointer<functional_unit>(current_fu)->fu_template_name, lib_name)) :
2062 if(tech_constrain_it != tech_vec.end() && tech_constrain_it->second == 0)
2068 const auto tech_constrain_value =
2069 tech_constrain_it == tech_vec.end() ?
INFINITE_UINT : tech_constrain_it->second;
2071 const auto structManager_obj = GetPointer<functional_unit>(current_fu)->CM;
2075 skip_flopoco_resources, current_fu))
2083 unsigned int current_id = current_fu_id;
2085 const auto lib_is_proxy_or_work =
2087 for(
const auto& ops : GetPointer<functional_unit>(current_fu)->get_operations())
2089 const auto curr_op = GetPointer<operation>(ops);
2090 const auto& curr_op_name = curr_op->get_name();
2092 if(vertex_to_analyse_partition.find(curr_op_name) == vertex_to_analyse_partition.end())
2097 for(
const auto vert : vertex_to_analyse_partition.at(curr_op_name))
2099 const auto vert_node_id = g->CGetOpNodeInfo(vert)->GetNodeId();
2100 const auto vert_node_operation = [&]() -> std::string {
2109 return GetPointer<const gimple_node>(TM->CGetTreeNode(vert_node_id))->
operation;
2115 else if((!lib_is_proxy_or_work) &&
2126 bool isMemory = fu_memory_ctrl_type.size();
2128 "unexpected condition: " + g->CGetOpNodeInfo(vert)->GetOperation());
2137 node_info->node_kind =
"VECTOR_BOOL";
2150 "expected a time model for " + current_fu->
get_name() +
" for operation " + curr_op_name);
2151 if(curr_op->time_m->get_cycles() >= 1 &&
2153 GetPointer<functional_unit>(current_fu)->fu_template_name.empty())
2156 " not compliant with the given clock period " +
STR(clock_period));
2159 else if(curr_op->time_m->get_cycles() >= 1)
2162 "Functional unit " + current_fu->
get_name() +
2163 " compliant with the given clock period " +
STR(clock_period) +
" stage period " +
2167 if(GetPointer<functional_unit>(current_fu)->fu_template_name.size())
2177 std::string current_op;
2178 std::string specialized_fuName =
"";
2180 const auto has_to_be_generated =
2181 structManager_obj && (GetPointer<module>(structManager_obj->get_circ())
2182 ->get_NP_functionality()
2184 GetPointer<module>(structManager_obj->get_circ())
2185 ->get_NP_functionality()
2187 if(has_to_be_generated)
2191 const auto varargs_fu = GetPointer<module>(structManager_obj->get_circ())->is_var_args();
2194 const auto required_variables =
HLSMgr->get_required_values(
funId, vert);
2195 std::string unique_id;
2196 if(g->CGetOpNodeInfo(vert)->GetOperation() ==
GIMPLE_ASM)
2198 unique_id =
STR(g->CGetOpNodeInfo(vert)->GetNodeId());
2200 auto firstIndexToSpecialize = 0
U;
2201 const auto mod = GetPointer<module>(structManager_obj->get_circ());
2202 for(
auto Pindex = 0
U; Pindex <
mod->get_in_port_size(); ++Pindex)
2204 const auto& port_obj =
mod->get_in_port(Pindex);
2205 const auto& port_name = port_obj->get_id();
2206 if(GetPointer<port_o>(port_obj)->get_is_var_args())
2212 ++firstIndexToSpecialize;
2215 THROW_ASSERT(required_variables.size() >= firstIndexToSpecialize,
2216 "unexpected condition:" +
STR(required_variables.size()) +
" " +
2217 STR(firstIndexToSpecialize));
2218 current_op = current_fu->
get_name() + unique_id +
2219 modGen->get_specialized_name(firstIndexToSpecialize, required_variables, FB);
2223 current_op = current_fu->
get_name() +
"_modgen";
2225 specialized_fuName = current_op;
2226 const auto& fu_name = current_fu->
get_name();
2229 if(check_lib == lib_name)
2231 new_fu[specialized_fuName] =
get_fu(specialized_fuName);
2233 else if(new_fu.find(specialized_fuName) == new_fu.end())
2237 modGen->specialize_fu(fu_name, vert, FB, lib_name, specialized_fuName, new_fu);
2241 modGen->create_generic_module(fu_name, vert, FB, lib_name, specialized_fuName);
2243 const auto new_techNode_obj = libraryManager->
get_fu(specialized_fuName);
2245 new_fu.insert(std::make_pair(specialized_fuName, new_techNode_obj));
2249 else if(node_info->node_kind.size() && !isMemory)
2251 current_op =
encode_op_type_prec(curr_op_name, curr_op->get_type_supported_string(), node_info);
2253 else if(node_info->node_kind.size())
2255 current_op =
encode_op_type(curr_op_name, curr_op->get_type_supported_string());
2259 current_op = curr_op_name;
2262 std::string library_name = lib_name;
2263 if(bambu_provided_resource.size())
2277 auto max_prec = node_info->input_prec.empty() ?
2279 *std::max_element(node_info->input_prec.begin(), node_info->input_prec.end());
2280 if(isMemory || lib_is_proxy_or_work || tech_constrain_value !=
INFINITE_UINT ||
2281 bambu_provided_resource.size())
2287 decltype(
fu_list)::iterator techMap;
2288 std::string functionalUnitName =
"";
2289 auto specializedId = current_id;
2291 if(has_to_be_generated)
2293 functionalUnitName = specialized_fuName;
2294 techMap =
fu_list.find(new_fu.at(functionalUnitName));
2296 if(techMap !=
fu_list.end() && techMap->second.find(max_prec) != techMap->second.end() &&
2297 techMap->second.find(max_prec)->second.find(constant_id) !=
2298 techMap->second.find(max_prec)->second.end())
2300 specializedId = techMap->second.find(max_prec)->second.find(constant_id)->second;
2305 "Insert into list of unit to add: " + functionalUnitName +
2306 " prec=" +
STR(max_prec) +
" constant_id=" +
STR(std::get<0>(constant_id)) +
2307 "-" +
STR(std::get<1>(constant_id)));
2308 fu_list[new_fu.find(functionalUnitName)->second][max_prec][constant_id] = current_id;
2314 else if(fu_memory_ctrl_type.size())
2318 auto fuUnit = new_fu.find(functionalUnitName)->second;
2321 auto fuUnitModule = GetPointer<functional_unit>(fuUnit)->CM->get_circ();
2322 if(GetPointer<module>(fuUnitModule))
2324 auto multiplicity = GetPointer<module>(fuUnitModule)->get_multi_unit_multiplicity();
2328 "Added multiplicity of " +
STR(multiplicity) +
" to " +
2329 functionalUnitName);
2341 functionalUnitName = current_fu->
get_name();
2343 "---Functional unit name is " + functionalUnitName);
2344 techMap =
fu_list.find(libraryManager->get_fu(functionalUnitName));
2345 if(techMap !=
fu_list.end() && techMap->second.find(max_prec) != techMap->second.end() &&
2346 techMap->second.find(max_prec)->second.find(constant_id) !=
2347 techMap->second.find(max_prec)->second.end())
2349 specializedId = techMap->second.find(max_prec)->second.find(constant_id)->second;
2353 fu_list[libraryManager->get_fu(functionalUnitName)][max_prec][constant_id] = current_id;
2357 auto n_ports =
parameters->getOption<
unsigned int>(OPT_memory_banks_number);
2364 else if(fu_memory_ctrl_type.size())
2368 add_tech_constraint(libraryManager->get_fu(functionalUnitName), tech_constrain_value, current_id,
2376 " . Adding candidate FU: " + functionalUnitName +
" for operation: " + current_op +
2377 " in position " +
STR(specializedId));
2378 vertex_analysed.insert(vert);
2380 ->
node_id_to_fus[std::pair<unsigned int, std::string>(vert_node_id, vert_node_operation)]
2383 if(node_info->is_single_bool_test_cond_expr)
2387 if(node_info->is_simple_pointer_plus_expr)
2395 const auto original_function_name = functionalUnitName.substr(
sizeof(
WRAPPED_PROXY_PREFIX) - 1);
2401 const auto original_function_name = functionalUnitName.substr(
sizeof(
PROXY_PREFIX) - 1);
2410 "<--Considered functional unit: " + current_fu->
get_name());
2412 for(
auto& iter_new_fu : new_fu)
2415 "Adding functional unit: " + iter_new_fu.first +
" in " + lib_name);
2416 TechM->
add(iter_new_fu.second, lib_name);
2428 bool completely_analyzed =
true;
2429 for(
const auto& ve_op : vertex_to_analyse_partition)
2431 for(
const auto& ve : ve_op.second)
2433 if(vertex_analysed.count(ve))
2440 std::string precisions;
2441 const size_t n_ins = node_info->input_prec.size();
2442 for(
size_t ind = 0; ind < n_ins; ++ind)
2444 if(node_info->real_input_nelem[ind] == 0)
2446 precisions +=
" " +
STR(node_info->input_prec[ind]);
2450 precisions +=
" " +
STR(node_info->input_prec[ind]) +
":" +
STR(node_info->real_input_nelem[ind]);
2453 if(node_info->real_output_nelem == 0)
2455 precisions +=
" " +
STR(node_info->output_prec);
2459 precisions +=
" " +
STR(node_info->output_prec) +
":" +
STR(node_info->real_output_nelem);
2462 "---Operation for which does not exist a functional unit in the resource library: " +
2464 " in vertex: " +
GET_NAME(g, ve) +
" with vertex type: " + node_info->node_kind +
2465 " and vertex prec:" + precisions);
2466 completely_analyzed =
false;
2469 if(!completely_analyzed)
2478 for(
auto fu_unit : op.second)
2501 for(
auto fu_unit : op.second)
2510 HLSMgr->Rmem->increment_n_mem_operations(
2525 "Time to perform module allocation: " +
print_cpu_time(step_time) +
" seconds");
2538 const std::string& library_name,
2539 const std::string& template_suffix,
unsigned long long module_prec)
2541 if(pipe_parameter.empty())
2545 THROW_ASSERT(GetPointer<functional_unit>(current_fu),
"expected a functional unit object");
2546 auto* fu = GetPointer<functional_unit>(current_fu);
2548 THROW_ASSERT(fu->fu_template_name.size(),
"expected a template_name for a pipelined unit");
2552 if(pipe_parameter == compliant_id)
2554 return pipe_parameter;
2563 THROW_ASSERT(fu_temp,
"expected a template functional unit for a pipelined unit");
2564 bool is_flopoco_provided =
false;
2569 auto* tmod = GetPointer<module>(tmodobj);
2573 is_flopoco_provided =
true;
2576 technology_nodeRef fun_temp_operation = GetPointer<functional_unit>(fu_temp->
FU)->get_operation(curr_op);
2577 THROW_ASSERT(fun_temp_operation,
"operation not present in the template description");
2578 auto* template_op = GetPointer<operation>(fun_temp_operation);
2579 std::string temp_pipe_parameters = template_op->pipe_parameters;
2580 std::vector<std::string> parameters_split =
SplitString(temp_pipe_parameters,
"|");
2581 THROW_ASSERT(parameters_split.size() > 0,
"unexpected pipe_parameter format");
2582 for(
auto& el_indx : parameters_split)
2584 std::vector<std::string> parameters_pairs =
SplitString(el_indx,
":");
2585 if(parameters_pairs[0] ==
"*")
2587 temp_pipe_parameters = parameters_pairs[1];
2590 else if(parameters_pairs[0] ==
"DSPs_y_sizes" and
2594 temp_pipe_parameters = parameters_pairs[1];
2597 else if(std::stoull(parameters_pairs[0]) == module_prec)
2599 temp_pipe_parameters = parameters_pairs[1];
2603 THROW_ASSERT(temp_pipe_parameters.size(),
"expected some pipe_parameters for the the template operation");
2604 std::string fastest_pipe_parameter =
"0";
2606 std::vector<std::string> pipe_parameters =
SplitString(temp_pipe_parameters,
",");
2607 const auto st_end = pipe_parameters.end();
2608 std::vector<std::string>::const_iterator st_next;
2609 unsigned int skip_pipe_parameter = 0;
2610 if(is_flopoco_provided)
2612 skip_pipe_parameter =
std::max(1u,
parameters->getOption<
unsigned int>(OPT_skip_pipe_parameter));
2616 skip_pipe_parameter =
parameters->getOption<
unsigned int>(OPT_skip_pipe_parameter);
2618 for(
auto st = st_next = pipe_parameters.begin(); st != st_end; ++st)
2622 fu->fu_template_name +
"_" + template_suffix +
"_" + *st, library_name);
2625 area_infoRef a_m = GetPointer<functional_unit>(fu_cur_obj)->area_m;
2626 THROW_ASSERT(a_m,
"Area information not specified for unit " + fu->fu_template_name +
"_" + template_suffix +
2631 double dsp_multiplier_stage =
2636 const functional_unit* fu_cur = GetPointer<functional_unit>(fu_cur_obj);
2637 auto* fu_cur_operation = GetPointer<operation>(fu_cur->
get_operation(curr_op));
2638 if(fu_cur_operation->time_m->get_cycles() >= 1 &&
2641 fastest_pipe_parameter = *st;
2647 (fu_cur_operation->time_m->get_cycles() >= 1 &&
2651 if(skip_pipe_parameter && st_next != st_end)
2653 --skip_pipe_parameter;
2658 if(*st == pipe_parameter)
2660 return pipe_parameter;
2671 if(fastest_pipe_parameter ==
"0")
2679 THROW_WARNING(
"No functional unit exists for the given clock period: the fastest pipelined unit will be used (" +
2680 fu->fu_template_name +
"): " +
STR(fastest_stage_period));
2683 if(pipe_parameter == fastest_pipe_parameter)
2685 return fastest_pipe_parameter;
2701 if(library_name.empty())
2711 if(!
parameters->IsParameter(
"variable-mem-lat") ||
parameters->GetParameter<
int>(
"variable-mem-lat") == 0)
2715 if(
HLSMgr->Rmem->is_read_only_variable(var))
2719 const auto n_ref =
static_cast<unsigned int>(
HLSMgr->Rmem->get_maximum_references(var));
2720 const auto clock_period = HLS_C->get_clock_period_resource_fraction() * HLS_C->get_clock_period();
2721 const auto controller_delay = 0;
2722 const auto fu_cur = GetPointerS<functional_unit>(current_fu);
2723 const auto load_operation = GetPointerS<operation>(fu_cur->get_operation(
"STORE"));
2725 const auto FB =
HLSMgr->CGetFunctionBehavior(
funId);
2726 const auto n_channels = FB->GetChannelsNumber() ? FB->GetChannelsNumber() : 1
U;
2729 return n_ref / n_channels > 1 && (controller_delay + ex_time + mux_delay + setup) > clock_period;
2735 std::string new_lat;
2738 if(is_synchronous_ram_not_timing_compliant)
2740 new_lat = latency_postfix.empty() ? std::string(
"3") : std::string(
"4");
2746 new_lat = latency_postfix.empty() ?
"2" : (latency_postfix ==
"_3" ?
"3" :
"4");
2754 const auto TM =
HLSMgr->get_tree_manager();
2755 const auto FB =
HLSMgr->CGetFunctionBehavior(
funId);
2756 const auto channels_number = FB->GetChannelsNumber();
2757 const auto channels_type = FB->GetChannelsType();
2759 const auto clock_period = HLS_C->get_clock_period_resource_fraction() * HLS_C->get_clock_period();
2761 std::string latency_postfix =
"";
2762 if(
parameters->getOption<std::string>(OPT_bram_high_latency).size())
2764 latency_postfix =
parameters->getOption<std::string>(OPT_bram_high_latency);
2766 for(
const auto& l :
HLSMgr->Rmem->get_function_vars(
funId))
2769 const auto& var = l.first;
2771 unsigned int n_ports = 1;
2773 if(
HLSMgr->Rmem->has_callSite_base_address(var))
2778 bool is_async_var =
false;
2783 if(
HLSMgr->Rmem->is_sds_var(var))
2785 if((
HLSMgr->Rmem->has_all_pointers_resolved() &&
HLSMgr->Rmem->does_need_addr(var)) ||
2786 (!
HLSMgr->Rmem->has_all_pointers_resolved() && !
HLSMgr->Rmem->is_private_memory(var)))
2792 if(
parameters->getOption<
bool>(OPT_use_asynchronous_memories) &&
2794 TM, var,
parameters->getOption<
unsigned int>(OPT_distram_threshold),
2795 HLSMgr->Rmem->is_read_only_variable(var), 1)))
2799 if(is_asynchronous_ram_not_timing_compliant)
2807 is_async_var =
true;
2825 if(
HLSMgr->Rmem->is_sds_var(var))
2827 if((
HLSMgr->Rmem->has_all_pointers_resolved() &&
HLSMgr->Rmem->does_need_addr(var)) ||
2828 (!
HLSMgr->Rmem->has_all_pointers_resolved() && !
HLSMgr->Rmem->is_private_memory(var)))
2834 if(
parameters->getOption<
bool>(OPT_use_asynchronous_memories) &&
2836 TM, var,
parameters->getOption<
unsigned int>(OPT_distram_threshold),
2837 HLSMgr->Rmem->is_read_only_variable(var), channels_number))
2841 if(is_asynchronous_ram_not_timing_compliant)
2849 is_async_var =
true;
2864 n_ports = channels_number;
2868 if(
HLSMgr->Rmem->is_sds_var(var))
2870 if((
HLSMgr->Rmem->has_all_pointers_resolved() &&
HLSMgr->Rmem->does_need_addr(var)) ||
2871 (!
HLSMgr->Rmem->has_all_pointers_resolved() && !
HLSMgr->Rmem->is_private_memory(var)))
2877 if(
parameters->getOption<
bool>(OPT_use_asynchronous_memories) &&
2879 TM, var,
parameters->getOption<
unsigned int>(OPT_distram_threshold),
2880 HLSMgr->Rmem->is_read_only_variable(var), channels_number))
2884 if(is_asynchronous_ram_not_timing_compliant)
2892 is_async_var =
true;
2907 n_ports = channels_number;
2911 THROW_ERROR(
"type of channel based organization not yet supported");
2916 " - allocating unit " + current_fu->
get_name() +
" for variable " +
2917 FB->CGetBehavioralHelper()->PrintVariable(l.first) +
" in position " +
STR(current_size));
2919 if(
HLSMgr->Rmem->is_sds_var(var) &&
HLSMgr->Rmem->is_read_only_variable(var) &&
2921 (
parameters->isOption(OPT_rom_duplication) &&
parameters->getOption<
bool>(OPT_rom_duplication))))
2934 "Something of wrong happened");
2940 auto* fu_br = GetPointer<functional_unit>(current_fu);
2942 auto* op_store = GetPointer<operation>(op_store_node);
2946 if(store_delay > clock_period)
2948 THROW_ERROR(
"clock constraint too tight: BRAMs for this device cannot run so fast... (" +
2949 current_fu->
get_name() +
":" +
STR(store_delay) +
">" +
STR(clock_period) +
")");
2954 if(
HLSMgr->Rmem->has_proxied_internal_variables(
funId))
2956 for(
const auto& proxied_var_id :
HLSMgr->Rmem->get_proxied_internal_variables(
funId))
2960 unsigned int n_ports = 1;
2963 if(
HLSMgr->Rmem->is_sds_var(proxied_var_id))
2965 if((
HLSMgr->Rmem->has_all_pointers_resolved() &&
HLSMgr->Rmem->does_need_addr(proxied_var_id)) ||
2966 (!
HLSMgr->Rmem->has_all_pointers_resolved() && !
HLSMgr->Rmem->is_private_memory(proxied_var_id)))
2972 if(
parameters->getOption<
bool>(OPT_use_asynchronous_memories) &&
2974 TM, proxied_var_id,
parameters->getOption<
unsigned int>(OPT_distram_threshold),
2975 HLSMgr->Rmem->is_read_only_variable(proxied_var_id), 1))
2978 bool is_asynchronous_ram_not_timing_compliant =
2980 if(is_asynchronous_ram_not_timing_compliant)
3007 if(
HLSMgr->Rmem->is_sds_var(proxied_var_id))
3009 if((
HLSMgr->Rmem->has_all_pointers_resolved() &&
HLSMgr->Rmem->does_need_addr(proxied_var_id)) ||
3010 (!
HLSMgr->Rmem->has_all_pointers_resolved() && !
HLSMgr->Rmem->is_private_memory(proxied_var_id)))
3017 if(
parameters->getOption<
bool>(OPT_use_asynchronous_memories) &&
3019 TM, proxied_var_id,
parameters->getOption<
unsigned int>(OPT_distram_threshold),
3020 HLSMgr->Rmem->is_read_only_variable(proxied_var_id), channels_number))
3024 bool is_asynchronous_ram_not_timing_compliant =
3026 if(is_asynchronous_ram_not_timing_compliant)
3031 latency_postfix, HLS_C, proxied_var_id)));
3043 latency_postfix, HLS_C, proxied_var_id)));
3051 n_ports = channels_number;
3055 THROW_ERROR(
"type of channel based organization not yet supported");
3059 " - allocating unit " + current_fu->
get_name() +
" for variable " +
3060 FB->CGetBehavioralHelper()->PrintVariable(proxied_var_id) +
" in position " +
3068 "Something of wrong happened");
3078 for(
const auto& shared_fu_name :
HLSMgr->Rfuns->get_shared_functions(
funId))
3082 if(library_name.size())
3085 auto techNode_obj = libraryManager->
get_fu(shared_fu_name);
3086 THROW_ASSERT(techNode_obj,
"function not yet built: " + shared_fu_name);
3092 if(structManager_obj && (GetPointer<module>(structManager_obj->
get_circ())
3093 ->get_NP_functionality()
3095 GetPointer<module>(structManager_obj->
get_circ())
3096 ->get_NP_functionality()
3100 std::string new_shared_fu_name = shared_fu_name +
"_modgen";
3102 const auto fu = GetPointer<const functional_unit>(techNode_obj);
3103 for(
const auto& op : fu->get_operations())
3105 const auto op_fnode =
HLSMgr->get_tree_manager()->GetFunction(op->get_name());
3114 modGen->create_generic_module(shared_fu_name,
nullptr,
3116 libraryManager->get_library_name(), new_shared_fu_name);
3117 techNode_obj = libraryManager->get_fu(new_shared_fu_name);
3118 THROW_ASSERT(techNode_obj,
"function not yet built: " + new_shared_fu_name);
3128 " - allocating unit " + wrapper_tn->get_name() +
" in position " +
STR(current_size));
3134 "Something of wrong happened");
3143 if(
HLSMgr->Rfuns->has_proxied_shared_functions(
funId))
3145 for(
const auto& original_proxied_fu_name :
HLSMgr->Rfuns->get_proxied_shared_functions(
funId))
3148 " - adding proxy function module " + original_proxied_fu_name);
3149 const std::string library_name =
TechM->
get_library(original_proxied_fu_name);
3150 if(library_name.size())
3154 THROW_ASSERT(techNode_obj,
"function not yet built: " + original_proxied_fu_name);
3167 const std::string file_name =
3168 parameters->getOption<std::string>(OPT_output_temporary_directory) +
"before_" +
GetName() +
".tm";
3169 std::ofstream raw_file(file_name);
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...
#define IUDATA_CONVERTER_STD
void Initialize() override
Initialize the step (i.e., like a constructor, but executed just before exec.
void add_connection(structural_objectRef src, structural_objectRef dest)
Create a connection between a source structural object and a destination structural object...
#define MEMORY_CTRL_TYPE_DPROXY
std::map< std::string, std::vector< unsigned int > > supported_types
supported types and precision of the operation, in form (name, list_of_prec).
bool check_generated_bambu_flopoco(bool skip_softfloat_resources, structural_managerRef structManager_obj, std::string &bambu_provided_resource, bool skip_flopoco_resources, technology_nodeRef current_fu)
#define IICONVERTER_EXPR_STD
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
const HLS_managerRef HLSMgr
information about all the HLS synthesis
static bool IsComplexType(const tree_nodeConstRef &type)
Return if treenode is a complex.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
void * top(node_stack *head)
Collect information about resource area.
#define GET_TYPE(data, vertex_index)
Helper macro returning the type associated with a node.
static std::string convert_to_identifier(const language_writer *writer, const std::string &id)
Converts a generic string to a language compliant identifier.
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 EXTRACT_BIT_EXPR_UNSIGNED_STD
#define DEBUG_LEVEL_PEDANTIC
very verbose debugging print is performed.
This structure collect the information of input and output precision of nodes and the node kind...
#define CHANNELS_TYPE_MEM_ACC_NN
technology_nodeRef get_fu(const std::string &fu_name, const std::string &Library) const
Return the reference to a component given its name.
Structure representing the most relevant information about the type of a structural object...
#define GIMPLE_RETURN
constant string identifying the operation performed by a gimple_return.
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.
static const unsigned int PARAMETRIC_PORT
std::string pipe_parameters
comma separated string with the parameter for the different implementation of the pipeline...
const structural_objectRef get_circ() const
Get a reference to circ field.
const int output_level
The output level.
const std::vector< std::string > SplitString(const std::string &input, const std::string &separators)
Function which splits a string into tokens.
#define ARRAY_1D_STD_BRAM_NN_SDS_BUS
technology_nodeRef get_fu(const std::string &name) const
only external memory access Datapath see only 1 memory port, while the bus manage parallel accesses ...
#define UUDATA_CONVERTER_STD
#define CHANNELS_TYPE_MEM_ACC_CS
void print(std::ostream &os) const
Function that prints the class technology_manager.
unsigned int get_out_port_size() const
Return the number of output ports.
#define ASSIGN_VEC_SIGNED_STD
RelationshipType
The relationship type.
#define EXTRACT_BIT_EXPR_SIGNED_STD
Source must be executed to satisfy target.
#define INDENT_OUT_MEX(outLevel, curOutLevel, mex)
std::string get_NP_functionality(NP_functionaly_type type) const
Return the description provided the type.
static void connectClockAndReset(structural_managerRef &SM, structural_objectRef &interfaceObj, structural_objectRef &component)
const unsigned int funId
identifier of the function to be processed (0 means that it is a global step)
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 std::vector< std::string > & get_library_list() const
Return the list of the libraries.
technology_nodeRef get_fu(const std::string &fu_name)
Returns the technology_node associated with the given operation.
technology_nodeRef extract_bambu_provided(const std::string &library_name, operation *curr_op, const std::string &bambu_provided_resource_)
void set_number_channels(unsigned int fu_name, unsigned int n_ports)
set the number of ports associated with the functional unit
#define IIVECTOR_CONVERTER_STD
#define ARRAY_1D_STD_BRAM_NN_SDS
This class manages the circuit structures.
const HLS_deviceRef HLS_D
reference to the information representing the target for the synthesis
#define READ_COND
constant string identifying the operation performed by a READ_COND.
exceptions managed by PandA
bool check_type_and_precision(operation *curr_op, node_kind_prec_infoRef node_info)
AllocationInformationRef allocation_information
Store the technology information.
static language_writerRef create_writer(HDLWriter_Language language, const technology_managerConstRef TM, const ParameterConstRef parameters)
Creates the specialization of the writer based on the desired language.
static std::string fix_identifier(std::string port_name, language_writerRef writer)
Collect information about resource performance.
const structural_objectRef get_in_port(unsigned int n) const
Return the ith input port.
void add_proxy_function_module(const HLS_constraintsRef HLS_C, technology_nodeRef techNode_obj, const std::string &orig_fun_name)
Add a proxy function to the WORK library.
#define ARRAY_1D_STD_BRAM_SDS
static bool is_other_port(const structural_objectRef &port)
time_infoRef time_m
class representing the timing information associated with this operation
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...
void BuildProxyFunction(functional_unit *current_fu)
Build the proxy function.
OpVertexSet operations
Set representing the subset of operations in the specification to be implemented. ...
void insert(node_tree **tree, int val)
static std::string encode_op_type(const std::string &op_name, const std::string &fu_supported_types)
static bool is_a_skip_operation(const std::string &op_name)
Class specification of the manager of the technology library data structures.
This class contains the base representation for a generic frontend flow step which works on a single ...
all objects that need to be stored in memory are allocated on an external memory
#define OUTPUT_LEVEL_VERY_VERY_PEDANTIC
verbose debugging print is performed.
This class specifies the characteristic of a particular functional unit.
Base class description of data information associated with each node of a graph.
#define ASSIGN_SIGNED_STD
#define INTERFACE_LIBRARY
interface library
#define OUTPUT_LEVEL_MINIMUM
minimum debugging print is performed.
redefinition of map to manage ordered/unordered structures
static bool IsEnumType(const tree_nodeConstRef &type)
Return if treenode index is an enumeral type.
std::tuple< unsigned int, unsigned int > io_binding_type
tuple set used to represent the required values or the constant default value associated with the inp...
void ComputeRelationships(DesignFlowStepSet &design_flow_step_set, const DesignFlowStep::RelationshipType relationship_type) override
Compute the relationships of a step with other steps.
#define VIEW_CONVERT_STD_UINT
Include a set of utilities used to manage CPU time measures.
#define TYPE_LOAD
Constant string identifying a memory load operation.
#define EXTRACT_BIT_EXPR
constant string identifying the operation performed by an extract_bit_expr.
#define MEMORY_CTRL_TYPE_PROXY
A set of operation vertices.
technology_nodeRef add_operation(const std::string &Library, const std::string &fu_name, const std::string &operation_name)
Add an operation to the specified functional unit.
std::map< std::string, std::string > precomputed_pipeline_unit
store the precomputed pipeline unit: given a functional unit it return the pipeline id compliant ...
DesignFlowStep_Status InternalExec() override
Execute the step.
refcount< technology_node > technology_nodeRef
refcount definition of the class
unsigned int get_cycles() const
#define THROW_WARNING(str_expr)
helper function used to throw a warning in a standard way: though it uses PRINT_DBG_MEX, the debug level used is such that the message is always printed
#define STR(s)
Macro which performs a lexical_cast to a string.
void BuildProxyFunctionVHDL(functional_unit *current_fu)
Build the proxy function in VHDL.
Auxiliary methods for manipulating string.
#define MEMORY_CTRL_TYPE_SPROXY
s_type type
The type of the port or the signal.
~allocation() override
Destructor.
void BuildProxyFunctionVerilog(functional_unit *current_fu)
Build the proxy function in Verilog.
#define CLOCK_PORT_NAME
standard name for ports
#define ADDR_EXPR
constant string identifying the addressing operation.
static bool IsUnsignedIntegerType(const tree_nodeConstRef &type)
Return true if the treenode is of unsigned integer type.
void ComputeRelationships(DesignFlowStepSet &relationship, const DesignFlowStep::RelationshipType relationship_type) override
Compute the relationships of a step with other steps.
static bool IsSignedIntegerType(const tree_nodeConstRef &type)
Return true if the treenode is of integer type.
#define CHANNELS_TYPE_MEM_ACC_P1N
Pure virtual base class for all the design flow step factory.
#define START_TIME(time_var)
Macro used to store the start time into time_var.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
bool starts_with(const std::string &str, const std::string &pattern)
#define ARRAY_1D_STD_BRAM_N1_SDS_BUS
static void add_NP_functionality(structural_objectRef cir, NP_functionality::NP_functionaly_type dt, std::string functionality_description)
Add a not-parsed functionality.
Factory for hls flow step.
allocation(const ParameterConstRef _parameters, const HLS_managerRef HLSMgr, unsigned int funId, const DesignFlowManagerConstRef design_flow_manager, const HLSFlowStep_Type=HLSFlowStep_Type::ALLOCATION)
Constructor.
#define GIMPLE_PHI
constant string identifying the operation performed by a gimple_phi.
double get_resource_value(value_t val) const
#define ASSERT_EXPR_UNSIGNED_STD
void add(const technology_nodeRef curr, const std::string &Library)
Add the given functional_unit to the specified library.
static unsigned long long Size(const tree_nodeConstRef &tn)
Return the size of a tree object.
#define EXIT_ID
constant used to represent tree node index of exit operation
static bool IsBooleanType(const tree_nodeConstRef &type)
Return true if the treenode is of bool type.
This class specifies the characteristic of a particular operation working on a given functional unit...
absl::flat_hash_map< T, U, Hash, Eq, Alloc > CustomUnorderedMap
void Initialize() override
Initialize the step (i.e., like a constructor, but executed just before exec.
#define ENTRY
Superclass include.
void set_top_info(const std::string &id, const technology_managerRef &LM, const std::string &Library="")
Data structure used to store the schedule of the operations.
std::string get_synch_ram_latency(const std::string &ram_template, const std::string &latency_postfix, const HLS_constraintsRef HLS_C, unsigned int var)
std::map< technology_nodeRef, std::map< unsigned long long, std::map< HLS_manager::io_binding_type, unsigned int > > > fu_list
all global variables, static variables and strings are allocated on BRAMs
#define ARRAY_1D_STD_BRAM_N1_SDS
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. ...
#define ARRAY_1D_STD_DISTRAM_SDS
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.
const structural_objectRef get_out_port(unsigned int n) const
Return the ith output port.
unsigned int bb_version
The version of bb intermediate representation on which this step was applied.
const unsigned int index
Represent the index read from the raw file and the index-1 of the vector of tree_node associated to t...
Classes to describe design flow graph.
Target must be reexecuted.
redefinition of set to manage ordered/unordered structures
#define ARRAY_1D_STD_BRAM_NN
#define STOP_TIME(time_var)
Macro used to store the elapsed time into time_var.
#define UUCONVERTER_EXPR_STD
#define ARRAY_1D_STD_BRAM
Datastructure to describe functions allocation in high-level synthesis.
#define TYPE_STORE
Constant string identifying a memory store operation.
const operation_vec & get_operations() const
Return the operations that the functional unit can handle.
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
const Wrefcount< const DesignFlowManager > design_flow_manager
The design flow manager.
#define VIEW_CONVERT_STD_INT
static bool IsVectorType(const tree_nodeConstRef &type)
Return true if the treenode is a vector.
unsigned offset[NUM_VERTICES+1]
static std::string encode_op_type_prec(const std::string &op_name, const std::string &fu_supported_types, node_kind_prec_infoRef node_info)
#define IIDATA_CONVERTER_STD
static std::string GetFUName(const std::string &fname, const HLS_managerRef HLSMgr)
Return FU used to implement given function.
const std::string & get_name() const override
Returns the name of the operation.
#define GET_CONST_NODE(t)
bool check_proxies(const library_managerRef library, const std::string &fu_name_)
#define UICONVERTER_EXPR_STD
AllocationInformationRef allocation_information
The allocation solution.
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.
#define FFDATA_CONVERTER_STD
static std::string NormalizeTypename(const std::string &id)
Return normalized name of types and variables.
#define GIMPLE_GOTO
constant string identifying the operation performed by a GIMPLE_GOTO.
#define GIMPLE_LABEL
constant string identifying the operation performed by a GIMPLE_LABEL.
const ParameterConstRef parameters
Set of input parameters.
#define UIDATA_CONVERTER_STD
DesignFlowStep_Status
The status of a step.
This file collects some utility functions and macros.
bool is_type_supported(const std::string &type_name) const
Checks if the specified type name is supported.
Base class to allocate memories in high-level synthesis.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
#define VIEW_CONVERT_EXPR
constant string identifying view convert expressions
refcount< structural_manager > structural_managerRef
RefCount type definition of the structural_manager class structure.
Data structure definition for HLS constraints.
#define WRAPPED_PROXY_PREFIX
#define ARRAY_1D_STD_DISTRAM_NN_SDS
This file collects some utility functions.
#define SWITCH_COND
constant string identifying the operation performed by a SWITCH_COND.
#define MEMORY_CTRL_TYPE_PROXYN
std::string print_cpu_time(long int t)
massage a long which represents a time interval in milliseconds, into a string suitable for output ...
void BuildProxyWrapper(functional_unit *current_fu, const std::string &orig_fun_name, const std::string &orig_library_name)
Build the proxy wrapper.
bool commutative
property of commutativity
unsigned int get_in_port_size() const
Return the number of input ports.
void add_proxy_function_wrapper(const std::string &library_name, technology_nodeRef techNode_obj, const std::string &orig_fun_name)
Add a proxy wrapper to the WORK library.
refcount< T > lock() const
This class describe a functional unit template.
for each memory at maximum n parallel direct accesses and one indirect access
#define LUT_EXPR
constant string identifying the operation performed by an extract_bit_expr.
void add(int accelnum, int startidx, int endidx)
#define TYPE_MEMCPY
A vertex is of type TYPE_MEMCPY when it is associated with a assignment between struct/union.
technology_managerRef TechM
The technology manager.
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.
const structural_type_descriptorRef & get_typeRef() const
Return the type descriptor of the structural_object.
bool is_fu(const std::string &name) const
#define OUTPUT_LEVEL_PEDANTIC
verbose debugging print is performed.
const CustomUnorderedSet< std::tuple< HLSFlowStep_Type, HLSFlowStepSpecializationConstRef, HLSFlowStep_Relationship > > ComputeHLSRelationships(const DesignFlowStep::RelationshipType relationship_type) const override
Return the set of analyses in relationship with this design step.
#define ASSIGN_VEC_UNSIGNED_STD
#define ASSERT_EXPR_REAL_STD
#define ASSIGN_UNSIGNED_STD
technology_nodeRef get_operation(const std::string &op_name) const
This method returns the operationRef from its name if the functional unit contains an operation of ty...
Class specification of the tree_reindex support class.
#define ENTRY_ID
constant used to represent tree node index of entry operation
#define ASSIGN
constant string identifying the operation performed by an assignment.
void set_id(const std::string &s)
Set the identifier associated with the structural_object.
bool check_for_memory_compliancy(bool Has_extern_allocated_data, technology_nodeRef current_fu, const std::string &memory_ctrl_type, const std::string &channels_type)
virtual const std::string & get_name() const =0
Return the name of the technology node.
#define WORK_LIBRARY
working library.
#define MEMORY_CTRL_TYPE_DPROXYN
#define INFINITE_UINT
UNSIGNED INT representing infinite.
#define GIMPLE_PRAGMA
constant string identifying the operation performed by a GIMPLE_PRAGMA.
#define ARRAY_1D_STD_BRAM_SDS_BUS
void PrintInitialIR() const override
Dump the initial intermediate representation.
technology_managerRef get_technology_manager() const
Returns the technology manager.
virtual void copy(structural_objectRef dest) const
Perform a copy of the structural object.
std::string GetName() const final
Return the name of this design step.
#define ASSERT_EXPR
constant string identifying the operation performed by an assignment.
hlsRef HLS
HLS data structure of the function to be analyzed.
#define NOP
constant string identifying a no operation.
for each memory at maximum n parallel direct accesses and n parallel indirect accesses ...
This class contains the methods to create a frontend flow step.
Data structures used in operations graph.
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.
for each memory at maximum one direct access and one indirect access
#define MEMORY_CTRL_TYPE_SPROXYN
virtual void IntegrateTechnologyLibraries()
Integrate technology libraries with special functional units.
this class is used to manage the command-line or XML options.
#define IUCONVERTER_EXPR_STD
std::string get_compliant_pipelined_unit(double clock, const std::string &pipe_parameter, const technology_nodeRef current_fu, const std::string &curr_op, const std::string &library_name, const std::string &template_suffix, unsigned long long module_prec)
In case the current functional unit has pipelined operations then it return an id identifying the mos...
bool check_templated_units(double clock_period, node_kind_prec_infoRef node_info, const library_managerRef library, technology_nodeRef current_fu, operation *curr_op)
#define ASSIGN_VECTOR_BOOL_STD
unsigned int functionId
this is the identifier of the function to be implemented
Not parsed functionality manager.
#define ARRAY_1D_STD_DISTRAM_N1_SDS
bool is_ram_not_timing_compliant(const HLS_constraintsRef HLS_C, unsigned int var, technology_nodeRef current_fu)
Class implementation of the structural_manager.
#define GIMPLE_ASM
constant string identifying the operation performed by a gimple_asm.
Generic device description.
std::string get_library_name() const
const HLS_constraintsRef HLS_C
store the HLS constraints
Class specification of the manager for each library.
int debug_level
The debug level.
#define BUVECTOR_CONVERTER_STD
This package is used by all HLS packages to manage resource constraints and characteristics.
This class writes different HDL based descriptions (VHDL, Verilog, SystemC) starting from a structura...
refcount< const HLSFlowStepSpecialization > HLSFlowStepSpecializationConstRef
const refcount definition of the class
std::vector< technology_nodeRef > operation_vec
Type definition of a vector of functional_unit.
#define UIVECTOR_CONVERTER_STD
#define GET_INDEX_CONST_NODE(t)
HLS_deviceRef HLS_D
The HLS target.
#define ARRAY_1D_STD_BRAM_N1
#define NOP_EXPR
constant string identifying some conversion expressions
#define DEBUG_LEVEL_VERBOSE
verbose debugging print is performed.
static bool IsPointerType(const tree_nodeConstRef &type)
Return true if treenode index is a pointer.
#define BIVECTOR_CONVERTER_STD
#define VIEW_CONVERT_STD_REAL
technology_nodeRef FU
Functional Unit.
Data structure definition for high-level synthesis flow.
This class describes a generic module.
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.
This class contains the base representation for a generic frontend flow step which works on the whole...
#define GIMPLE_NOP
constant string identifying the operation performed by a gimple_return.
#define NULL_VERTEX
null vertex definition
#define ENCODE_FU_LIB(fu_name, library)
macro used to convert the functional unit name and the library in an unique string.
static time_infoRef factory(const ParameterConstRef Param)
Datastructure to represent memory information in high-level synthesis.
#define PROXY_LIBRARY
proxy library
#define MULTI_READ_COND
constant string identifying the operation performed by a MULTI_READ_COND.
library_managerRef get_library_manager(const std::string &Name) const
Return the library data structure corresponding to the given library id.
Class specification of the manager of the tree structures extracted from the raw file.
#define ASSERT_EXPR_SIGNED_STD
HLS specialization of generic_device.
std::string get_library(const std::string &Name) const
Return the higher priority library where the given component is stored.
#define UUVECTOR_CONVERTER_STD
#define UBVECTOR_CONVERTER_STD
#define IUVECTOR_CONVERTER_STD
static bool IsRealType(const tree_nodeConstRef &type)
Return true if the treenode is of real type.
void add_tech_constraint(technology_nodeRef cur_fu, unsigned int tech_constrain_value, unsigned int pos, bool proxy_constrained)
#define CONVERT_EXPR
constant string identifying some conversion expressions
#define STD_GET_SIZE(structural_obj)
Macro returning the size of a type.
static const std::string ComputeSignature(const FrontendFlowStepType frontend_flow_step_type, const unsigned int function_id)
Compute the signature of a function frontend flow step.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...