76     : memory_allocation_policy(_memory_allocation_policy),
    77       memory_allocation_channels_type(_memory_allocation_channels_type)
    99          ret += 
"EXT_PIPELINED_BRAM";
   136                                      const DesignFlowManagerConstRef _design_flow_manager,
   139     : 
HLS_step(_parameters, _HLSMgr, _design_flow_manager, _hls_flow_step_type,
   140                _hls_flow_step_specialization and
   142                    _hls_flow_step_specialization :
   158    switch(relationship_type)
   184    const auto cg_man = 
HLSMgr->CGetCallGraphManager();
   185    func_list = cg_man->GetReachedBodyFunctions();
   189       const auto function_behavior = 
HLSMgr->CGetFunctionBehavior(It);
   191       const auto& parm_decl_copied = function_behavior->get_parm_decl_copied();
   192       for(
const auto p : parm_decl_copied)
   194          HLSMgr->Rmem->add_parm_decl_copied(p);
   197       const auto& parm_decl_stored = function_behavior->get_parm_decl_stored();
   198       for(
const auto p : parm_decl_stored)
   200          HLSMgr->Rmem->add_parm_decl_stored(p);
   203       const auto& parm_decl_loaded = function_behavior->get_parm_decl_loaded();
   204       for(
const auto p : parm_decl_loaded)
   206          HLSMgr->Rmem->add_actual_parm_loaded(p);
   214    bool use_unknown_address = 
false;
   215    bool has_unaligned_accesses = 
false;
   216    auto m64P = 
parameters->getOption<std::string>(OPT_gcc_m32_mx32).find(
"-m64") != std::string::npos;
   217    bool assume_aligned_access_p =
   219    const auto TreeM = 
HLSMgr->get_tree_manager();
   222       const auto FB = 
HLSMgr->CGetFunctionBehavior(It);
   223       const auto BH = FB->CGetBehavioralHelper();
   224       const auto& function_parameters = BH->get_parameters();
   226       if(FB->get_dereference_unknown_addr())
   229                         "---This function uses unknown addresses deref: " + BH->get_function_name());
   232       use_unknown_address |= FB->get_dereference_unknown_addr();
   234       if(FB->get_unaligned_accesses())
   237                         "---This function performs unaligned accesses: " + BH->get_function_name());
   238          if(assume_aligned_access_p)
   240             THROW_ERROR(
"Option --aligned-access have been specified on a function with unaligned accesses");
   244       has_unaligned_accesses |= FB->get_unaligned_accesses();
   246       for(
auto const parameter : function_parameters)
   248          if(
HLSMgr->Rmem->is_parm_decl_copied(parameter) && !
HLSMgr->Rmem->is_parm_decl_stored(parameter))
   250             HLSMgr->Rmem->set_implicit_memcpy(
true);
   255    if(
HLSMgr->Rmem->has_implicit_memcpy())
   257       const auto memcpy_function = TreeM->GetFunction(
MEMCPY);
   258       func_list.insert(memcpy_function->index);
   261    unsigned long long maximum_bus_size = 0;
   262    bool use_databus_width = 
false;
   263    bool has_intern_shared_data = 
false;
   264    bool has_misaligned_indirect_ref = 
HLSMgr->Rmem->has_packed_vars();
   265    bool needMemoryMappedRegisters = 
false;
   266    const auto call_graph_manager = 
HLSMgr->CGetCallGraphManager();
   267    const auto root_functions = call_graph_manager->GetRootFunctions();
   269    for(
auto fun_id : func_list)
   271       const auto function_behavior = 
HLSMgr->CGetFunctionBehavior(fun_id);
   272       const auto behavioral_helper = function_behavior->CGetBehavioralHelper();
   273       const auto is_interfaced = 
HLSMgr->hasToBeInterfaced(behavioral_helper->get_function_index());
   274       const auto fname = behavioral_helper->GetMangledFunctionName();
   275       const auto func_arch = 
HLSMgr->module_arch->GetArchitecture(fname);
   276       if(function_behavior->get_has_globals() && 
parameters->isOption(OPT_expose_globals) &&
   277          parameters->getOption<
bool>(OPT_expose_globals))
   279          has_intern_shared_data = 
true;
   281       const auto& function_parameters = behavioral_helper->get_parameters();
   282       for(
const auto function_parameter : function_parameters)
   284          const auto pname = behavioral_helper->PrintVariable(function_parameter);
   285          if(func_arch && root_functions.find(fun_id) != root_functions.end())
   287             THROW_ASSERT(func_arch->parms.find(pname) != func_arch->parms.end(),
   288                          "Parameter " + pname + 
" not found in function " + fname);
   289             const auto& parm_attrs = func_arch->parms.at(pname);
   290             const auto& iface_attrs = func_arch->ifaces.at(parm_attrs.at(FunctionArchitecture::parm_bundle));
   291             const auto iface_mode = iface_attrs.at(FunctionArchitecture::iface_mode);
   292             if(iface_mode != 
"default")
   297          if(
HLSMgr->Rmem->is_parm_decl_copied(function_parameter) &&
   298             !
HLSMgr->Rmem->is_parm_decl_stored(function_parameter))
   300             use_databus_width = 
true;
   301             maximum_bus_size = 
std::max(maximum_bus_size, 8ull);
   305             use_unknown_address = 
true;
   308                THROW_WARNING(
"This function uses unknown addresses: " + behavioral_helper->get_function_name());
   312       if(function_behavior->has_packed_vars())
   314          has_misaligned_indirect_ref = 
true;
   316       const auto& parm_decl_stored = function_behavior->get_parm_decl_stored();
   317       for(
unsigned int p : parm_decl_stored)
   324                     "Analyzing function for bus size: " + behavioral_helper->get_function_name());
   326       graph::vertex_iterator v, v_end;
   327       const auto TM = 
HLSMgr->get_tree_manager();
   328       const auto fnode = TM->CGetTreeReindex(fun_id);
   330       if(
HLSMgr->design_interface_io.find(fname) != 
HLSMgr->design_interface_io.end())
   332          for(
const auto& bb2arg2stmtsR : 
HLSMgr->design_interface_io.find(fname)->second)
   334             for(
const auto& arg2stms : bb2arg2stmtsR.second)
   336                if(arg2stms.second.size() > 0)
   338                   for(
const auto& stmt : arg2stms.second)
   340                      const auto op_it = g->CGetOpGraphInfo()->tree_node_to_operation.find(stmt);
   341                      if(op_it != g->CGetOpGraphInfo()->tree_node_to_operation.end())
   343                         RW_stmts.insert(op_it->second);
   351       for(boost::tie(v, v_end) = boost::vertices(*g); v != v_end; ++v)
   353          if(RW_stmts.find(*v) != RW_stmts.end())
   357          const auto current_op = g->CGetOpNodeInfo(*v)->GetOperation();
   358          const auto var_read = 
HLSMgr->get_required_values(fun_id, *v);
   362             const auto curr_tn = TreeM->CGetTreeNode(g->CGetOpNodeInfo(*v)->GetNodeId());
   363             const auto me = GetPointer<const gimple_assign>(curr_tn);
   364             THROW_ASSERT(me, 
"only gimple_assign's are allowed as memory operations");
   377                has_misaligned_indirect_ref = 
true;
   380             if(!has_misaligned_indirect_ref)
   386             if(!has_intern_shared_data && var && function_behavior->is_variable_mem(var->index) &&
   387                !
HLSMgr->Rmem->is_private_memory(var->index) && 
parameters->isOption(OPT_expose_globals) &&
   388                parameters->getOption<
bool>(OPT_expose_globals))
   392                   (((!vd->scpe || 
GET_NODE(vd->scpe)->get_kind() == translation_unit_decl_K) && !vd->static_flag) ||
   395                   has_intern_shared_data =
   399             unsigned long long value_bitsize;
   402                const auto size_var = std::get<0>(var_read[0]);
   409                const auto size_var = 
HLSMgr->get_produced_value(fun_id, *v);
   414             if(!(function_behavior->is_variable_mem(var->index) && 
HLSMgr->Rmem->is_private_memory(var->index)))
   416                maximum_bus_size = 
std::max(maximum_bus_size, value_bitsize);
   419                           " with maximum_bus_size=" + 
STR(maximum_bus_size) + 
" " + curr_tn->ToString());
   425                use_databus_width = 
true;
   426                maximum_bus_size = 
std::max(maximum_bus_size, 8ull);
   427                if(assume_aligned_access_p)
   429                   THROW_ERROR(
"Option --aligned-access cannot be used in presence of memcpy, memcmp or memset");
   433             auto vr_it_end = var_read.end();
   434             for(
auto vr_it = var_read.begin(); vr_it != vr_it_end; ++vr_it)
   436                const auto var = std::get<0>(*vr_it);
   439                   const auto var_node = TreeM->CGetTreeReindex(var);
   455                   maximum_bus_size = 
std::max(maximum_bus_size, bitsize);
   457                                 " with maximum_bus_size=" + 
STR(maximum_bus_size) + 
" " +
   458                                     g->CGetOpNodeInfo(*v)->node->ToString());
   464       const auto top_functions = 
HLSMgr->CGetCallGraphManager()->GetRootFunctions();
   465       const auto local_needMemoryMappedRegisters = top_functions.count(fun_id) ?
   466                                                        parameters->getOption<
bool>(OPT_memory_mapped_top) :
   467                                                        HLSMgr->hasToBeInterfaced(fun_id);
   468       needMemoryMappedRegisters = needMemoryMappedRegisters || local_needMemoryMappedRegisters;
   469       if(local_needMemoryMappedRegisters)
   471          unsigned long long addr_bus_bitsize;
   472          if(
parameters->isOption(OPT_addr_bus_bitsize))
   474             addr_bus_bitsize = 
parameters->getOption<
unsigned int>(OPT_addr_bus_bitsize);
   478             addr_bus_bitsize = m64P ? 64 : 32;
   480          for(
const auto& par : behavioral_helper->GetParameters())
   483             const auto is_a_struct_union =
   485             if(is_a_struct_union)
   487                maximum_bus_size = 
std::max(addr_bus_bitsize, maximum_bus_size);
   501                     "Analyzed function for bus size: " + behavioral_helper->get_function_name());
   504    const auto HLS_D = 
HLSMgr->get_HLS_device();
   505    unsigned long long bram_bitsize = 0;
   506    unsigned addr_bus_bitsize = 0;
   507    const auto bram_bitsize_min = HLS_D->get_parameter<
unsigned int>(
"BRAM_bitsize_min");
   508    const auto bram_bitsize_max = HLS_D->get_parameter<
unsigned int>(
"BRAM_bitsize_max");
   509    HLSMgr->Rmem->set_maxbram_bitsize(bram_bitsize_max);
   511    maximum_bus_size = ceil_pow2(maximum_bus_size);
   513    if(has_misaligned_indirect_ref || has_unaligned_accesses)
   515       if(maximum_bus_size > bram_bitsize_max)
   517          THROW_ERROR(
"Unsupported data bus size. In case, try a device supporting this BRAM BITSIZE: " +
   518                      STR(maximum_bus_size) + 
" available maximum BRAM BITSIZE: " + 
STR(bram_bitsize_max));
   522          bram_bitsize = maximum_bus_size;
   525    else if(maximum_bus_size / 2 > bram_bitsize_max)
   527       THROW_ERROR(
"Unsupported data bus size. In case, try a device supporting this BRAM BITSIZE: " +
   528                   STR(maximum_bus_size / 2) + 
" available maximum BRAM BITSIZE: " + 
STR(bram_bitsize_max));
   532       bram_bitsize = maximum_bus_size / 2;
   535    if(bram_bitsize < bram_bitsize_min)
   537       bram_bitsize = bram_bitsize_min;
   545    if(
parameters->isOption(OPT_addr_bus_bitsize))
   547       addr_bus_bitsize = 
parameters->getOption<
unsigned int>(OPT_addr_bus_bitsize);
   549    else if(use_unknown_address)
   551       addr_bus_bitsize = m64P ? 64 : 32;
   556       addr_bus_bitsize = m64P ? 64 : 32;
   558    else if(
HLSMgr->Rmem->get_memory_address() - 
HLSMgr->base_address > 0)
   560       addr_bus_bitsize = m64P ? 64 : 32;
   564       unsigned long long int addr_range = 
HLSMgr->Rmem->get_max_address();
   568              std::max(addr_range, ((2 * HLS_D->get_parameter<
unsigned long long int>(
"BRAM_bitsize_max")) / 8));
   572       for(index = 1; addr_range >= (1ull << 
index); ++
index)
   576       addr_bus_bitsize = 
index;
   577       if(
HLSMgr->Rmem->count_non_private_internal_symbols() == 1)
   583    if(needMemoryMappedRegisters)
   586       maximum_bus_size = 
std::max(maximum_bus_size, static_cast<unsigned long long>(addr_bus_bitsize));
   588    HLSMgr->set_address_bitsize(addr_bus_bitsize);
   589    HLSMgr->Rmem->set_bus_data_bitsize(maximum_bus_size);
   592    HLSMgr->Rmem->set_bram_bitsize(bram_bitsize);
   593    HLSMgr->Rmem->set_intern_shared_data(has_intern_shared_data);
   594    HLSMgr->Rmem->set_use_unknown_addresses(use_unknown_address);
   595    HLSMgr->Rmem->set_unaligned_accesses(has_unaligned_accesses);
   600                   "---" + (use_databus_width ? std::string(
"Spec may exploit DATA bus width") :
   601                                                std::string(
"Spec may not exploit DATA bus width")));
   603                   "---" + (!use_unknown_address ?
   604                                std::string(
"All the data have a known address") :
   605                                std::string(
"Spec accesses data having an address unknown at compile time")));
   607                   "---" + (!has_intern_shared_data ? std::string(
"Internal data is not externally accessible") :
   608                                                      std::string(
"Internal data may be accessed")));
   610                   "---DATA bus bitsize: " + 
STR(
HLSMgr->Rmem->get_bus_data_bitsize()));
   613                   "---SIZE bus bitsize: " + 
STR(
HLSMgr->Rmem->get_bus_size_bitsize()));
   614    if(
HLSMgr->Rmem->has_all_pointers_resolved())
   618    if(has_unaligned_accesses)
   622    if(
HLSMgr->Rmem->get_allocated_parameters_memory())
   625                      "---Total amount of memory allocated for memory mapped parameters: " +
   626                          STR(
HLSMgr->Rmem->get_allocated_parameters_memory()));
   629                   "---Internally allocated memory (no private memories): " +
   630                       STR(
HLSMgr->Rmem->get_allocated_internal_memory()));
   632                   "---Internally allocated memory: " + 
STR(
HLSMgr->Rmem->get_allocated_space()));
   643    const auto function_behavior = 
HLSMgr->CGetFunctionBehavior(functionId);
   644    const auto behavioral_helper = function_behavior->CGetBehavioralHelper();
   645    const auto function_return = behavioral_helper->GetFunctionReturnType(functionId);
   650                        behavioral_helper->get_parameters().empty() && !function_return);
   659    const auto& topParams = behavioral_helper->get_parameters();
   660    for(
auto itr = topParams.begin(), end = topParams.end(); itr != end; ++itr)
   664       auto par_name = behavioral_helper->PrintVariable(*itr);
   665       Rmem->
add_parameter(behavioral_helper->get_function_index(), *itr, par_name, !function_return && itr_next == end);
   678       Rmem->
add_parameter(behavioral_helper->get_function_index(), function_return, 
"@return_" + functionName, 
true);
   696    std::map<unsigned int, unsigned int> cur_bb_ver;
   697    std::map<unsigned int, unsigned int> cur_bitvalue_ver;
   698    const auto CGMan = 
HLSMgr->CGetCallGraphManager();
   699    for(
const auto i : CGMan->GetReachedBodyFunctions())
   701       const auto FB = 
HLSMgr->CGetFunctionBehavior(i);
   702       cur_bb_ver[i] = FB->GetBBVersion();
   703       cur_bitvalue_ver[i] = FB->GetBitValueVersion();
   711    const auto CGMan = 
HLSMgr->CGetCallGraphManager();
   712    for(
const auto i : CGMan->GetReachedBodyFunctions())
   714       const auto FB = 
HLSMgr->CGetFunctionBehavior(i);
 #define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed. 
static bool IsUnionType(const tree_nodeConstRef &type)
Return if treenode is an union. 
const HLS_managerRef HLSMgr
information about all the HLS synthesis 
static bool IsComplexType(const tree_nodeConstRef &type)
Return if treenode is a complex. 
Data structure representing the entire HLS information. 
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;. 
static std::string name_function(const tree_managerConstRef &tm, const unsigned int index)
Return the name of the function. 
#define GET_TYPE(data, vertex_index)
Helper macro returning the type associated with a node. 
#define MEMCPY
constant string identifying the operation performed when two objects are memcopied. 
static unsigned long long AccessedMaximumBitsize(const tree_nodeConstRef &type_node, unsigned long long bitsize)
return the maximum bitsize associated with the elements accessible through type_node ...
File containing functions and utilities to support the printing of debug messagges. 
#define PRINT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;. 
#define OUTPUT_LEVEL_NONE
no output print is performed. 
unsigned long long int get_parameter_base_address(unsigned int funId, unsigned int var) const
Get the current base address of the given variable. 
#define GET_CLASS(obj)
Macro returning the actual type of an object. 
std::map< unsigned int, unsigned int > last_bb_ver
The version of BB IR representation on which this step was applied. 
~memory_allocation() override
Destructor. 
Definition of the class representing a generic C application. 
const int output_level
The output level. 
only external memory access Datapath see only 1 memory port, while the bus manage parallel accesses ...
static bool is_a_misaligned_vector(const tree_managerConstRef &TM, const unsigned int index)
Return true if the treenode index is a a misaligned access to a vector data object. 
RelationshipType
The relationship type. 
Source must be executed to satisfy target. 
mathematical utility function not provided by standard libraries 
#define INDENT_OUT_MEX(outLevel, curOutLevel, mex)
all objects that need to be stored in memory are allocated on an external pipelined memory ...
void finalize_memory_allocation()
Performs a final analysis of the memory allocation to finalize the data-structure. 
#define GET_NAME(data, vertex_index)
Helper macro returning the name associated with a node. 
virtual DesignFlowStep_Status InternalExec()=0
Execute the step. 
MemoryAllocation_ChannelsType
The number of channels. 
static bool IsVolatile(const tree_nodeConstRef &tn)
return true in case the tree node corresponds to a volatile variable 
all objects that need to be stored in memory are allocated on an external memory 
MemoryAllocationSpecialization(const MemoryAllocation_Policy memory_allocation_policy, const MemoryAllocation_ChannelsType memory_allocation_channels_type)
Constructor. 
#define OUTPUT_LEVEL_MINIMUM
minimum debugging print is performed. 
redefinition of map to manage ordered/unordered structures 
static bool is_packed_access(const tree_managerConstRef &TreeM, unsigned int node_index)
Check if the access is on a packed data structure or not. 
#define TYPE_LOAD
Constant string identifying a memory load operation. 
#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. 
Auxiliary methods for manipulating string. 
memory_allocation(const ParameterConstRef _parameters, const HLS_managerRef HLSMgr, const DesignFlowManagerConstRef design_flow_manager, const HLSFlowStep_Type hls_flow_step_type, const HLSFlowStepSpecializationConstRef hls_flow_step_specialization=HLSFlowStepSpecializationConstRef())
Constructor. 
#define MEMSET
constant string identifying the operation performed when two objects are memsetted. 
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached 
T ceil_log2(T x)
Return the smallest n such that 2**n >= X. 
static unsigned long long Size(const tree_nodeConstRef &tn)
Return the size of a tree object. 
all global variables, static variables and strings are allocated on BRAMs 
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...
Target must be reexecuted. 
redefinition of set to manage ordered/unordered structures 
#define TYPE_STORE
Constant string identifying a memory store operation. 
void allocate_parameters(unsigned int functionId, memoryRef Rmem=nullptr)
Allocate parameters for given function. 
#define MEMCMP
constant string identifying the operation performed when two objects are memcompared. 
#define GET_CONST_NODE(t)
Classes specification of the tree_node data structures. 
const MemoryAllocation_ChannelsType memory_allocation_channels_type
number of channels 
const ParameterConstRef parameters
Set of input parameters. 
DesignFlowStep_Status
The status of a step. 
bool HasToBeExecuted() const override
Check if this step has actually to be executed. 
Base class to allocate memories in high-level synthesis. 
static bool is_a_pointer(const tree_managerConstRef &TM, const unsigned int index)
Return if treenode index is a pointer. 
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way 
std::map< unsigned int, unsigned int > last_bitvalue_ver
The version of bit value IR representation on which this step was applied. 
T compute_n_bytes(T bitsize)
static void check_bitwidth(unsigned long long prec)
check if the maximum bitwidth used for registers, busses, muxes, etc. is compatible with prec ...
This file collects some utility functions. 
for each memory at maximum n parallel direct accesses and one indirect access 
static tree_nodeConstRef GetBaseVariable(const tree_nodeConstRef &mem)
Retrun the base variable of a memory access. 
CustomOrderedSet< unsigned int > func_list
list of functions to be analyzed 
struct definition of the type node structures. 
Class specification of the tree_reindex support class. 
const CustomUnorderedSet< std::tuple< HLSFlowStep_Type, HLSFlowStepSpecializationConstRef, HLSFlowStep_Relationship > > ComputeHLSRelationships(const DesignFlowStep::RelationshipType relationship_type) const override
Compute the relationship of this step. 
T * GetPointer(const refcount< U > &t)
Template function used to hide dynamic_cast The template parameter T represents a type of an object h...
std::string GetKindText() const override
Return the string representation of this. 
DesignFlowStep_Status Exec() override
Execute the step. 
unsigned int memory_version
The version of memory representation on which this step was applied. 
all local variables, static variables and strings are allocated on BRAMs 
for each memory at maximum n parallel direct accesses and n parallel indirect accesses ...
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. 
static bool IsStructType(const tree_nodeConstRef &type)
Return true if treenode is a record. 
for each memory at maximum one direct access and one indirect access 
Classes specification of the tree_node data structures not present in the gcc. 
this class is used to manage the command-line or XML options. 
std::string GetSignature() const override
Return the contribution to the signature of a step given by the specialization. 
Generic device description. 
int debug_level
The debug level. 
The information about how memory allocation has to be specialized. 
#define OUTPUT_LEVEL_VERBOSE
verbose debugging print is performed. 
refcount< const HLSFlowStepSpecialization > HLSFlowStepSpecializationConstRef
const refcount definition of the class 
all objects that need to be stored in memory are allocated on BRAMs 
#define DEBUG_LEVEL_VERBOSE
verbose debugging print is performed. 
const MemoryAllocation_Policy memory_allocation_policy
memory allocation policy 
static tree_nodeConstRef GetFunctionReturnType(const tree_nodeConstRef &function, bool void_as_null=true)
Return the return type of a function. 
Datastructure to represent memory information in high-level synthesis. 
MemoryAllocation_Policy
The allocation memory polycy. 
void add_parameter(unsigned int funID_scope, unsigned int var, const std::string &var_name, bool is_last)
Allocates a parameter to the set of the interface registers. 
Class specification of the manager of the tree structures extracted from the raw file. 
HLS specialization of generic_device. 
A brief description of the C++ Header File. 
void setup_memory_allocation()
Prepares the data structures for the memory allocation. 
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...