Skip to content

Commit

Permalink
HLS allocation constraints fix (ferrandi#118)
Browse files Browse the repository at this point in the history
* HLS allocation constraints fix

* Dominator allocation instance count guard

* Added relative connection offset tag to NG-ULTRA

* HLS backend default dependence fix

* Code refactoring

* Inlined functions need -O2 for the testbench co-simulation.

* STG info computation update

* Fixed a scheduling problem.

* Fixed a possible scheduling conflict between load/store and reading/writing functions.

* STG optimization conditions fix

* Technology manager get_fu overload
get_fu version to search for both functional unit and library name

* Time model unused field

* Added multiple top functions allocation support

* Functions to library components binding fix

* Function dominator allocation update

* Function scope memory interface
Memory allocation policy and channels are now function scope;
memory dominator allocation update

* Register binding refectoring

---------

Co-authored-by: Fabrizio Ferrandi <[email protected]>
Co-authored-by: Claudio Barone <[email protected]>
  • Loading branch information
3 people authored Feb 21, 2023
1 parent 7dfd8c8 commit a71eaf8
Show file tree
Hide file tree
Showing 101 changed files with 2,788 additions and 2,478 deletions.
2 changes: 2 additions & 0 deletions QTCreator-PandA-GitHub.files
Original file line number Diff line number Diff line change
Expand Up @@ -1663,6 +1663,8 @@ src/HLS/hls_constraints.cpp
src/HLS/hls_constraints.hpp
src/HLS/hls_flow/classical_synthesis_flow.cpp
src/HLS/hls_flow/classical_synthesis_flow.hpp
src/HLS/hls_flow/dominator_allocation.cpp
src/HLS/hls_flow/dominator_allocation.hpp
src/HLS/hls_flow/initialize_hls.cpp
src/HLS/hls_flow/initialize_hls.hpp
src/HLS/hls_flow/synthesis/hls_synthesis_flow.cpp
Expand Down
1 change: 1 addition & 0 deletions etc/devices/NanoXplore_devices/nx2h540tsc-seed.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<DSPs_ry_sizes value="16" />
<max_lut_size value="4" />
<OutputDSPConnectionRatio value="3" />
<RelativeConnectionOffset value="2.0" />
<OutputCarryConnectionRatio value="3" />
<use_soft_64_mul value="1" />
</device>
Expand Down
1 change: 1 addition & 0 deletions etc/devices/NanoXplore_devices/nx2h540tsc.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<DSPs_x_sizes value="18"/>
<DSPs_y_sizes value="24"/>
<OutputCarryConnectionRatio value="3"/>
<RelativeConnectionOffset value="2.0" />
<OutputDSPConnectionRatio value="3"/>
<max_lut_size value="4"/>
<use_soft_64_mul value="1"/>
Expand Down
6 changes: 4 additions & 2 deletions panda_regressions/hls/gcc_regression_simple/builtins/printf.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@ main_test (void)
printf ("%s\n", "hello");
printf ("%s\n", *s2);
s3 = s2;
printf ("%s\n", *s3++);
printf ("%s\n", *s3);
s3++;
if (s3 != s2+1 || *s3 != 0)
abort();

printf ("%c", '\n');
printf ("%c", **s2);
s3 = s2;
printf ("%c", **s3++);
printf ("%c", **s3);
s3++;
if (s3 != s2+1 || *s3 != 0)
abort();

Expand Down
431 changes: 277 additions & 154 deletions src/HLS/Makefile.am

Large diffs are not rendered by default.

33 changes: 16 additions & 17 deletions src/HLS/architecture_creation/TopEntityMemoryMapped.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ void TopEntityMemoryMapped::Initialize()
const auto is_addressed_fun = HLSMgr->hasToBeInterfaced(funId) && !is_root_function;
needMemoryMappedRegisters = is_wb4_root || is_addressed_fun || parameters->getOption<bool>(OPT_memory_mapped_top);
AddedComponents.clear();
const auto FB = HLSMgr->CGetFunctionBehavior(funId);
_channels_number = FB->GetChannelsNumber();
_channels_type = FB->GetChannelsType();
}

DesignFlowStep_Status TopEntityMemoryMapped::InternalExec()
Expand Down Expand Up @@ -256,9 +259,8 @@ void TopEntityMemoryMapped::insertMemoryMappedRegister(structural_managerRef SM_
const auto FB = HLSMgr->CGetFunctionBehavior(funId);
const auto BH = FB->CGetBehavioralHelper();

structural_objectRef controlSignal = interfaceObj->find_member("ControlSignal", signal_o_K, interfaceObj);
bool multi_channel_bus = parameters->getOption<MemoryAllocation_ChannelsType>(OPT_channels_type) ==
MemoryAllocation_ChannelsType::MEM_ACC_NN;
const auto controlSignal = interfaceObj->find_member("ControlSignal", signal_o_K, interfaceObj);
const auto multi_channel_bus = _channels_type == MemoryAllocation_ChannelsType::MEM_ACC_NN;

for(const auto& function_parameter : function_parameters)
{
Expand All @@ -277,8 +279,7 @@ void TopEntityMemoryMapped::insertMemoryMappedRegister(structural_managerRef SM_
interfaceObj, HLS->HLS_T->get_technology_manager());
if(multi_channel_bus)
{
resizing_IO(GetPointer<module>(memoryMappedRegister),
parameters->getOption<unsigned int>(OPT_channels_number));
resizing_IO(GetPointerS<module>(memoryMappedRegister), _channels_number);
}
GetPointerS<module>(memoryMappedRegister)
->SetParameter("ALLOCATED_ADDRESS",
Expand Down Expand Up @@ -339,7 +340,7 @@ void TopEntityMemoryMapped::insertMemoryMappedRegister(structural_managerRef SM_
interfaceObj, HLS->HLS_T->get_technology_manager());
if(multi_channel_bus)
{
resizing_IO(GetPointer<module>(returnRegister), parameters->getOption<unsigned int>(OPT_channels_number));
resizing_IO(GetPointer<module>(returnRegister), _channels_number);
}
GetPointer<module>(returnRegister)
->SetParameter("ALLOCATED_ADDRESS", HLSMgr->Rmem->get_symbol(returnType, HLS->functionId)->get_symbol_name());
Expand Down Expand Up @@ -401,15 +402,14 @@ void TopEntityMemoryMapped::insertStartDoneLogic(structural_managerRef SM_mm, st

if(HLSMgr->CGetCallGraphManager()->ExistsAddressedFunction())
{
bool multi_channel_bus = parameters->getOption<MemoryAllocation_ChannelsType>(OPT_channels_type) ==
MemoryAllocation_ChannelsType::MEM_ACC_NN;
std::string component_name = multi_channel_bus ? NOTYFY_CALLER_MINIMALN_FU : NOTYFY_CALLER_MINIMAL_FU;
structural_objectRef notifyCaller = SM_mm->add_module_from_technology_library(
const auto multi_channel_bus = _channels_type == MemoryAllocation_ChannelsType::MEM_ACC_NN;
const auto component_name = multi_channel_bus ? NOTYFY_CALLER_MINIMALN_FU : NOTYFY_CALLER_MINIMAL_FU;
const auto notifyCaller = SM_mm->add_module_from_technology_library(
"notifyCaller", component_name, HLS->HLS_T->get_technology_manager()->get_library(component_name),
interfaceObj, HLS->HLS_T->get_technology_manager());
if(multi_channel_bus)
{
resizing_IO(GetPointer<module>(notifyCaller), parameters->getOption<unsigned int>(OPT_channels_number));
resizing_IO(GetPointerS<module>(notifyCaller), _channels_number);
}
setBusSizes(notifyCaller, HLSMgr);
connectClockAndReset(SM_mm, interfaceObj, notifyCaller);
Expand All @@ -428,9 +428,8 @@ void TopEntityMemoryMapped::insertStartDoneLogic(structural_managerRef SM_mm, st

void TopEntityMemoryMapped::insertStatusRegister(structural_managerRef SM_mm, structural_objectRef wrappedObj)
{
bool multi_channel_bus = parameters->getOption<MemoryAllocation_ChannelsType>(OPT_channels_type) ==
MemoryAllocation_ChannelsType::MEM_ACC_NN;
structural_objectRef interfaceObj = SM_mm->get_circ();
const auto multi_channel_bus = _channels_type == MemoryAllocation_ChannelsType::MEM_ACC_NN;
const auto interfaceObj = SM_mm->get_circ();
if(HLSMgr->CGetCallGraphManager()->ExistsAddressedFunction())
{
const auto component_name = multi_channel_bus ? STATUS_REGISTERN_FU : STATUS_REGISTER_FU;
Expand All @@ -439,7 +438,7 @@ void TopEntityMemoryMapped::insertStatusRegister(structural_managerRef SM_mm, st
interfaceObj, HLS->HLS_T->get_technology_manager());
if(multi_channel_bus)
{
resizing_IO(GetPointer<module>(statusRegister), parameters->getOption<unsigned int>(OPT_channels_number));
resizing_IO(GetPointer<module>(statusRegister), _channels_number);
}
GetPointerS<module>(statusRegister)
->SetParameter("ALLOCATED_ADDRESS",
Expand Down Expand Up @@ -482,7 +481,7 @@ void TopEntityMemoryMapped::insertStatusRegister(structural_managerRef SM_mm, st
interfaceObj, HLS->HLS_T->get_technology_manager());
if(multi_channel_bus)
{
resizing_IO(GetPointer<module>(statusRegister), parameters->getOption<unsigned int>(OPT_channels_number));
resizing_IO(GetPointer<module>(statusRegister), _channels_number);
}
GetPointerS<module>(statusRegister)
->SetParameter("ALLOCATED_ADDRESS",
Expand Down Expand Up @@ -553,7 +552,7 @@ static void propagateInterface(structural_managerRef SM, structural_objectRef wr
continue;
}

SM->add_port(portObj->get_id(), portObj->get_port_direction(), interfaceObj, portObj->get_typeRef());
SM->add_port(portID, portObj->get_port_direction(), interfaceObj, portObj->get_typeRef());
}

connectClockAndReset(SM, interfaceObj, wrappedObj);
Expand Down
7 changes: 7 additions & 0 deletions src/HLS/architecture_creation/TopEntityMemoryMapped.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include <list>
#include <string>
class module;
enum class MemoryAllocation_ChannelsType;

/**
* @brief Build a wrapper layer on the top entity implementing the
Expand Down Expand Up @@ -92,6 +93,12 @@ class TopEntityMemoryMapped : public top_entity
/// true when the module is a root function
bool is_root_function{false};

/// Function scope channels number
unsigned int _channels_number;

/// Function scope channels type
MemoryAllocation_ChannelsType _channels_type;

/**
* Allocates the in/out parameters of the module as internal registers
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ datapath_parallel_cs::ComputeHLSRelationships(const DesignFlowStep::Relationship
{
case DEPENDENCE_RELATIONSHIP:
{
ret.insert(std::make_tuple(HLSFlowStep_Type::INITIALIZE_HLS, HLSFlowStepSpecializationConstRef(),
HLSFlowStep_Relationship::SAME_FUNCTION));
ret.insert(std::make_tuple(HLSFlowStep_Type::DOMINATOR_ALLOCATION, HLSFlowStepSpecializationConstRef(),
HLSFlowStep_Relationship::WHOLE_APPLICATION));
ret.insert(std::make_tuple(HLSFlowStep_Type::OMP_BODY_LOOP_SYNTHESIS_FLOW, HLSFlowStepSpecializationConstRef(),
HLSFlowStep_Relationship::CALLED_FUNCTIONS));
break;
Expand Down
7 changes: 4 additions & 3 deletions src/HLS/architecture_creation/top_entity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,8 @@ void top_entity::add_ports(structural_objectRef circuit, structural_objectRef cl
top_obj = SM->add_port(FB->CGetBehavioralHelper()->PrintVariable(function_parameter), port_o::IN, circuit,
port_type);
}
if(has_registered_inputs)
const auto is_pipelined = HLSMgr->CGetFunctionBehavior(funId)->is_simple_pipeline();
if(has_registered_inputs && !is_pipelined)
{
const auto port_prefix = GetPointerS<port_o>(in_obj)->get_id();
if(in_obj->get_kind() == port_vector_o_K)
Expand Down Expand Up @@ -657,8 +658,8 @@ void top_entity::add_ports(structural_objectRef circuit, structural_objectRef cl

void top_entity::add_command_signals(structural_objectRef circuit)
{
structural_objectRef Datapath = HLS->datapath->get_circ();
structural_objectRef Controller = HLS->controller->get_circ();
const auto Datapath = HLS->datapath->get_circ();
const auto Controller = HLS->controller->get_circ();

for(const auto& selector : HLS->Rconn->GetSelectors())
{
Expand Down
19 changes: 9 additions & 10 deletions src/HLS/backend/generate_hdl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ generate_hdl::ComputeHLSRelationships(const DesignFlowStep::RelationshipType rel
{
ret.insert(std::make_tuple(HLSFlowStep_Type::HLS_SYNTHESIS_FLOW, HLSFlowStepSpecializationConstRef(),
HLSFlowStep_Relationship::ALL_FUNCTIONS));
if(parameters->isOption(OPT_discrepancy_hw) and parameters->getOption<bool>(OPT_discrepancy_hw))
if(parameters->isOption(OPT_discrepancy_hw) && parameters->getOption<bool>(OPT_discrepancy_hw))
{
ret.insert(std::make_tuple(HLSFlowStep_Type::HW_DISCREPANCY_ANALYSIS, HLSFlowStepSpecializationConstRef(),
HLSFlowStep_Relationship::TOP_FUNCTION));
Expand All @@ -110,20 +110,19 @@ generate_hdl::ComputeHLSRelationships(const DesignFlowStep::RelationshipType rel

generate_hdl::~generate_hdl() = default;

bool generate_hdl::HasToBeExecuted() const
{
return true;
}

DesignFlowStep_Status generate_hdl::Exec()
{
HDL_managerRef HM =
HDL_managerRef(new HDL_manager(HLSMgr, HLSMgr->get_HLS_target()->get_target_device(), parameters));
auto file_name = parameters->getOption<std::string>(OPT_top_file);
HDL_manager HM(HLSMgr, HLSMgr->get_HLS_target()->get_target_device(), parameters);
const auto file_name = parameters->getOption<std::string>(OPT_top_file);
std::list<structural_objectRef> top_circuits;
const auto root_functions = HLSMgr->CGetCallGraphManager()->GetRootFunctions();
std::transform(root_functions.begin(), root_functions.end(), std::back_inserter(top_circuits),
[&](unsigned int top_function) { return HLSMgr->get_HLS(top_function)->top->get_circ(); });
HM->hdl_gen(file_name, top_circuits, false, HLSMgr->hdl_files, HLSMgr->aux_files);
HM.hdl_gen(file_name, top_circuits, false, HLSMgr->hdl_files, HLSMgr->aux_files);
return DesignFlowStep_Status::SUCCESS;
}

bool generate_hdl::HasToBeExecuted() const
{
return true;
}
6 changes: 3 additions & 3 deletions src/HLS/binding/interconnection/conn_binding_creator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,12 @@ conn_binding_creator::ComputeHLSRelationships(const DesignFlowStep::Relationship

void conn_binding_creator::add_parameter_ports()
{
const FunctionBehaviorConstRef FB = HLSMgr->CGetFunctionBehavior(funId);
const BehavioralHelperConstRef BH = FB->CGetBehavioralHelper();
const auto FB = HLSMgr->CGetFunctionBehavior(funId);
const auto BH = FB->CGetBehavioralHelper();
input_ports.clear();
output_ports.clear();
/// list containing the parameters of the original function (representing input and output values)
const std::list<unsigned int>& function_parameters = BH->get_parameters();
const auto function_parameters = BH->get_parameters();
PRINT_DBG_STRING(DEBUG_LEVEL_PEDANTIC, debug_level, "Parameters values: ");
for(auto function_parameter : function_parameters)
{
Expand Down
4 changes: 2 additions & 2 deletions src/HLS/binding/interconnection/conn_binding_cs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ void conn_binding_cs::instantiate_suspension_component(const HLS_managerRef HLSM
{
structural_objectRef portStart = curr_gate->find_member(STR(START_PORT_NAME), port_o_K, curr_gate);
structural_objectRef startMemOp = GetPointer<port_o>(portStart)->find_bounded_object();
THROW_ASSERT(startMemOp != NULL, "No start port for mem_ctrl_found");
THROW_ASSERT(startMemOp != nullptr, "No start port for mem_ctrl_found");
andStartMemOp_required = true;
break;
}
Expand Down Expand Up @@ -188,7 +188,7 @@ void conn_binding_cs::instantiate_suspension_component(const HLS_managerRef HLSM
{
structural_objectRef portStart = curr_gate->find_member(STR(START_PORT_NAME), port_o_K, curr_gate);
structural_objectRef startMemOp = GetPointer<port_o>(portStart)->find_bounded_object();
THROW_ASSERT(startMemOp != NULL, "No start port for mem_ctrl_found");
THROW_ASSERT(startMemOp != nullptr, "No start port for mem_ctrl_found");
SM->add_connection(startMemOp, GetPointer<port_o>(port_in_and)->get_port(1));
break;
}
Expand Down
26 changes: 15 additions & 11 deletions src/HLS/binding/module/cdfc_module_binding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1950,26 +1950,30 @@ DesignFlowStep_Status cdfc_module_binding::InternalExec()
total_area_muxes_prev = total_area_muxes;
total_area_muxes = total_area_muxes_initial;

DesignFlowStepRef regb;
// if(iteration%2)
if(parameters->getOption<HLSFlowStep_Type>(OPT_register_allocation_algorithm) ==
HLSFlowStep_Type::WEIGHTED_CLIQUE_REGISTER_BINDING)
{
regb = GetPointer<const HLSFlowStepFactory>(design_flow_manager.lock()->CGetDesignFlowStepFactory("HLS"))
DesignFlowStepRef regb;
// if(iteration%2)
if(parameters->getOption<HLSFlowStep_Type>(OPT_register_allocation_algorithm) ==
HLSFlowStep_Type::WEIGHTED_CLIQUE_REGISTER_BINDING)
{
regb =
GetPointer<const HLSFlowStepFactory>(design_flow_manager.lock()->CGetDesignFlowStepFactory("HLS"))
->CreateHLSFlowStep(
HLSFlowStep_Type::WEIGHTED_CLIQUE_REGISTER_BINDING, funId,
HLSFlowStepSpecializationConstRef(new WeightedCliqueRegisterBindingSpecialization(
parameters->getOption<CliqueCovering_Algorithm>(
OPT_weighted_clique_register_algorithm))));
}
else
{
regb = GetPointer<const HLSFlowStepFactory>(design_flow_manager.lock()->CGetDesignFlowStepFactory("HLS"))
}
else
{
regb =
GetPointer<const HLSFlowStepFactory>(design_flow_manager.lock()->CGetDesignFlowStepFactory("HLS"))
->CreateHLSFlowStep(
parameters->getOption<HLSFlowStep_Type>(OPT_register_allocation_algorithm), funId);
}
regb->Initialize();
regb->Exec();
}
regb->Initialize();
regb->Exec();
}

if(output_level >= OUTPUT_LEVEL_VERBOSE)
Expand Down
16 changes: 8 additions & 8 deletions src/HLS/binding/module/easy_module_binding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ easy_module_binding::ComputeHLSRelationships(const DesignFlowStep::RelationshipT
{
case DEPENDENCE_RELATIONSHIP:
{
ret.insert(std::make_tuple(HLSFlowStep_Type::INITIALIZE_HLS, HLSFlowStepSpecializationConstRef(),
HLSFlowStep_Relationship::SAME_FUNCTION));
ret.insert(std::make_tuple(HLSFlowStep_Type::DOMINATOR_ALLOCATION, HLSFlowStepSpecializationConstRef(),
HLSFlowStep_Relationship::WHOLE_APPLICATION));
if(HLSMgr->get_HLS(funId))
{
ret.insert(std::make_tuple(HLSMgr->get_HLS(funId)->chaining_algorithm, HLSFlowStepSpecializationConstRef(),
Expand Down Expand Up @@ -146,18 +146,18 @@ DesignFlowStep_Status easy_module_binding::InternalExec()
const auto TM = HLSMgr->get_tree_manager();
// resource binding and allocation info
fu_binding& fu = *(HLS->Rfu);
const AllocationInformationConstRef allocation_information = HLS->allocation_information;
const auto allocation_information = HLS->allocation_information;
// pointer to a Control, Data dependence and antidependence graph graph
const FunctionBehaviorConstRef FB = HLSMgr->CGetFunctionBehavior(funId);
const OpGraphConstRef sdg = FB->CGetOpGraph(FunctionBehavior::SDG);
const auto FB = HLSMgr->CGetFunctionBehavior(funId);
const auto sdg = FB->CGetOpGraph(FunctionBehavior::SDG);

unsigned int fu_unit;
/// compute unshared resources
std::map<unsigned int, unsigned int> n_shared_fu;
for(const auto operation : sdg->CGetOperations())
{
const auto id = sdg->CGetOpNodeInfo(operation)->GetNodeId();
if(id == ENTRY_ID or id == EXIT_ID)
if(id == ENTRY_ID || id == EXIT_ID)
{
continue;
}
Expand All @@ -175,7 +175,7 @@ DesignFlowStep_Status easy_module_binding::InternalExec()
n_shared_fu[fu_unit] = 1 + n_shared_fu[fu_unit];
}
}
if(output_level >= OUTPUT_LEVEL_MINIMUM and output_level <= OUTPUT_LEVEL_PEDANTIC)
if(output_level >= OUTPUT_LEVEL_MINIMUM && output_level <= OUTPUT_LEVEL_PEDANTIC)
{
INDENT_OUT_MEX(OUTPUT_LEVEL_MINIMUM, output_level, "");
}
Expand Down Expand Up @@ -247,7 +247,7 @@ DesignFlowStep_Status easy_module_binding::InternalExec()
INDENT_OUT_MEX(OUTPUT_LEVEL_MINIMUM, output_level,
"---Bound operations:" + STR(easy_bound_vertices.size()) + "/" + STR(boost::num_vertices(*sdg)));
}
if(output_level >= OUTPUT_LEVEL_MINIMUM and output_level <= OUTPUT_LEVEL_PEDANTIC)
if(output_level >= OUTPUT_LEVEL_MINIMUM && output_level <= OUTPUT_LEVEL_PEDANTIC)
{
STOP_TIME(step_time);
INDENT_OUT_MEX(OUTPUT_LEVEL_MINIMUM, output_level,
Expand Down
Loading

0 comments on commit a71eaf8

Please sign in to comment.