PandA-2024.02
module_interface.cpp
Go to the documentation of this file.
1 /*
2  *
3  * _/_/_/ _/_/ _/ _/ _/_/_/ _/_/
4  * _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/
5  * _/_/_/ _/_/_/_/ _/ _/_/ _/ _/ _/_/_/_/
6  * _/ _/ _/ _/ _/ _/ _/ _/ _/
7  * _/ _/ _/ _/ _/ _/_/_/ _/ _/
8  *
9  * ***********************************************
10  * PandA Project
11  * URL: http://panda.dei.polimi.it
12  * Politecnico di Milano - DEIB
13  * System Architectures Group
14  * ***********************************************
15  * Copyright (C) 2004-2024 Politecnico di Milano
16  *
17  * This file is part of the PandA framework.
18  *
19  * The PandA framework is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program. If not, see <http://www.gnu.org/licenses/>.
31  *
32  */
46 #include "module_interface.hpp"
47 
48 #include "Parameter.hpp"
49 #include "add_library.hpp"
50 #include "behavioral_helper.hpp"
51 #include "call_graph_manager.hpp"
52 #include "constant_strings.hpp"
53 #include "custom_set.hpp"
54 #include "dbgPrintHelper.hpp"
55 #include "function_behavior.hpp"
56 #include "hls.hpp"
57 #include "hls_manager.hpp"
58 #include "memory.hpp"
59 #include "memory_symbol.hpp"
60 #include "omp_functions.hpp"
61 #include "structural_manager.hpp"
62 #include "structural_objects.hpp"
63 
64 #include <tuple>
65 
67  unsigned int _funId, const DesignFlowManagerConstRef _design_flow_manager,
68  const HLSFlowStep_Type _hls_flow_step_type)
69  : HLSFunctionStep(_parameters, _HLSMgr, _funId, _design_flow_manager, _hls_flow_step_type)
70 {
71  THROW_ASSERT(_parameters, "Parameter null");
72 }
73 
75 
78 {
80  switch(relationship_type)
81  {
83  {
84  const auto cg_man = HLSMgr->CGetCallGraphManager();
85  if(HLSMgr->hasToBeInterfaced(funId) &&
86  (cg_man->ExistsAddressedFunction() || parameters->getOption<bool>(OPT_memory_mapped_top)))
87  {
88  ret.insert(std::make_tuple(HLSFlowStep_Type::TOP_ENTITY_MEMORY_MAPPED_CREATION,
90  }
91  else
92  {
93  ret.insert(std::make_tuple(parameters->getOption<HLSFlowStep_Type>(OPT_function_allocation_algorithm),
95  HLSFlowStep_Relationship::SAME_FUNCTION)); // add dependence to omp_function
96  if(HLSMgr->Rfuns)
97  {
98  bool found = false;
99  if(parameters->isOption(OPT_context_switch))
100  {
101  auto omp_functions = GetPointer<OmpFunctions>(HLSMgr->Rfuns);
102  THROW_ASSERT(omp_functions, "OMP_functions must not be null");
103  if(omp_functions->kernel_functions.find(funId) != omp_functions->kernel_functions.end())
104  {
105  found = true;
106  }
107  if(omp_functions->parallelized_functions.find(funId) != omp_functions->parallelized_functions.end())
108  {
109  found = true;
110  }
111  if(omp_functions->atomic_functions.find(funId) != omp_functions->atomic_functions.end())
112  {
113  found = true;
114  }
115  if(found) // use new top_entity
116  {
118  ret.insert(std::make_tuple(top_entity_type, HLSFlowStepSpecializationConstRef(),
120  }
121  }
122  if(!found) // use standard
123  {
125  ret.insert(std::make_tuple(top_entity_type, HLSFlowStepSpecializationConstRef(),
127  }
128  }
129  }
130  break;
131  }
133  {
134  break;
135  }
137  {
138  ret.insert(std::make_tuple(HLSFlowStep_Type::ADD_LIBRARY,
141  break;
142  }
143  default:
144  THROW_UNREACHABLE("");
145  }
146  return ret;
147 }
148 
150  const structural_objectRef sig2, const std::string& sig_name)
151 {
152  auto sig = SM->add_sign(sig_name, SM->get_circ(), sig1->get_typeRef());
153  SM->add_connection(sig, sig1);
154  SM->add_connection(sig, sig2);
155 }
156 
158  const structural_objectRef sig2, const std::string& sig_name)
159 {
160  THROW_ASSERT(GetPointer<port_o>(sig1)->get_ports_size(), "");
161  auto sig =
162  SM->add_sign_vector(sig_name, GetPointer<port_o>(sig1)->get_ports_size(), SM->get_circ(), sig1->get_typeRef());
163  SM->add_connection(sig, sig1);
164  SM->add_connection(sig, sig2);
165 }
166 
168  const std::string& port1_name, const structural_objectRef component2,
169  const std::string& port2_name, const std::string& signal_name)
170 {
171  structural_objectRef port1;
172  unsigned long long size1;
173  if(port1_name.find('[') != std::string::npos)
174  {
175  const auto port1_base_name = port1_name.substr(0, port1_name.find('['));
176  const auto port1_index =
177  port1_name.substr(port1_name.find('[') + 1, port1_name.size() - port1_base_name.size() - 2);
178  const auto port1_vector = component1->find_member(port1_base_name, port_o_K, component1);
179  THROW_ASSERT(port1_vector, port1_name + " is not in " + component1->get_path());
180  port1 = GetPointer<port_o>(port1_vector)->get_port(static_cast<unsigned>(std::stoul(port1_index)));
181  size1 = GetPointer<port_o>(port1_vector)->get_typeRef()->vector_size;
182  }
183  else
184  {
185  port1 = component1->find_member(port1_name, port_o_K, component1);
186  THROW_ASSERT(port1, port1_name + " is not in " + component1->get_path());
187  size1 = GET_TYPE_SIZE(port1);
188  }
189  structural_objectRef port2;
190  unsigned long long size2;
191  if(port2_name.find('[') != std::string::npos)
192  {
193  const auto port2_base_name = port2_name.substr(0, port2_name.find('['));
194  const auto port2_index =
195  port2_name.substr(port2_name.find('[') + 1, port2_name.size() - port2_base_name.size() - 2);
196  const auto port2_vector = component2->find_member(port2_base_name, port_o_K, component2);
197  THROW_ASSERT(port2_vector, port2_base_name + " is not in " + component2->get_path());
198  port2 = GetPointer<port_o>(port2_vector)->get_port(static_cast<unsigned>(std::stoul(port2_index)));
199  size2 = GetPointer<port_o>(port2_vector)->get_typeRef()->vector_size;
200  }
201  else
202  {
203  port2 = component2->find_member(port2_name, port_o_K, component2);
204  THROW_ASSERT(port2, port2_name + " is not in " + component2->get_path());
205  size2 = GET_TYPE_SIZE(port2);
206  }
208  "---Connecting " + component1->get_id() + "::" + port1_name + " (Size " + STR(size1) + ") to " +
209  component2->get_id() + "::" + port2_name + " (Size " + STR(size2) + ")");
210  if(size1 > size2)
211  {
212  GetPointer<port_o>(port2)->type_resize(size1);
213  }
214  if(size1 < size2)
215  {
216  GetPointer<port_o>(port1)->type_resize(size2);
217  }
218  const auto bounded_object = GetPointer<port_o>(port1)->find_bounded_object();
219  if(bounded_object)
220  {
221  SM->add_connection(bounded_object, port2);
222  }
223  else
224  {
225  structural_objectRef sig = SM->add_sign(signal_name, SM->get_circ(), port1->get_typeRef());
226  SM->add_connection(sig, port1);
227  SM->add_connection(sig, port2);
228  }
229 }
230 
232  const std::string& port1_name, const structural_objectRef component2,
233  const std::string& port2_name)
234 {
235  structural_objectRef port1;
236  unsigned long long size1;
237  if(port1_name.find('[') != std::string::npos)
238  {
239  const auto port1_base_name = port1_name.substr(0, port1_name.find('['));
240  const auto port1_index =
241  port1_name.substr(port1_name.find('[') + 1, port1_name.size() - port1_base_name.size() - 2);
242  const auto port1_vector = component1->find_member(port1_base_name, port_o_K, component1);
243  THROW_ASSERT(port1_vector, port1_name + " is not in " + component1->get_path());
244  port1 = GetPointer<port_o>(port1_vector)->get_port(static_cast<unsigned>(std::stoul(port1_index)));
245  size1 = GetPointer<port_o>(port1_vector)->get_typeRef()->vector_size;
246  }
247  else
248  {
249  port1 = component1->find_member(port1_name, port_o_K, component1);
250  THROW_ASSERT(port1, port1_name + " is not in " + component1->get_path());
251  size1 = GET_TYPE_SIZE(port1);
252  }
253  structural_objectRef port2;
254  unsigned long long size2;
255  if(port2_name.find('[') != std::string::npos)
256  {
257  const auto port2_base_name = port2_name.substr(0, port2_name.find('['));
258  const auto port2_index =
259  port2_name.substr(port2_name.find('[') + 1, port2_name.size() - port2_base_name.size() - 2);
260  const auto port2_vector = component2->find_member(port2_base_name, port_o_K, component2);
261  THROW_ASSERT(port2_vector, port2_base_name + " is not in " + component2->get_path());
262  port2 = GetPointer<port_o>(port2_vector)->get_port(static_cast<unsigned>(std::stoul(port2_index)));
263  size2 = GetPointer<port_o>(port2_vector)->get_typeRef()->vector_size;
264  }
265  else
266  {
267  port2 = component2->find_member(port2_name, port_o_K, component2);
268  THROW_ASSERT(port2, port2_name + " is not in " + component2->get_path());
269  size2 = GET_TYPE_SIZE(port2);
270  }
272  "---Connecting " + component1->get_id() + "::" + port1_name + " (Size " + STR(size1) + ") to " +
273  component2->get_id() + "::" + port2_name + " (Size " + STR(size2) + ")");
274  if(size1 > size2)
275  {
276  GetPointer<port_o>(port2)->type_resize(size1);
277  }
278  if(size1 < size2)
279  {
280  GetPointer<port_o>(port1)->type_resize(size2);
281  }
282  SM->add_connection(port1, port2);
283 }
284 
286  const std::string& port_name, const std::string& constant_value,
287  const unsigned long long constant_size)
288 {
290  unsigned long long size;
291  if(port_name.find('[') != std::string::npos)
292  {
293  const auto port_base_name = port_name.substr(0, port_name.find('['));
294  const auto port_index = port_name.substr(port_name.find('[') + 1, port_name.size() - port_base_name.size() - 2);
295  const auto port_vector = component->find_member(port_base_name, port_o_K, component);
296  THROW_ASSERT(port_vector, port_name + " is not in " + component->get_path());
297  port = GetPointer<port_o>(port_vector)->get_port(static_cast<unsigned>(std::stoul(port_index)));
298  size = GetPointer<port_o>(port_vector)->get_typeRef()->vector_size;
299  }
300  else
301  {
302  port = component->find_member(port_name, port_o_K, component);
303  THROW_ASSERT(port, port_name + " is not in " + component->get_path());
304  size = GetPointer<port_o>(port)->get_port_size();
305  if(size < constant_size)
306  {
307  GetPointer<port_o>(port)->type_resize(constant_size);
308  }
309  }
311  "---Binding " + constant_value + " to " + component->get_id() + "::" + port_name);
312  structural_objectRef constant(
313  new constant_o(parameters->getOption<int>(OPT_debug_level), SM->get_circ(), constant_value));
314  structural_type_descriptorRef constant_type =
315  structural_type_descriptorRef(new structural_type_descriptor("bool", std::max(size, constant_size)));
316  constant->set_type(constant_type);
317  GetPointer<module>(SM->get_circ())->add_internal_object(constant);
318  SM->add_connection(constant, port);
319 }
void add_connection(structural_objectRef src, structural_objectRef dest)
Create a connection between a source structural object and a destination structural object...
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
const HLS_managerRef HLSMgr
information about all the HLS synthesis
Definition: hls_step.hpp:205
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;.
module_interface(const ParameterConstRef _parameters, const HLS_managerRef HLSMgr, unsigned int funId, const DesignFlowManagerConstRef design_flow_manager, const HLSFlowStep_Type hls_flow_step_type)
Constructor.
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.
This step adds the current module to the technology library.
Structure representing the most relevant information about the type of a structural object...
const std::string & get_id() const
Return the identifier associated with the structural_object.
const structural_objectRef get_circ() const
Get a reference to circ field.
RelationshipType
The relationship type.
Source must be executed to satisfy target.
Datastructure to represent a memory symbol in HLS.
const unsigned int funId
identifier of the function to be processed (0 means that it is a global step)
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...
Base class to model interfaces for high-level synthesis.
#define STR(s)
Macro which performs a lexical_cast to a string.
#define max
Definition: backprop.h:17
~module_interface() override
Destructor.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
Definition: exceptions.hpp:292
HLSFlowStep_Type
Definition: hls_step.hpp:95
const std::string get_path() const
Return a unique identifier of the structural object.
redefinition of set to manage ordered/unordered structures
const ParameterConstRef parameters
Set of input parameters.
#define GET_TYPE_SIZE(structural_obj)
Macro returning the size of the type of a structural object.
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.
static structural_objectRef add_sign(std::string id, structural_objectRef owner, structural_type_descriptorRef sign_type, unsigned int treenode=0)
Create a new signal.
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.
void AddSignal(const structural_managerRef SM, const structural_objectRef component1, const std::string &port1, const structural_objectRef component2, const std::string &port2, const std::string &signal_name)
Connects two ports by adding a signal.
void AddConstant(const structural_managerRef SM, const structural_objectRef component, const std::string &port, const std::string &constant, const unsigned long long size)
Connects a constant to a port.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
this class is used to manage the command-line or XML options.
constant strings
Wrapper to call graph.
Class implementation of the structural_manager.
int debug_level
The debug level.
refcount< const HLSFlowStepSpecialization > HLSFlowStepSpecializationConstRef
const refcount definition of the class
Definition: hls_step.hpp:93
This class describes a constant value.
Information about speciaization of add_library.
Definition: add_library.hpp:58
void AddConnection(const structural_managerRef SM, const structural_objectRef component1, const std::string &port1, const structural_objectRef component2, const std::string &port2)
Connects two ports by adding a signal.
Datastructure to describe functions allocation in high-level synthesis.
void add_sign_vector(const structural_managerRef SM, const structural_objectRef sig1, const structural_objectRef sig2, const std::string &sig_name)
Connects two ports by adding a vector signal (i.e., wire)
Data structure definition for high-level synthesis flow.
Superclass include.
void add_sign(const structural_managerRef SM, const structural_objectRef sig1, const structural_objectRef sig2, const std::string &sig_name)
Connects two ports by adding a signal (i.e., wire)
Datastructure to represent memory information in high-level synthesis.
A brief description of the C++ Header File.
static structural_objectRef add_sign_vector(std::string id, unsigned int n_signs, structural_objectRef owner, structural_type_descriptorRef sign_type, unsigned int treenode=0)
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...
Definition: exceptions.hpp:289

Generated on Mon Feb 12 2024 13:02:53 for PandA-2024.02 by doxygen 1.8.13