PandA-2024.02
hls.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  */
47 #include "hls.hpp"
48 
49 #include "BambuParameter.hpp"
51 #include "chaining_information.hpp"
52 #include "conn_binding.hpp"
53 #include "dbgPrintHelper.hpp"
54 #include "exceptions.hpp"
55 #include "fu_binding.hpp"
56 #include "hls_constraints.hpp"
57 #include "hls_device.hpp"
58 #include "op_graph.hpp"
59 #include "polixml.hpp"
60 #include "reg_binding.hpp"
61 #include "schedule.hpp"
62 #include "standard_hls.hpp"
64 #include "structural_manager.hpp"
65 #include "technology_manager.hpp"
66 #include "technology_node.hpp"
67 #include "utility.hpp"
68 #include "virtual_hls.hpp"
69 #include "xml_helper.hpp"
70 
71 #include <utility>
72 
73 static void computeResources(const structural_objectRef circ, const technology_managerRef TM,
74  std::map<std::string, unsigned int>& resources);
75 
76 /*************************************************************************************************
77  * *
78  * HLS methods *
79  * *
80  *************************************************************************************************/
81 
82 hls::hls(const ParameterConstRef _Param, unsigned int _function_id, OpVertexSet _operations, const HLS_deviceRef _HLS_T,
83  const HLS_constraintsRef _HLS_C)
84  : functionId(_function_id),
85  operations(std::move(_operations)),
86  HLS_D(_HLS_T),
87  HLS_C(_HLS_C),
88  allocation_information(),
89  registered_inputs(false),
90  registered_done_port(false),
91  call_sites_number(0),
92  Param(_Param),
93  debug_level(_Param->getOption<int>(OPT_debug_level)),
94  output_level(_Param->getOption<int>(OPT_output_level)),
95  HLS_execution_time(0)
96 {
97  THROW_ASSERT(HLS_D, "HLS initialization: HLS_device not available");
98  THROW_ASSERT(HLS_C, "HLS initialization: HLS_constraints not available");
99  THROW_ASSERT(Param, "HLS initialization: Parameter not available");
100 }
101 
102 hls::~hls() = default;
103 
104 void hls::xload(const xml_element* node, const OpGraphConstRef data)
105 {
106  ScheduleRef sch = this->Rsch;
107  fu_binding& fu = *(this->Rfu);
108  unsigned int tot_cstep = 0;
109 
110  std::map<std::string, vertex> String2Vertex;
111  std::map<std::pair<std::string, std::string>, std::list<unsigned int>> String2Id;
112 
113  for(auto operation : operations)
114  {
115  String2Vertex[GET_NAME(data, operation)] = operation;
116  }
117 
118  for(unsigned int id = 0; id < allocation_information->get_number_fu_types(); id++)
119  {
120  String2Id[allocation_information->get_fu_name(id)].push_back(id);
121  }
122  // Recurse through child nodes:
123  const xml_node::node_list list = node->get_children();
124  for(const auto& iter : list)
125  {
126  const auto* Enode = GetPointer<const xml_element>(iter);
127  if(!Enode || Enode->get_name() != "scheduling")
128  {
129  continue;
130  }
131  const xml_node::node_list list1 = Enode->get_children();
132  for(const auto& iter1 : list1)
133  {
134  const auto* EnodeC = GetPointer<const xml_element>(iter1);
135  if(!EnodeC)
136  {
137  continue;
138  }
139  if(EnodeC->get_name() == "scheduling_constraints")
140  {
141  std::string vertex_name;
142  unsigned int cstep = 0u;
143  LOAD_XVM(vertex_name, EnodeC);
144  THROW_ASSERT(vertex_name != "", "bad formed xml file: vertex_name expected in a hls specification");
145  if(CE_XVM(cstep, EnodeC))
146  {
147  LOAD_XVM(cstep, EnodeC);
148  }
149  else
150  {
151  THROW_ERROR("bad formed xml file: cstep expected in a hls specification for operation " + vertex_name);
152  }
153  if(cstep > tot_cstep)
154  {
155  tot_cstep = cstep;
156  }
157 
158  unsigned int fu_index;
159  LOAD_XVM(fu_index, EnodeC);
160 
161  std::string fu_name;
162  std::string library = LIBRARY_STD;
163  LOAD_XVM(fu_name, EnodeC);
164  if(CE_XVM(library, EnodeC))
165  {
166  LOAD_XVM(library, EnodeC);
167  }
168  unsigned int fu_type;
169  if(allocation_information->is_artificial_fu(String2Id[std::make_pair(fu_name, library)].front()) ||
170  allocation_information->is_assign(String2Id[std::make_pair(fu_name, library)].front()))
171  {
172  fu_type = String2Id[std::make_pair(fu_name, library)].front();
173  String2Id[std::make_pair(fu_name, library)].pop_front();
174  }
175  else
176  {
177  fu_type = String2Id[std::make_pair(fu_name, library)].front();
178  }
179 
180  sch->set_execution(String2Vertex[vertex_name], ControlStep(cstep));
181  fu.bind(String2Vertex[vertex_name], fu_type, fu_index);
182  }
183  }
184  }
185  sch->set_csteps(ControlStep(tot_cstep + 1u));
186 }
187 
188 void hls::xwrite(xml_element* rootnode, const OpGraphConstRef data)
189 {
190  const ScheduleRef sch = this->Rsch;
191  fu_binding& fu = *(this->Rfu);
192 
193  xml_element* Enode = rootnode->add_child_element("scheduling");
194 
195  for(auto operation : operations)
196  {
197  xml_element* EnodeC = Enode->add_child_element("scheduling_constraints");
198  std::string vertex_name = GET_NAME(data, operation);
199  const auto cstep = sch->get_cstep(operation).second;
200  WRITE_XVM(vertex_name, EnodeC);
201  WRITE_XVM(cstep, EnodeC);
202 
203  unsigned int fu_type = fu.get_assign(operation);
204  unsigned int fu_index = fu.get_index(operation);
205  std::string fu_name, library;
206  boost::tie(fu_name, library) = allocation_information->get_fu_name(fu_type);
207 
208  WRITE_XVM(fu_name, EnodeC);
209  WRITE_XVM(fu_index, EnodeC);
210  if(library != LIBRARY_STD)
211  {
212  WRITE_XVM(library, EnodeC);
213  }
214  }
215 
216  if(datapath)
217  {
218  Enode = rootnode->add_child_element("resource_allocation");
219  std::map<std::string, unsigned int> resources;
220  const technology_managerRef TM = HLS_D->get_technology_manager();
221  computeResources(datapath->get_circ(), TM, resources);
222  for(auto& resource : resources)
223  {
224  xml_element* EnodeC = Enode->add_child_element("resource");
225  std::string name = resource.first;
226  unsigned int number = resource.second;
227  WRITE_XVM(name, EnodeC);
228  WRITE_XVM(number, EnodeC);
229  }
230  }
231 }
232 
234  std::map<std::string, unsigned int>& resources)
235 {
236  const module* mod = GetPointer<module>(circ);
237  auto processResources = [&](const structural_objectRef c) {
238  THROW_ASSERT(c, "unexpected condition");
239  const structural_type_descriptorRef id_type = c->get_typeRef();
240  if(c->get_kind() != component_o_K)
241  {
242  return;
243  }
244  computeResources(c, TM, resources);
245  if(c->get_id() == "Controller_i" || c->get_id() == "Datapath_i")
246  {
247  return;
248  }
249  std::string library = TM->get_library(id_type->id_type);
250  if(library == WORK_LIBRARY || library == PROXY_LIBRARY)
251  {
252  return;
253  }
254  resources[id_type->id_type]++;
255  };
256  for(unsigned int l = 0; l < mod->get_internal_objects_size(); l++)
257  {
258  const structural_objectRef obj = mod->get_internal_object(l);
259  processResources(obj);
260  }
263  {
264  std::string ip_cores = NPF->get_NP_functionality(NP_functionality::IP_COMPONENT);
265  std::vector<std::string> ip_cores_list = string_to_container<std::vector<std::string>>(ip_cores, ",");
266  for(const auto& ip_core : ip_cores_list)
267  {
268  std::vector<std::string> ip_core_vec = string_to_container<std::vector<std::string>>(ip_core, ":");
269  if(ip_core_vec.size() < 1 or ip_core_vec.size() > 2)
270  {
271  THROW_ERROR("Malformed IP component definition \"" + ip_core + "\"");
272  }
273  std::string library, component_name;
274  if(ip_core_vec.size() == 2)
275  {
276  library = ip_core_vec[0];
277  component_name = ip_core_vec[1];
278  }
279  else
280  {
281  component_name = ip_core_vec[0];
282  library = TM->get_library(component_name);
283  }
284  technology_nodeRef tn = TM->get_fu(component_name, library);
285  structural_objectRef core_cir;
286  if(tn->get_kind() == functional_unit_K)
287  {
288  core_cir = GetPointer<functional_unit>(tn)->CM->get_circ();
289  }
290  else if(tn->get_kind() == functional_unit_template_K &&
291  GetPointer<functional_unit>(GetPointer<functional_unit_template>(tn)->FU))
292  {
293  core_cir = GetPointer<functional_unit>(GetPointer<functional_unit_template>(tn)->FU)->CM->get_circ();
294  }
295  else
296  {
297  THROW_ERROR("Unexpected pattern");
298  }
299  processResources(core_cir);
300  }
301  }
302 }
303 
305 {
306  THROW_ASSERT(datapath, "datapath not yet created!");
307  std::map<std::string, unsigned int> resources;
308  const technology_managerRef TM = HLS_D->get_technology_manager();
309  computeResources(datapath->get_circ(), TM, resources);
311  {
313  }
314  INDENT_OUT_MEX(OUTPUT_LEVEL_MINIMUM, output_level, "-->Summary of resources:");
315  for(auto r = resources.begin(); r != resources.end(); ++r)
316  {
317  INDENT_OUT_MEX(OUTPUT_LEVEL_MINIMUM, output_level, "--- - " + r->first + ": " + STR(r->second));
318  }
320 }
class containing information about chaining
File containing functions and utilities to support the printing of debug messagges.
const structural_objectRef get_internal_object(unsigned int n) const
Return the ith internal objects.
structural_managerRef datapath
Store the datapath description.
Definition: hls.hpp:155
technology_nodeRef get_fu(const std::string &fu_name, const std::string &Library) const
Return the reference to a component given its name.
const ParameterConstRef Param
class containing all the parameters
Definition: hls.hpp:169
static void computeResources(const structural_objectRef circ, const technology_managerRef TM, std::map< std::string, unsigned int > &resources)
Definition: hls.cpp:233
const structural_objectRef get_circ() const
Get a reference to circ field.
AbsControlStep get_cstep(const vertex &op) const
Returns the clock cycle where the given operation has been scheduled.
Definition: schedule.cpp:270
#define INDENT_OUT_MEX(outLevel, curOutLevel, mex)
std::string get_NP_functionality(NP_functionaly_type type) const
Return the description provided the type.
unsigned int get_assign(const vertex &v) const
Returns the functional unit assigned to the vertex.
Definition: fu_binding.cpp:242
void set_csteps(ControlStep cs)
This method sets the number of control steps.
Definition: schedule.hpp:225
#define GET_NAME(data, vertex_index)
Helper macro returning the name associated with a node.
std::pair< std::string, std::string > get_fu_name(unsigned int id) const
Returns the name of the functional unit, associated with the name of the library, given the correspon...
const HLS_deviceRef HLS_D
reference to the information representing the target for the synthesis
Definition: hls.hpp:107
exceptions managed by PandA
AllocationInformationRef allocation_information
Store the technology information.
Definition: hls.hpp:115
#define CE_XVM(variable, node)
Check existence XML Value Macro. Check if an XML attribute is present in the XML tree.
Definition: xml_helper.hpp:88
Definition of hash function for EdgeDescriptor.
Definition: graph.hpp:1321
OpVertexSet operations
Set representing the subset of operations in the specification to be implemented. ...
Definition: hls.hpp:102
void xwrite(xml_element *rootnode, const OpGraphConstRef data)
Writes current HLS results to XML node.
Definition: hls.cpp:188
unsigned int get_internal_objects_size() const
Return the number of internal objects.
Class specification of the manager of the technology library data structures.
#define OUTPUT_LEVEL_MINIMUM
minimum debugging print is performed.
A set of operation vertices.
Definition: op_graph.hpp:654
#define STR(s)
Macro which performs a lexical_cast to a string.
hls(const ParameterConstRef Param, unsigned int function_id, OpVertexSet operations, const HLS_deviceRef HLS_D, const HLS_constraintsRef HLS_C)
Definition: hls.cpp:82
fu_bindingRef Rfu
Store the refcounted functional unit binding of the operations.
Definition: hls.hpp:121
ScheduleRef Rsch
Store the refcounted scheduling of the operations.
Definition: hls.hpp:118
Data structure used to store the register binding of variables.
This class specifies the characteristic of a particular operation working on a given functional unit...
Data structure used to store the interconnection binding of datapath elements.
Data structure used to store the schedule of the operations.
Class specification of the data structures used to manage technology information. ...
const NP_functionalityRef & get_NP_functionality() const
Return the alternative functionalities.
int output_level
verbosity level of the class
Definition: hls.hpp:175
void bind(const vertex &v, unsigned int unit, unsigned int index=std::numeric_limits< unsigned int >::max())
Binds an operation vertex to a functional unit.
Definition: fu_binding.cpp:173
#define LIBRARY_STD
standard library where all built-in ports are defined.
This package is used by all HLS packages to manage resource constraints and characteristics.
This file collects some utility functions and macros.
Definition of the class to create the structural description of the component.
std::list< xml_nodeRef > node_list
type for list of xml nodes
Definition: xml_node.hpp:90
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
Definition: exceptions.hpp:263
~hls()
Destructor.
Data structure definition for HLS constraints.
This package is used to define the storage value scheme adopted by the register allocation algorithms...
std::string id_type
Original type id of the structural object.
#define OUTPUT_LEVEL_PEDANTIC
verbose debugging print is performed.
Data structure used to store the functional-unit binding of the vertexes.
#define WORK_LIBRARY
working library.
#define WRITE_XVM(variable, node)
WRITE XML Value Macro. Insert a value in an XML tree.
Definition: xml_helper.hpp:51
bool is_assign(const unsigned int fu_name) const
Checks if the functional unit implements an ASSIGN operation.
Data structures used in operations graph.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
void xload(const xml_element *rootnode, const OpGraphConstRef data)
Loads previous HLS results from XML node.
Definition: hls.cpp:104
void PrintResources() const
Prints the summary of allocated resources.
Definition: hls.cpp:304
Basic HLS flow.
#define LOAD_XVM(variable, node)
LOAD XML Value Macro. Set a variable starting from an XML value. Conversion is performed if needed...
Definition: xml_helper.hpp:65
Some macro used to interface with the XML library.
node_list const & get_children()
Obtain the list of child nodes.
Definition: xml_node.hpp:310
Class implementation of the structural_manager.
Class managing the functional-unit binding.
Definition: fu_binding.hpp:90
const HLS_constraintsRef HLS_C
store the HLS constraints
Definition: hls.hpp:110
bool exist_NP_functionality(NP_functionaly_type type) const
Return true in case there exist a functionaly of the given type.
bool is_artificial_fu(const unsigned int fu_name) const
Checks if the functional unit is actually an artificial functional unit like: NOP, ENTRY and EXIT.
Data structure definition for high-level synthesis flow.
This class describes a generic module.
void set_execution(const vertex &op, ControlStep c_step)
Sets the starting clock cycle for the given operation.
Definition: schedule.cpp:232
xml_element * add_child_element(const std::string &name)
Add a child element to this node.
Definition: xml_node.cpp:54
#define PROXY_LIBRARY
proxy library
unsigned int get_index(const vertex &v) const
Returns the index of functional unit assigned to the vertex.
Definition: fu_binding.cpp:261
HLS specialization of generic_device.
std::string get_library(const std::string &Name) const
Return the higher priority library where the given component is stored.
unsigned int get_number_fu_types() const
Returns the number of functional units types.
#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