PandA-2024.02
technology_manager.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  */
45 #include "technology_manager.hpp"
46 
47 #include "config_HAVE_CIRCUIT_BUILT.hpp"
48 
49 #include "Parameter.hpp"
50 #include "area_info.hpp"
51 #include "constant_strings.hpp"
52 #include "custom_map.hpp"
53 #include "dbgPrintHelper.hpp"
54 #include "exceptions.hpp"
55 #include "fileIO.hpp"
56 #include "graph.hpp"
57 #include "library_manager.hpp"
58 #include "polixml.hpp"
59 #include "string_manipulation.hpp"
60 #include "structural_manager.hpp"
61 #include "technology_node.hpp"
62 #include "time_info.hpp"
63 #include "utility.hpp"
64 #include "xml_helper.hpp"
65 
66 #include <filesystem>
67 
68 const unsigned int technology_manager::XML = 1 << 0;
69 
71 {
72  debug_level = Param->get_class_debug_level(GET_CLASS(*this));
73 }
74 
76 
77 void technology_manager::print(std::ostream& os) const
78 {
79  for(const auto& librarie : libraries)
80  {
81  const library_managerRef library = library_map.find(librarie)->second;
82  const library_manager::fu_map_type& cells = library->get_library_fu();
83  for(const auto& cell : cells)
84  {
85  cell.second->print(os);
86  }
87  }
88 }
89 
90 bool technology_manager::can_implement(const std::string& fu_name, const std::string& op_name,
91  const std::string& Library) const
92 {
93  technology_nodeRef node = get_fu(fu_name, Library);
94  if(!node)
95  {
96  return false;
97  }
98  return GetPointer<functional_unit>(node)->get_operation(op_name) ? true : false;
99 }
100 
101 technology_nodeRef technology_manager::get_fu(const std::string& fu_name, const std::string& Library) const
102 {
103  THROW_ASSERT(Library.size(), "Library not specified for component " + fu_name);
104  if(library_map.count(Library) && library_map.at(Library)->is_fu(fu_name))
105  {
106  return library_map.at(Library)->get_fu(fu_name);
107  }
108  return nullptr;
109 }
110 
111 technology_nodeRef technology_manager::get_fu(const std::string& fu_name, std::string* Library) const
112 {
113  for(const auto& lib : libraries)
114  {
115  THROW_ASSERT(library_map.count(lib), "Library " + lib + " not found");
116  if(library_map.at(lib)->is_fu(fu_name))
117  {
118  if(Library)
119  {
120  *Library = lib;
121  }
122  return library_map.at(lib)->get_fu(fu_name);
123  }
124  }
125  return nullptr;
126 }
127 
128 ControlStep technology_manager::get_initiation_time(const std::string& fu_name, const std::string& op_name,
129  const std::string& Library) const
130 {
131  technology_nodeRef node = get_fu(fu_name, Library);
132  THROW_ASSERT(GetPointer<functional_unit>(node), "Unit " + fu_name + " not stored into library (" + Library + ")");
133  technology_nodeRef node_op = GetPointer<functional_unit>(node)->get_operation(op_name);
134  THROW_ASSERT(GetPointer<operation>(node_op),
135  "Operation " + op_name + " not stored into " + fu_name + " library (" + Library + ")");
136  THROW_ASSERT(GetPointer<operation>(node_op)->time_m, "Missing timing information");
137  return GetPointer<operation>(node_op)->time_m->get_initiation_time();
138 }
139 
140 double technology_manager::get_execution_time(const std::string& fu_name, const std::string& op_name,
141  const std::string& Library) const
142 {
143  technology_nodeRef node = get_fu(fu_name, Library);
144  THROW_ASSERT(GetPointer<functional_unit>(node), "Unit " + fu_name + " not stored into library (" + Library + ")");
145  technology_nodeRef node_op = GetPointer<functional_unit>(node)->get_operation(op_name);
146  THROW_ASSERT(GetPointer<operation>(node_op),
147  "Operation " + op_name + " not stored into " + fu_name + " library (" + Library + ")");
148  THROW_ASSERT(GetPointer<operation>(node_op)->time_m, "Missing timing information");
149  return GetPointer<operation>(node_op)->time_m->get_execution_time();
150 }
151 
152 double technology_manager::get_area(const std::string& fu_name, const std::string& Library) const
153 {
154  technology_nodeRef node = get_fu(fu_name, Library);
155  THROW_ASSERT(GetPointer<functional_unit>(node), "Unit " + fu_name + " not stored into library (" + Library + ")");
156  THROW_ASSERT(GetPointer<functional_unit>(node)->area_m,
157  "Unit " + fu_name + "(" + Library + ") does not store area model");
158  return GetPointer<functional_unit>(node)->area_m->get_area_value();
159 }
160 
161 #if HAVE_CIRCUIT_BUILT
162 void technology_manager::add_resource(const std::string& Library, const std::string& fu_name,
163  const structural_managerRef CM, const bool is_builtin)
164 {
165  technology_nodeRef curr = get_fu(fu_name, Library);
166  if(!curr)
167  {
169  GetPointer<functional_unit>(curr)->functional_unit_name = fu_name;
170  GetPointer<functional_unit>(curr)->CM = CM;
171  add(curr, Library);
172  }
173  else
174  {
175  GetPointer<functional_unit>(curr)->CM = CM;
176  }
177  if(is_builtin)
178  {
179  builtins.insert(fu_name);
180  }
181 }
182 #endif
183 
184 technology_nodeRef technology_manager::add_operation(const std::string& Library, const std::string& fu_name,
185  const std::string& operation_name)
186 {
187  THROW_ASSERT(library_map.count(Library), "Library \"" + Library + "\" not found");
188  THROW_ASSERT(library_map.at(Library)->is_fu(fu_name), "Unit \"" + fu_name + "\" not found in library \"" + Library);
189  const auto curr = get_fu(fu_name, Library);
190  const technology_nodeRef curr_op(new operation);
191  GetPointerS<operation>(curr_op)->operation_name = operation_name;
192  auto fu = GetPointer<functional_unit>(curr);
193  THROW_ASSERT(fu, "");
194  fu->add(curr_op);
195  function_fu[operation_name] = curr;
196  return curr_op;
197 }
198 
199 void technology_manager::add(const technology_nodeRef curr, const std::string& Library)
200 {
201  auto it = std::find(libraries.begin(), libraries.end(), Library);
202  if(it == libraries.end())
203  {
204  bool std = true;
205  if(Library == CG_LIBRARY || Library == DESIGN)
206  {
207  std = false;
208  }
209  library_managerRef lib(new library_manager(Library, Param, std));
210  library_map[Library] = lib;
211  libraries.push_back(Library);
212  }
213  library_map[Library]->add(curr);
214 }
215 
217 {
218  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Loading xml technology");
219  std::map<unsigned int, std::string> info;
221 
222  const xml_node::node_list list = node->get_children();
223  for(const auto& iter : list)
224  {
225  const auto* Enode = GetPointer<const xml_element>(iter);
226  if(!Enode)
227  {
228  continue;
229  }
230  if(Enode->get_name() == "information")
231  {
232  }
233  if(Enode->get_name() == "library")
234  {
236  library_manager::xload(Enode, LM, Param);
237 
238  std::string library_name = LM->get_library_name();
239  if(library_map.find(library_name) == library_map.end())
240  {
241  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Loading library " + library_name);
242  library_map[library_name] = LM;
243  libraries.push_back(library_name);
244  temp_libraries.insert(LM);
245  LM->set_info(library_manager::XML, "");
246  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Loaded library " + library_name);
247  }
248  else
249  {
250  const library_manager::fu_map_type& fus = LM->get_library_fu();
251  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Updating library " + library_name);
252  for(const auto& fu : fus)
253  {
254  if(library_map[library_name]->is_fu(fu.first))
255  {
257  if(not GetPointer<const functional_unit>(library_map[library_name]->get_fu(fu.first)) or
258  GetPointer<const functional_unit>(library_map[library_name]->get_fu(fu.first))
259  ->characterization_timestamp <=
260  GetPointer<const functional_unit>(fu.second)->characterization_timestamp)
261  {
264  "-->Updating " + fu.first +
265  (GetPointer<const functional_unit>(library_map[library_name]->get_fu(fu.first)) ?
266  " characterized at " +
267  STR(GetPointer<const functional_unit>(fu.second)->characterization_timestamp) +
268  " - Previous characterization is at " +
269  STR(GetPointer<const functional_unit>(library_map[library_name]->get_fu(fu.first))
270  ->characterization_timestamp) :
271  ""));
272  library_map[library_name]->update(fu.second);
273  }
274  else
275  {
278  "-->Not updating " + fu.first +
279  (GetPointer<const functional_unit>(library_map[library_name]->get_fu(fu.first)) ?
280  " characterized at " +
281  STR(GetPointer<const functional_unit>(fu.second)->characterization_timestamp) +
282  " - Previous characterization is at " +
283  STR(GetPointer<const functional_unit>(library_map[library_name]->get_fu(fu.first))
284  ->characterization_timestamp) :
285  ""));
286  }
288  }
289  else
290  {
293  "-->Loading " + fu.first +
294  (GetPointer<const functional_unit>(fu.second) ?
295  " characterized at " +
296  STR(GetPointer<const functional_unit>(fu.second)->characterization_timestamp) :
297  ""));
298  library_map[library_name]->add(fu.second);
300  }
301  }
302  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Updated library " + library_name);
303  }
304  }
305  }
306  for(const auto& temp_library : temp_libraries)
307  {
308  for(const auto& temp_info : info)
309  {
310  temp_library->set_info(temp_info.first, temp_info.second);
311  }
312  }
313  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Loaded xml technology");
314 }
315 
317 {
319  CustomOrderedSet<std::string> sorted_libraries;
320  for(const auto& library : library_map)
321  {
322  sorted_libraries.insert(library.first);
323  }
324  for(const auto& library : sorted_libraries)
325  {
326  if(library == "design")
327  {
328  continue;
329  }
330  if(_libraries.empty() || _libraries.count(library))
331  {
332  if(get_library_manager(library)->get_library_fu().size())
333  {
334  get_library_manager(library)->xwrite(rootnode);
335  }
336  }
337  }
338 }
339 
340 std::string technology_manager::get_library(const std::string& Name) const
341 {
342  std::string Library;
343  for(const auto& librarie : libraries)
344  {
345  Library = librarie;
346  THROW_ASSERT(library_map.find(Library) != library_map.end(), "Library " + Library + " not found");
347  if(library_map.find(Library)->second->is_fu(Name))
348  {
349  return Library;
350  }
351  }
353  return "";
354 }
355 
357 {
358  THROW_ASSERT(library_map.find(Name) != library_map.end(), "library_manager not stored for library: " + Name);
359  return library_map.find(Name)->second;
360 }
361 
362 bool technology_manager::is_library_manager(const std::string& Name) const
363 {
364  return library_map.find(Name) != library_map.end();
365 }
366 
367 void technology_manager::erase_library(const std::string& Name)
368 {
369  library_map.erase(Name);
370  if(std::find(libraries.begin(), libraries.end(), Name) != libraries.end())
371  {
372  libraries.erase(std::find(libraries.begin(), libraries.end(), Name));
373  }
374 }
375 
376 bool technology_manager::IsBuiltin(const std::string& component_name) const
377 {
378  return builtins.find(component_name) != builtins.end();
379 }
380 
382 {
383  const technology_nodeConstRef f_unit_as = get_fu("ASSIGN_SINGLE_UNSIGNED_FU", LIBRARY_STD_FU);
384  if(f_unit_as)
385  {
386  return GetPointer<const functional_unit>(f_unit_as);
387  }
388  else
389  {
390  return nullptr;
391  }
392 }
393 
395 {
396  const auto fu_as = CGetSetupHoldFU();
397  if(!fu_as)
398  {
399  return 0.1;
400  }
401  const technology_nodeConstRef op_as_node = fu_as->get_operation("ASSIGN_SINGLE");
402  const auto op_ASSIGN = GetPointer<const operation>(op_as_node);
403  THROW_ASSERT(op_ASSIGN->time_m->get_execution_time() > 0.0, "expected a setup time greater than zero");
404  return op_ASSIGN->time_m->get_execution_time();
405 }
406 
408 {
409  auto fu = CGetSetupHoldFU();
410  if(fu)
411  {
413  }
414  else
415  {
416  return TimeStamp();
417  }
418 }
419 
421 {
422  const auto fu_it = function_fu.find(fname);
423  return fu_it != function_fu.end() ? fu_it->second : nullptr;
424 }
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
double CGetSetupHoldTime() const
Return the setup hold time.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
Collect information about resource area.
const fu_map_type & get_library_fu() const
Return the list of the resources contained into the given library.
File containing functions and utilities to support the printing of debug messagges.
technology_nodeRef get_fu(const std::string &fu_name, const std::string &Library) const
Return the reference to a component given its name.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
void xwrite(xml_element *rootnode, const CustomOrderedSet< std::string > &libraries=CustomOrderedSet< std::string >())
add library elements operation node to an xml tree.
void print(std::ostream &os) const
Function that prints the class technology_manager.
void set_info(unsigned int type, const std::string &information)
const ParameterConstRef Param
class containing all the parameters
Class specification of the graph structures.
exceptions managed by PandA
static void xload(const xml_element *node, const library_managerRef &LM, const ParameterConstRef &Param)
#define CG_LIBRARY
compound gates
void xwrite(xml_element *rootnode)
Collect information about resource performance.
~technology_manager()
Destructor.
Definition of hash function for EdgeDescriptor.
Definition: graph.hpp:1321
#define LIBRARY_STD_FU
standard library where all standard HLS resources are defined
Class specification of the manager of the technology library data structures.
This class specifies the characteristic of a particular functional unit.
void xload(const xml_element *node)
Load a technology manager from an xml file.
redefinition of map to manage ordered/unordered structures
TimeStamp characterization_timestamp
The timestamp of the characterization of this functional unit.
technology_nodeRef add_operation(const std::string &Library, const std::string &fu_name, const std::string &operation_name)
Add an operation to the specified functional unit.
refcount< technology_node > technology_nodeRef
refcount definition of the class
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
technology_manager(const ParameterConstRef Param)
Constructor.
static const unsigned int XML
#define DESIGN
Autoheader include.
CustomSet< std::string > builtins
The builtin components.
double get_area(const std::string &fu_name, const std::string &Library) const
Return the area for a given component.
void add(const technology_nodeRef curr, const std::string &Library)
Add the given functional_unit to the specified library.
This class specifies the characteristic of a particular operation working on a given functional unit...
Class specification of the data structures used to manage technology information. ...
int debug_level
The debug level for this class.
ControlStep get_initiation_time(const std::string &fu_name, const std::string &op_name, const std::string &Library) const
Return the initiation time for a given operation type and a given component.
bool IsBuiltin(const std::string &component_name) const
Return true if a component is builtin.
utility function used to read files.
This file collects some utility functions and macros.
std::list< xml_nodeRef > node_list
type for list of xml nodes
Definition: xml_node.hpp:90
bool is_library_manager(const std::string &Name) const
Check if a library is contained into the data structure.
std::map< std::string, technology_nodeRef > fu_map_type
typedef for the identification of the functional units contained into the library ...
library_map_type library_map
map between library name and the corresponding data structure
const functional_unit * CGetSetupHoldFU() const
Return the functional unit used to compute the setup hold time.
std::vector< std::string > libraries
(reverse) ordered list of libraries; it gives a priority ordering for searching the nodes ...
This class manages the specific library structure.
CustomUnorderedMap< std::string, technology_nodeRef > function_fu
Map function names to hardware module used for implementation.
void erase_library(const std::string &Name)
Release the given library.
TimeStamp CGetSetupHoldTimeStamp() const
Return the characterization timestamp of the setup hold time.
technology_nodeRef GetFunctionFU(const std::string &fname) const
Return FU used to implement given function if any.
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.
The type used for timestamp.
Definition: utility.hpp:280
constant strings
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.
std::string get_library_name() const
Class specification of the manager for each library.
bool can_implement(const std::string &fu_name, const std::string &op_name, const std::string &Library) const
Check if an operation can be implemented by a given component in a given library. ...
double get_execution_time(const std::string &fu_name, const std::string &op_name, const std::string &Library) const
Return the execution time for a given operation type and a given component.
library_managerRef get_library_manager(const std::string &Name) const
Return the library data structure corresponding to the given library id.
std::string get_library(const std::string &Name) const
Return the higher priority library where the given component is stored.
#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:55 for PandA-2024.02 by doxygen 1.8.13