81 static inline unsigned long long int align(
unsigned long long int address,
unsigned long long int alignment)
83 return ((address / alignment) + (address % alignment != 0)) * alignment;
90 bool _null_pointer_check,
bool initial_internal_address_p,
91 unsigned long long int initial_internal_address,
const unsigned int& _bus_addr_bitsize)
93 maximum_private_memory_size(0),
94 total_amount_of_private_memory(0),
95 total_amount_of_parameter_memory(0),
96 off_base_address(_off_base_address),
97 next_off_base_address(_off_base_address),
102 intern_shared_data(
false),
103 use_unknown_addresses(
false),
104 unaligned_accesses(
false),
105 all_pointers_resolved(
false),
106 implicit_memcpy(
false),
107 parameter_alignment(16),
108 null_pointer_check(_null_pointer_check),
110 bus_addr_bitsize(_bus_addr_bitsize),
111 enable_hls_bit_value(
false)
113 const auto max_bus_size = 2
U * max_bram;
119 else if(initial_internal_address_p && initial_internal_address != 0)
133 unsigned long long _off_base_address,
unsigned int max_bram,
bool _null_pointer_check,
134 bool initial_internal_address_p,
unsigned int initial_internal_address,
135 const unsigned int& _address_bitsize)
137 if(_parameters->getOption<
bool>(OPT_parse_pragma) && _parameters->isOption(OPT_context_switch))
139 return memoryRef(
new memory_cs(_TreeM, _off_base_address, max_bram, _null_pointer_check,
140 initial_internal_address_p, initial_internal_address, _address_bitsize));
144 return memoryRef(
new memory(_TreeM, _off_base_address, max_bram, _null_pointer_check, initial_internal_address_p,
145 initial_internal_address, _address_bitsize));
155 unsigned long long int alignment)
const 158 unsigned long long size = 0;
172 return align(address + size, alignment);
238 THROW_WARNING(
"The variable " +
STR(var) +
" has been already allocated out of the module");
242 THROW_WARNING(
"The variable " +
STR(var) +
" has been already set as a parameter");
245 "variable already allocated inside this module");
247 internal[funID_scope][var] = m_sym;
266 const auto address = m_sym->get_address();
275 unsigned int n_non_private = 0;
276 for(
const auto& iv_pair :
in_vars)
283 return n_non_private;
297 THROW_WARNING(
"The variable " +
STR(var) +
" has been already internally allocated");
301 THROW_WARNING(
"The variable " +
STR(var) +
" has been already set as a parameter");
340 THROW_WARNING(
"The variable " +
STR(var) +
" has been already allocated out of the module");
344 THROW_WARNING(
"The variable " +
STR(var) +
" has been already internally allocated");
348 const auto address = m_sym->get_address();
361 return internal.find(funID_scope) !=
internal.end() &&
362 internal.find(funID_scope)->second.find(var) !=
internal.find(funID_scope)->second.end();
389 parameter.find(funID_scope)->second.find(var) !=
parameter.find(funID_scope)->second.end();
401 return in_vars.at(var)->get_address();
407 return external.at(var)->get_address();
414 return parameter.at(funId).at(var)->get_address();
419 const auto internal_it =
internal.find(funID_scope);
420 if(internal_it ==
internal.end())
422 return std::map<unsigned int, memory_symbolRef>();
424 return internal_it->second;
431 return std::map<unsigned int, memory_symbolRef>();
458 return itr->second.find(var) != itr->second.end();
487 unsigned long long int minAddress = UINT_MAX;
488 const auto internal_it =
internal.find(funId);
489 if(internal_it !=
internal.end())
491 for(
const auto& internalVar : internal_it->second)
493 const auto& var = internalVar.first;
496 minAddress =
std::min(minAddress, internalVar.second->get_address());
500 if(minAddress == UINT_MAX)
502 const auto& paramsVar =
parameter.at(funId);
503 for(
const auto& itr : paramsVar)
505 const auto& var = itr.first;
508 minAddress =
std::min(minAddress, itr.second->get_address());
517 unsigned long long int maxAddress = 0;
518 const auto internal_it =
internal.find(funId);
519 if(internal_it !=
internal.end())
521 for(
const auto& internalVar : internal_it->second)
523 const auto& var = internalVar.first;
526 maxAddress =
std::max(maxAddress, internalVar.second->get_address() +
531 if(AppMgr->hasToBeInterfaced(funId))
534 for(
const auto& itr : paramsVar)
536 const auto& var = itr.first;
541 const auto calledSet = AppMgr->CGetCallGraphManager()->get_called_by(funId);
542 for(
const auto Itr : calledSet)
544 if(!AppMgr->hasToBeInterfaced(Itr))
647 !(_internal_base_address_alignment & (_internal_base_address_alignment - 1)),
648 "alignment must be a power of two");
656 std::map<std::string, std::string> res_parameters;
660 const auto current_src_parameters =
662 for(
const auto& current_src_parameter : current_src_parameters)
664 std::vector<std::string> current_parameter =
665 string_to_container<std::vector<std::string>>(current_src_parameter,
"=");
666 res_parameters[current_parameter[0]] = current_parameter[1];
670 const auto srcModule = GetPointer<const module>(src);
674 for(
unsigned int i = 0; i < srcModule->get_internal_objects_size(); ++i)
676 const auto subModule = srcModule->get_internal_object(i);
679 const auto current_src_parameters =
680 string_to_container<std::vector<std::string>>(subModule->GetParameter(
MEMORY_PARAMETER),
";");
681 for(
const auto& current_src_parameter : current_src_parameters)
683 const auto current_parameter = string_to_container<std::vector<std::string>>(current_src_parameter,
"=");
684 res_parameters[current_parameter[0]] = current_parameter[1];
694 const auto current_tgt_parameters =
696 for(
const auto& current_tgt_parameter : current_tgt_parameters)
698 const auto current_parameter = string_to_container<std::vector<std::string>>(current_tgt_parameter,
"=");
699 if(res_parameters.find(current_parameter[0]) != res_parameters.end() &&
700 res_parameters[current_parameter[0]] != current_parameter[1])
702 THROW_ERROR(
"The parameter \"" + current_parameter[0] +
703 "\" has been set with (at least) two different values");
705 res_parameters[current_parameter[0]] = current_parameter[1];
708 if(res_parameters.size() == 0)
713 std::string memory_parameters;
714 for(
const auto& res_parameter : res_parameters)
716 if(memory_parameters.size())
718 memory_parameters +=
";";
720 memory_parameters += res_parameter.first +
"=" + res_parameter.second;
732 const auto current_parameters = string_to_container<std::vector<std::string>>(memory_parameters,
";");
733 for(
const auto& l : current_parameters)
735 const auto current_parameter = string_to_container<std::vector<std::string>>(l,
"=");
736 THROW_ASSERT(current_parameter.size() == 2,
"expected two elements");
737 if(current_parameter[0] == name)
739 if(value == current_parameter[1])
743 THROW_ERROR(
"The parameter \"" + name +
"\" has been set with (at least) two different values: " + value +
744 " != " + current_parameter[1]);
747 memory_parameters += name +
"=" +
value;
758 const auto IntNode = Enode->add_child_element(
"internal_memory");
759 for(
auto iIt =
internal.begin(); iIt !=
internal.end(); ++iIt)
761 const auto ScopeNode = IntNode->add_child_element(
"scope");
762 const auto id =
"@" +
STR(iIt->first);
766 for(
auto vIt = iIt->second.begin(); vIt != iIt->second.end(); ++vIt)
768 const auto VarNode = ScopeNode->add_child_element(
"variable");
769 const auto variable =
"@" +
STR(vIt->second->get_variable());
771 const auto address = vIt->second->get_address();
773 const auto var_symbol_name = vIt->second->get_symbol_name();
775 const auto var_name = vIt->second->get_name();
780 const auto params0 =
parameter.at(iIt->first);
781 for(
auto vIt = params0.begin(); vIt != params0.end(); ++vIt)
783 const auto VarNode = ScopeNode->add_child_element(
"parameter");
784 const auto variable =
"@" +
STR(vIt->second->get_variable());
786 const auto address = vIt->second->get_address();
788 const auto var_symbol_name = vIt->second->get_symbol_name();
790 const auto var_name = vIt->second->get_symbol_name();
797 for(
auto iIt =
internal.begin(); iIt !=
internal.end(); ++iIt)
799 if(
internal.find(iIt->first) !=
internal.end())
803 const auto ScopeNode = IntNode->add_child_element(
"scope");
804 const auto id =
"@" +
STR(iIt->first);
808 const auto params0 =
parameter.find(iIt->first)->second;
809 for(
auto vIt = params0.begin(); vIt != params0.end(); ++vIt)
811 const auto VarNode = ScopeNode->add_child_element(
"parameter");
812 const auto variable =
"@" +
STR(vIt->second->get_variable());
814 unsigned long long int address = vIt->second->get_address();
816 const auto var_symbol_name = vIt->second->get_symbol_name();
818 const auto var_name = vIt->second->get_symbol_name();
826 const auto ExtNode = Enode->add_child_element(
"external_memory");
829 const auto VarNode = ExtNode->add_child_element(
"variable");
830 const auto variable =
"@" +
STR(eIt->second->get_variable());
832 const auto address = eIt->second->get_address();
834 const auto var_name = eIt->second->get_symbol_name();
846 auto neEQMapSymbolRef = [](
const std::map<unsigned int, memory_symbolRef>& ref1,
847 const std::map<unsigned int, memory_symbolRef>& ref2) ->
bool {
848 if(ref1.size() != ref2.size())
854 std::map<unsigned int, memory_symbolRef>::const_iterator i_it, j_it;
855 for(i_it = ref1.begin(), j_it = ref2.begin(); i_it != ref1.end(); ++i_it, ++j_it)
857 if(i_it->first != j_it->first)
861 if((i_it->second)->notEQ(*(j_it->second)))
869 auto neEQ2MapSymbolRef =
870 [&neEQMapSymbolRef](
const std::map<unsigned int, std::map<unsigned int, memory_symbolRef>>& ref1,
871 const std::map<unsigned int, std::map<unsigned int, memory_symbolRef>>& ref2) ->
bool {
872 if(ref1.size() != ref2.size())
878 std::map<unsigned int, std::map<unsigned int, memory_symbolRef>>::const_iterator i_it, j_it;
879 for(i_it = ref1.begin(), j_it = ref2.begin(); i_it != ref1.end(); ++i_it, ++j_it)
881 if(i_it->first != j_it->first)
885 if(neEQMapSymbolRef(i_it->second, j_it->second))
897 if(neEQ2MapSymbolRef(
internal, ref->
internal))
1067 for(
const auto& int_obj :
internal)
1069 for(
const auto& var_obj : int_obj.second)
1071 const auto ObjNode = Enode->add_child_element(
"object");
1074 const auto name = var_obj.second->get_name();
1079 for(
const auto& ext_obj :
external)
1081 const auto ObjNode = Enode->add_child_element(
"object");
1082 const auto name = ext_obj.second->get_name();
1097 catch(
const char* msg)
1099 std::cerr << msg << std::endl;
1101 catch(
const std::string& msg)
1103 std::cerr << msg << std::endl;
1105 catch(
const std::exception& ex)
1107 std::cout <<
"Exception caught: " << ex.what() << std::endl;
1111 std::cerr <<
"unknown exception" << std::endl;
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...
unsigned long long int off_base_address
it represents the base address of the external memory
std::map< unsigned int, std::map< unsigned int, memory_symbolRef > > internal
set of variables allocated internally to the cores, classified by function id
unsigned long long int next_base_address
it represents the next address that is available for internal allocation
void reserve_space(unsigned long long space)
Explicitly allocate a certain space in the external memory.
void xwrite(xml_element *node)
Writes the current memory allocation into an XML description.
static std::string name_function(const tree_managerConstRef &tm, const unsigned int index)
Return the name of the function.
unsigned int count_non_private_internal_symbols() const
unsigned long long int get_next_internal_base_address() const
Returns next free address of memory allocated internally but not private.
bool null_pointer_check
when false object could be allocated starting from address 0
std::map< unsigned int, memory_symbolRef > external
set of variables allocated outside the top module
std::map< unsigned int, memory_symbolRef > get_function_parameters(unsigned int funID_scope) const
Return parameters allocated in register of the interface.
std::map< unsigned int, memory_symbolRef > callSites
set of call sites for __builtin_wait_call
bool is_parameter(unsigned int funID_scope, unsigned int var) const
Test if a variable is into the set of interface registers.
unsigned long long int get_parameter_base_address(unsigned int funId, unsigned int var) const
Get the current base address of the given variable.
const tree_nodeRef CGetTreeReindex(const unsigned int i) const
Return a tree_reindex wrapping the i-th tree_node.
static unsigned int get_var_alignment(const tree_managerConstRef &TM, unsigned int var)
Return the var alignment.
unsigned long long external_base_address_alignment
external address alignment
Definition of the class representing a generic C application.
const structural_objectRef get_circ() const
Get a reference to circ field.
void add_parm_decl_stored(unsigned int var)
add a parm_decl to the set of parm_decl that has to be initialized
Datastructure to represent a memory symbol in HLS.
mathematical utility function not provided by standard libraries
static unsigned long long int align(unsigned long long int address, unsigned long long int alignment)
STL includes.
bool has_sds_var(unsigned int var) const
return true if the var has been classified in term of same data size relation
bool implicit_memcpy
when true an implicit memcpy is called
std::map< unsigned int, unsigned long long int > rangesize
for each var store the address space rangesize associated with it
bool notEQ(refcount< memory > ref) const
return true in case the current memory object and the passed one are different
exceptions managed by PandA
CustomOrderedSet< unsigned int > private_memories
store the objects that does not need to be attached to the bus
bool is_read_only_variable(unsigned var) const
return true when the variable is only read
void set_sds_var(unsigned int var, bool value)
set if a variable is always accessed with the same data size or not
bool has_external_base_address(unsigned int var) const
Check if there is a base address for the given variable.
unsigned long long get_allocated_space() const
Returns the amount of memory allocated internally to the module.
const tree_managerConstRef TreeM
data-structure containing tree information
std::map< unsigned int, CustomOrderedSet< unsigned int > > source_values
ssa_names assigned to a given memory variable
std::map< unsigned int, memory_symbolRef > get_function_vars(unsigned int funID_scope) const
Return the variables allocated within the space of a given function.
refcount< memory > memoryRef
refcount definition of the class
CustomOrderedSet< unsigned int > parm_decl_copied
parm_decl that has to be copied from the caller
virtual ~memory()
Destructor.
void add_internal_variable(unsigned int funID_scope, unsigned int var, const std::string &var_name)
Allocates a variable to the set of variables allocated internally to the given function.
const CustomOrderedSet< unsigned int > & get_proxied_internal_variables(unsigned int funID_scope) const
return the proxied internal variables associated with the function
unsigned long long int get_base_address(unsigned int var, unsigned int funId) const
Get the current base address of the given variable.
unsigned long long get_external_base_address(unsigned int var) const
Get the current base address of the given variable.
CustomOrderedSet< unsigned int > actual_parm_loaded
actual parameter that has to be loaded from a stored value
bool is_external_variable(unsigned int var) const
Test if a variable is into the set of variables out of the top function.
bool is_a_proxied_variable(unsigned int var) const
return true if the variable is a proxied variable
const unsigned int & bus_addr_bitsize
std::string GetParameter(std::string name) const
Get the value associated to parameter if it has been associated; if it has not specified returns the ...
const tree_nodeConstRef CGetTreeNode(const unsigned int i) const
std::map< unsigned int, memory_symbolRef > in_vars
set of all the internal variables
#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.
static void add_memory_parameter(const structural_managerRef SM, const std::string &name, const std::string &value)
Adds the given memory parameter to the corresponding object.
unsigned long long get_callSite_base_address(unsigned int var) const
Get the current base address of the given call site.
CustomOrderedSet< unsigned int > parm_decl_stored
parm_decl storage has to be initialized from the formal parameter
virtual void AddParameter(const std::string &name, const std::string &default_value)
Add a parameter.
unsigned long long get_allocated_parameters_memory() const
Return the total amount of memory allocated for the memory mapped parameters.
unsigned long long get_first_address(unsigned int funId) const
Get the first address of the function address space.
bool all_pointers_resolved
is true when all pointers are resolved statically
unsigned long long get_rangesize(unsigned int var) const
return the address space rangesize associated with the given var
void add_read_only_variable(unsigned var)
add a read only variable
static unsigned long long Size(const tree_nodeConstRef &tn)
Return the size of a tree object.
void add_private_memory(unsigned int var)
add a var that safely cannot be attached to the bus
memory_symbolRef get_symbol(unsigned int var, unsigned int funId) const
Return the symbol associated with the given variable.
void xwrite2(xml_element *node)
Writes the current memory allocation into an XML description.
static memoryRef create_memory(const ParameterConstRef _parameters, const tree_managerConstRef _TreeM, unsigned long long int _off_base_address, unsigned int max_bram, bool _null_pointer_check, bool initial_internal_address_p, unsigned int initial_internal_address, const unsigned int &_address_bitsize)
unsigned long long int total_amount_of_parameter_memory
total amount of parameter memory
const unsigned long long parameter_alignment
parameter alignment
std::map< unsigned int, size_t > maximum_loads
define for each variable the number of loads whenever it is possible
refcount< memory_symbol > memory_symbolRef
refcount definition of the class
unsigned long long internal_base_address_alignment
internal address alignment
std::map< unsigned int, memory_symbolRef > params
set of all the internal parameters
void write_to_file_formatted(const std::filesystem::path &filename)
Write the document to a file.
void add_parameter_symbol(unsigned int funID_scope, unsigned int var, const memory_symbolRef m_sym)
Allocates a parameter to the set of the interface registers.
xml_element * create_root_node(const std::string &_name)
Creates the root node.
unsigned int maxbram_bitsize
maximum bram bitsize
unsigned long long int get_internal_base_address(unsigned int var) const
Get the current base address of the given variable.
bool has_parameter_base_address(unsigned int var, unsigned int funId) const
Check if there is a base address for the given parameter.
bool is_parm_decl_stored(unsigned int var) const
return true in case the parm_decl parameter has to be initialized from the formal value ...
bool is_parm_decl_copied(unsigned int var) const
return true in case the parm_decl parameter has to be copied from the caller
std::map< unsigned int, CustomOrderedSet< unsigned int > > internal_variable_proxy
set of variable proxies accessed by a function
#define GET_CONST_NODE(t)
void SetParameter(const std::string &name, const std::string &value)
Set a parameter value.
unsigned long long bus_data_bitsize
bus data bitsize
Classes specification of the tree_node data structures.
bool is_private_memory(unsigned int var) const
Return true in case the variable is private.
This file collects some utility functions and macros.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
T compute_n_bytes(T bitsize)
This file collects some utility functions.
void add_external_variable(unsigned int var, const std::string &var_name)
Allocates a variable to the set of variables allocated outside to outermost function.
std::map< unsigned int, size_t > maximum_references
define for each variable the number of references whenever it is possible
unsigned long long compute_next_base_address(unsigned long long address, unsigned int var, unsigned long long int alignment) const
Compute the new base address based on the size of the given variable and align the memory as needed...
unsigned long long bus_size_bitsize
bus size bitsize
memory(const tree_managerConstRef TreeM, unsigned long long int off_base_address, unsigned int max_bram, bool null_pointer_check, bool initial_internal_address_p, unsigned long long initial_internal_address, const unsigned int &_bus_addr_bitsize)
Constructor.
This class describes all classes used to represent a structural object.
void add_source_value(unsigned int var, unsigned int value)
add a value to the set of values written in a given memory variable
#define WRITE_XNVM(variable, value, node)
WRITE XML Name Value Macro.
void add_parm_decl_copied(unsigned int var)
add a parm_decl to the set of parm_decl written
Class specification of the tree_reindex support class.
bool has_base_address(unsigned int var) const
Check if there is a base address for the given variable.
bool is_sds_var(unsigned int var) const
check if the variable is always accessed with the same data size
CustomOrderedSet< unsigned int > read_only_vars
#define WRITE_XVM(variable, node)
WRITE XML Value Macro. Insert a value in an XML tree.
unsigned long long int get_max_address() const
return the maximum address allocated
bool ExistsParameter(std::string name) const
Check if a parameter has been specified.
void add_actual_parm_loaded(unsigned int var)
add an actual parameter to the set of parameter that has to be initialized from a stored value ...
static tree_nodeConstRef CGetType(const tree_nodeConstRef &node)
Return the treenode of the type of node.
unsigned long long get_memory_address() const
Return the first memory address not yet allocated.
bool use_unknown_addresses
Spec accesses data having an address unknown at compile time.
CustomOrderedSet< unsigned int > need_bus
define for each variable the number of loads whenever it is possible
unsigned long long int maximum_private_memory_size
is the maximum amount of private memory allocated
bool has_internal_base_address(unsigned int var) const
Check if there is a base address for the given variable.
void add_external_symbol(unsigned int var, const memory_symbolRef m_sym)
Allocates a variable to the set of variables allocated outside to outermost function.
this class is used to manage the command-line or XML options.
CustomOrderedSet< unsigned int > proxied_variables
is the set of proxied variables
unsigned long long int get_allocated_internal_memory() const
Returns the amount of memory allocated internally but not private.
unsigned long long int total_amount_of_private_memory
total amount of internal memory allocated
Some macro used to interface with the XML library.
unsigned long long get_last_address(unsigned int funId, const application_managerRef AppM) const
Get the last address of the function address space.
Class implementation of the structural_manager.
bool packed_vars
true when packed vars are used
unsigned long long int internal_base_address_start
is the start internal address
bool is_actual_parm_loaded(unsigned int var) const
return true in case the actual parameter has to be initialized from a stored value ...
bool is_internal_variable(unsigned int funID_scope, unsigned int var) const
Test if a variable is allocated into the specified function.
unsigned long long bram_bitsize
bram bitsize
bool intern_shared_data
define if the Spec has data that can be externally accessed
Base class for all register into datapath.
void reserve_internal_space(unsigned long long int space)
Explicitly allocate a certain space in the internal memory.
bool has_callSite_base_address(unsigned int var) const
Check if there is a base address for the given call site.
bool has_proxied_internal_variables(unsigned int funID_scope) const
check if the function has proxied variables
std::map< unsigned int, memory_symbolRef > get_ext_memory_variables() const
Return variables allocated out of the top module.
void set_internal_base_address_alignment(unsigned long long _internal_base_address_alignment)
set the internal base address alignment
Datastructure to represent memory information in high-level synthesis.
xml_element * add_child_element(const std::string &name)
Add a child element to this node.
bool unaligned_accesses
true when LOADs or STOREs perform unaligned accesses
std::map< unsigned int, std::map< unsigned int, memory_symbolRef > > parameter
set of variables allocated in registers of the interface
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.
void add_internal_symbol(unsigned int funID_scope, unsigned int var, const memory_symbolRef m_sym)
Allocates a variable to the set of variables allocated internally to the given function.
unsigned long long int next_off_base_address
it represents the next address that is available to allocate a variable out of the top module ...
std::map< unsigned int, unsigned int > same_data_size_accesses
store if a given variable is accessed always with the same data_size or not
void add_internal_variable_proxy(unsigned int funID_scope, unsigned int var)
allocate a proxy for the variable for the specified function
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...