83 :
fu_binding(_HLS_mgr, _function_id, _parameters)
92 const auto& parallelized_functions = GetPointer<const OmpFunctions>(HLSMgr->Rfuns)->parallelized_functions;
93 const auto& omp_for_wrappers = GetPointer<const OmpFunctions>(HLSMgr->Rfuns)->omp_for_wrappers;
94 const auto TM = HLS->
HLS_D->get_technology_manager();
95 const auto memory_banks_number =
parameters->getOption<
unsigned int>(OPT_memory_banks_number);
98 if(parallelized_functions.find(HLS->
functionId) != parallelized_functions.end())
100 std::list<structural_objectRef> memory_enableds;
101 bool load_store_operation = [&]() ->
bool {
104 std::string channels_type =
114 for(
unsigned int internal_object_id = 0;
115 internal_object_id < GetPointer<const module>(circuit)->get_internal_objects_size(); internal_object_id++)
117 const auto internal_object = GetPointer<const module>(circuit)->get_internal_object(internal_object_id);
118 const auto memory_enabled = internal_object->find_member(
"memory_enabled",
port_o_K, internal_object);
121 memory_enableds.push_back(memory_enabled);
124 if(load_store_operation)
127 const auto allow_mem_access = SM->add_module_from_technology_library(
128 "allow_memory_access",
"ALLOW_MEM_ACCESS_FU",
LIBRARY_PC, circuit, TM);
130 SM->add_connection(clock_port, clock);
132 SM->add_connection(reset_port,
reset);
133 const auto amaf_access_allowed = allow_mem_access->find_member(
"access_allowed",
port_o_K, allow_mem_access);
134 GetPointer<port_o>(amaf_access_allowed)->add_n_ports(memory_banks_number, amaf_access_allowed);
139 const auto memory_enabled = allow_mem_access->find_member(
"memory_enabled",
port_o_K, allow_mem_access);
140 GetPointer<port_o>(memory_enabled)->add_n_ports(memory_banks_number, memory_enabled);
141 memory_enableds.push_back(memory_enabled);
143 for(
unsigned int internal_object_id = 0;
144 internal_object_id < GetPointer<const module>(circuit)->get_internal_objects_size(); internal_object_id++)
146 const auto internal_object = GetPointer<const module>(circuit)->get_internal_object(internal_object_id);
147 if(internal_object->get_typeRef()->id_type ==
"MEMORY_CTRL_P1N")
157 for(boost::tie(operation, operation_end) = boost::vertices(*
op_graph); operation != operation_end; operation++)
161 atomics.insert(
get(*operation)->get_structural_obj());
164 for(
const auto& atomic : atomics)
167 "-->Adding ALLOW_MEM_ACCESS_FU for " + atomic->get_path());
168 const auto allow_mem_access = SM->add_module_from_technology_library(
169 "allow_memory_access_" + atomic->get_id(),
"ALLOW_MEM_ACCESS_FU",
LIBRARY_PC, circuit, TM);
173 SM->add_connection(clock_port, clock);
175 SM->add_connection(reset_port,
reset);
178 const auto amaf_access_allowed = allow_mem_access->find_member(
"access_allowed",
port_o_K, allow_mem_access);
179 GetPointer<port_o>(amaf_access_allowed)->add_n_ports(memory_banks_number, amaf_access_allowed);
185 const auto memory_enabled = allow_mem_access->find_member(
"memory_enabled",
port_o_K, allow_mem_access);
186 GetPointer<port_o>(memory_enabled)->add_n_ports(memory_banks_number, memory_enabled);
187 memory_enableds.push_back(memory_enabled);
193 "<--Added ALLOW_MEM_ACCESS_FU for " + atomic->get_path());
196 if(memory_enableds.size())
199 "-->" +
STR(memory_enableds.size()) +
" memory enableds to be put in and");
200 size_t and_counter = 0;
201 size_t and_counter_sig = 0;
202 while(memory_enableds.size() > 1)
204 const auto first = memory_enableds.front();
205 memory_enableds.pop_front();
206 const auto first_signal = SM->add_sign_vector(
"memory_enabled_and_sign_" +
STR(and_counter_sig),
207 memory_banks_number, circuit, first->
get_typeRef());
208 SM->add_connection(first, first_signal);
211 const auto second = memory_enableds.front();
212 memory_enableds.pop_front();
213 const auto second_signal = SM->add_sign_vector(
"memory_enabled_and_sign_" +
STR(and_counter_sig),
214 memory_banks_number, circuit, second->
get_typeRef());
215 SM->add_connection(second, second_signal);
218 const auto and_port = SM->add_module_from_technology_library(
"memory_enabled_and_" +
STR(and_counter),
219 "MEMORY_ENABLED_AND",
LIBRARY_PC, circuit, TM);
220 const auto out_memory_enabled = and_port->find_member(
"memory_enabled",
port_o_K, and_port);
221 GetPointer<port_o>(out_memory_enabled)->add_n_ports(memory_banks_number, out_memory_enabled);
224 const auto first_port = and_port->find_member(
"in1",
port_o_K, and_port);
225 GetPointer<port_o>(first_port)->add_n_ports(memory_banks_number, first_port);
226 SM->add_connection(first_signal, first_port);
228 const auto second_port = and_port->find_member(
"in2",
port_o_K, and_port);
229 GetPointer<port_o>(second_port)->add_n_ports(memory_banks_number, second_port);
230 SM->add_connection(second_signal, second_port);
232 memory_enableds.push_back(out_memory_enabled);
234 GetPointer<port_o>(memory_enableds.front())->set_is_memory(
true);
235 GetPointer<port_o>(memory_enableds.front())->set_is_global(
true);
236 GetPointer<port_o>(memory_enableds.front())->set_is_extern(
true);
245 else if(omp_for_wrappers.find(HLS->
functionId) != omp_for_wrappers.end())
248 std::list<structural_objectRef> slaves;
249 std::list<structural_objectRef> memory_enableds;
251 for(
unsigned int internal_object_id = 0;
252 internal_object_id < GetPointer<const module>(circuit)->get_internal_objects_size(); internal_object_id++)
254 const auto internal_object = GetPointer<const module>(circuit)->get_internal_object(internal_object_id);
255 const auto access_request = internal_object->find_member(
"access_request",
port_o_K, internal_object);
258 slaves.push_back(internal_object);
259 memory_enableds.push_back(internal_object->find_member(
"memory_enabled",
port_o_K, internal_object));
262 size_t and_counter = 0;
263 size_t and_counter_sig = 0;
264 while(memory_enableds.size() > 1)
266 const auto first = memory_enableds.front();
267 memory_enableds.pop_front();
268 const auto first_signal = SM->add_sign_vector(
"memory_enabled_and_sign_" +
STR(and_counter_sig),
269 memory_banks_number, circuit, first->
get_typeRef());
270 SM->add_connection(first, first_signal);
273 const auto second = memory_enableds.front();
274 memory_enableds.pop_front();
275 const auto second_signal = SM->add_sign_vector(
"memory_enabled_and_sign_" +
STR(and_counter_sig),
276 memory_banks_number, circuit, second->
get_typeRef());
277 SM->add_connection(second, second_signal);
280 const auto and_port = SM->add_module_from_technology_library(
"memory_enabled_and_" +
STR(and_counter),
281 "MEMORY_ENABLED_AND",
LIBRARY_PC, circuit, TM);
282 const auto out_memory_enabled = and_port->find_member(
"memory_enabled",
port_o_K, and_port);
283 GetPointer<port_o>(out_memory_enabled)->add_n_ports(memory_banks_number, out_memory_enabled);
286 const auto first_port = and_port->find_member(
"in1",
port_o_K, and_port);
287 GetPointer<port_o>(first_port)->add_n_ports(memory_banks_number, first_port);
288 SM->add_connection(first_signal, first_port);
290 const auto second_port = and_port->find_member(
"in2",
port_o_K, and_port);
291 GetPointer<port_o>(second_port)->add_n_ports(memory_banks_number, second_port);
292 SM->add_connection(second_signal, second_port);
294 memory_enableds.push_back(out_memory_enabled);
296 for(
unsigned int memory_bank_index = 0; memory_bank_index < memory_banks_number; memory_bank_index++)
299 const auto pt_rr_fu = SM->add_module_from_technology_library(
"pt_rr_fu_" +
STR(memory_bank_index),
"PT_FU_MEM",
305 const auto rops_so = pt_rr_fu->find_member(
"rops",
port_o_K, pt_rr_fu);
307 const auto rops = GetPointer<port_o>(rops_so);
308 rops->add_n_ports(static_cast<unsigned int>(slaves.size()), rops_so);
309 const auto ops_so = pt_rr_fu->find_member(
"ops",
port_o_K, pt_rr_fu);
311 const auto ops = GetPointer<port_o>(ops_so);
312 ops->add_n_ports(static_cast<unsigned int>(slaves.size()), ops_so);
313 const auto enable_so = pt_rr_fu->find_member(
"ENABLE",
port_o_K, pt_rr_fu);
316 unsigned int internal_object_id = 0;
317 for(
const auto& slave : slaves)
321 const auto int_access_request =
322 GetPointer<port_o>(slave->find_member(
"access_request",
port_o_K, slave))->get_port(memory_bank_index);
323 const auto access_request_sign =
324 SM->add_sign(
"access_request_" +
STR(internal_object_id) +
"_" +
STR(memory_bank_index), circuit,
326 const auto rop = rops->get_port(internal_object_id);
327 SM->add_connection(int_access_request, access_request_sign);
328 SM->add_connection(access_request_sign, rop);
332 const auto int_access_allowed =
333 GetPointer<port_o>(slave->find_member(
"access_allowed",
port_o_K, slave))->get_port(memory_bank_index);
334 const auto access_allowed_sign =
335 SM->add_sign(
"access_allowed_" +
STR(internal_object_id) +
"_" +
STR(memory_bank_index), circuit,
337 const auto op = ops->get_port(internal_object_id);
338 SM->add_connection(int_access_allowed, access_allowed_sign);
339 SM->add_connection(access_allowed_sign, op);
342 internal_object_id++;
345 const auto int_enable = GetPointer<port_o>(memory_enableds.front())->get_port(memory_bank_index);
346 const auto enable_sign = SM->add_sign(
"enable_" +
STR(memory_bank_index), circuit, int_enable->
get_typeRef());
347 SM->add_connection(int_enable, enable_sign);
348 SM->add_connection(enable_sign, enable_so);
356 for(
unsigned int internal_object_id = 0;
357 internal_object_id < GetPointer<const module>(circuit)->get_internal_objects_size(); internal_object_id++)
359 const auto internal_object = GetPointer<const module>(circuit)->get_internal_object(internal_object_id);
360 if(internal_object->get_typeRef()->id_type ==
"MEMORY_CTRL_P1N")
362 const auto access_allowed = internal_object->find_member(
"access_allowed",
port_o_K, internal_object);
363 for(
unsigned int memory_bank_index = 0; memory_bank_index < memory_banks_number; memory_bank_index++)
365 const auto constant = SM->add_constant(
"access_allowed_enabled_" +
STR(memory_bank_index), circuit,
367 SM->add_connection(constant, GetPointer<port_o>(access_allowed)->get_port(memory_bank_index));
372 const auto access_allowed = internal_object->find_member(
"access_allowed",
port_o_K, internal_object);
375 for(
unsigned int memory_bank_index = 0; memory_bank_index < memory_banks_number; memory_bank_index++)
377 const auto constant = SM->add_constant(
"access_allowed_enabled_" + internal_object->get_id() +
"_" +
378 STR(memory_bank_index),
380 SM->add_connection(constant, GetPointer<port_o>(access_allowed)->get_port(memory_bank_index));
392 const auto TM = HLSMgr->get_tree_manager();
396 GetPointerS<port_o>(memory_enabled)->set_is_memory(
false);
397 GetPointerS<port_o>(memory_enabled)->set_is_global(
false);
398 GetPointerS<port_o>(memory_enabled)->set_is_extern(
false);
400 const auto& parallelized_functions = GetPointerS<const OmpFunctions>(HLSMgr->Rfuns)->parallelized_functions;
404 const auto fd = GetPointerS<const function_decl>(
GET_CONST_NODE(fu_node));
411 GetPointerS<port_o>(access_allowed)->set_is_memory(
false);
412 GetPointerS<port_o>(access_allowed)->set_is_global(
false);
413 GetPointerS<port_o>(access_allowed)->set_is_extern(
false);
417 if(parallelized_functions.find(HLS->
functionId) == parallelized_functions.end())
422 GetPointerS<port_o>(access_request)->set_is_memory(
false);
423 GetPointerS<port_o>(access_request)->set_is_global(
false);
424 GetPointerS<port_o>(access_request)->set_is_extern(
false);
430 GetPointerS<port_o>(access_allowed)->set_is_memory(
false);
431 GetPointerS<port_o>(access_allowed)->set_is_global(
false);
432 GetPointerS<port_o>(access_allowed)->set_is_extern(
false);
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
int debug_level
The debug level.
#define GET_TYPE(data, vertex_index)
Helper macro returning the type associated with a node.
File containing functions and utilities to support the printing of debug messagges.
structural_managerRef datapath
Store the datapath description.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
const HLS_deviceRef HLS_D
reference to the information representing the target for the synthesis
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 add_to_SM(const HLS_managerRef HLSMgr, const hlsRef HLS, structural_objectRef clock_port, structural_objectRef reset_port) override
Instance the functional unit inside the structural representation of the datapath.
bool manage_module_ports(const HLS_managerRef HLSMgr, const hlsRef HLS, const structural_managerRef SM, const structural_objectRef curr_gate, unsigned int num) override
virtual void add_to_SM(const HLS_managerRef HLSMgr, const hlsRef HLS, structural_objectRef clock_port, structural_objectRef reset_port)
Instance the functional unit inside the structural representation of the datapath.
virtual void manage_extern_global_port(const HLS_managerRef HLSMgr, const hlsRef HLS, const structural_managerRef SM, structural_objectRef port_in, unsigned int dir, structural_objectRef circuit, unsigned int num)
Class specification of the manager of the technology library data structures.
#define STR(s)
Macro which performs a lexical_cast to a string.
Base class for all resources into datapath.
#define CLOCK_PORT_NAME
standard name for ports
#define CHANNELS_TYPE_MEM_ACC_P1N
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
fu_bindingRef Rfu
Store the refcounted functional unit binding of the operations.
const OpGraphConstRef op_graph
The operation graph.
This class specifies the characteristic of a particular operation working on a given functional unit...
#define TYPE_ATOMIC
Constant identifying an atomic operation.
Class specification of the data structures used to manage technology information. ...
Data structure used to store the functional-unit binding of the vertices.
#define GET_CONST_NODE(t)
#define LIBRARY_PC
standard library for parallel controller
boost::graph_traits< graph >::vertex_iterator VertexIterator
vertex_iterator definition.
Classes specification of the tree_node data structures.
This file collects some utility functions and macros.
std::list< unsigned int > get_allocation_list() const
Returns the set of allocated unit.
AllocationInformationRef allocation_information
allocation manager. Used to retrieve the string name of the functional units.
std::string id_type
Original type id of the structural object.
virtual bool manage_module_ports(const HLS_managerRef HLSMgr, const hlsRef HLS, const structural_managerRef SM, const structural_objectRef curr_gate, unsigned int num)
const structural_type_descriptorRef & get_typeRef() const
Return the type descriptor of the structural_object.
Class specification of the tree_reindex support class.
ParallelMemoryFuBinding(const HLS_managerConstRef HLS_mgr, const unsigned int function_id, const ParameterConstRef parameters)
Constructor.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
this class is used to manage the command-line or XML options.
unsigned int functionId
this is the identifier of the function to be implemented
Class implementation of the structural_manager.
Class managing the functional-unit binding.
const ParameterConstRef parameters
The set of input parameters.
Datastructure to describe functions allocation in high-level synthesis.
Data structure definition for high-level synthesis flow.
Class specification of the manager of the tree structures extracted from the raw file.
HLS specialization of generic_device.
CustomSet< structural_objectRef > access_allowed_killeds
Internal objects for which access_allowed was killed.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...
CustomMap< structural_objectRef, structural_objectRef > component_to_allow_mem_access
For each component, the corresponding ALLOW_MEM_ACCESS_FU.