PandA-2024.02
library_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 "library_manager.hpp"
46 
47 #include "config_HAVE_CIRCUIT_BUILT.hpp"
48 #include "config_HAVE_EXPERIMENTAL.hpp"
49 
50 #include "Parameter.hpp"
51 #include "area_info.hpp"
52 #include "constant_strings.hpp"
53 #include "dbgPrintHelper.hpp" // for DEBUG_LEVEL_
54 #include "exceptions.hpp"
55 #include "parse_technology.hpp"
56 #include "polixml.hpp"
57 #include "technology_node.hpp"
58 #include <iosfwd>
59 #include <utility>
60 
61 attribute::attribute(const std::vector<attributeRef>& _content)
62 {
63  content_list = _content;
64 }
65 
66 attribute::attribute(const std::string& _value_type, std::string _content) : content(std::move(_content))
67 {
69  if(_value_type == "float64")
70  {
71  value_type = FLOAT64;
72  }
73  else if(_value_type == "boolean")
74  {
76  }
77  else if(_value_type == "int32")
78  {
79  value_type = INT32;
80  }
81  else if(_value_type == "string")
82  {
83  value_type = STRING;
84  }
85  else
86  {
87  THROW_ERROR("Not supported attribute type: " + _value_type);
88  }
89 }
90 
91 attribute::attribute(const value_t _value_type, std::string _content)
92  : content(std::move(_content)), value_type(_value_type)
93 {
95  value_type = static_cast<value_t>(_value_type);
96 }
97 
98 std::string attribute::get_value_type_str() const
99 {
100  if(value_type == FLOAT64)
101  {
102  return "float64";
103  }
104  if(value_type == BOOLEAN)
105  {
106  return "boolean";
107  }
108  if(value_type == INT32)
109  {
110  return "int32";
111  }
112  else if(value_type == STRING)
113  {
114  return "string";
115  }
116  else
117  {
118  THROW_ERROR("Not supported attribute type: " + STR(value_type));
119  }
120  return "<unknown>";
121 }
122 
123 std::string attribute::get_content_str() const
124 {
126  return content;
127 }
128 
130 {
131  return !content_list.empty();
132 }
133 
134 unsigned int attribute::get_value_type() const
135 {
136  return value_type;
137 }
138 
139 void attribute::xload(const xml_element* EnodeC, std::vector<std::string>& ordered_attributes,
140  std::map<std::string, attributeRef>& attributes)
141 {
142  const xml_attribute* att_name = EnodeC->get_attribute("name");
143  const xml_node::node_list& list_att = EnodeC->get_children();
144  std::vector<attributeRef> _content;
145  for(const auto& iter_int : list_att)
146  {
147  const auto* EnodeC1 = GetPointer<const xml_element>(iter_int);
148  if(!EnodeC1)
149  {
150  continue;
151  }
152  const xml_text_node* txt_node = EnodeC1->get_child_text();
153  _content.push_back(attributeRef(new attribute(EnodeC1->get_name(), txt_node->get_content())));
154  }
155  if(std::find(ordered_attributes.begin(), ordered_attributes.end(), att_name->get_value()) ==
156  ordered_attributes.end())
157  {
158  ordered_attributes.push_back(att_name->get_value());
159  }
160  if(!_content.empty())
161  {
162  attributes[att_name->get_value()] = attributeRef(new attribute(_content));
163  }
164  else
165  {
166  const xml_attribute* value_type_node = EnodeC->get_attribute("value_type");
167  const xml_text_node* txt_node = EnodeC->get_child_text();
168  attributes[att_name->get_value()] =
169  attributeRef(new attribute(value_type_node->get_value(), txt_node->get_content()));
170  }
171 }
172 
173 void attribute::xwrite(xml_element* xml_node, const std::string& name)
174 {
175  xml_element* attr_name = xml_node->add_child_element("attribute");
176  attr_name->set_attribute("name", name);
177  if(!has_list())
178  {
179  attr_name->set_attribute("value_type", get_value_type_str());
180  attr_name->add_child_text(get_content_str());
181  }
182  else
183  {
184  for(auto& v : content_list)
185  {
186  xml_element* el = attr_name->add_child_element(v->get_value_type_str());
187  el->add_child_text(v->get_content_str());
188  }
189  }
190 }
191 
193 {
194 }
195 
196 library_manager::library_manager(ParameterConstRef _Param, bool std) : Param(std::move(_Param)), is_std(std)
197 {
199 }
200 
201 library_manager::library_manager(std::string library_name, ParameterConstRef _Param, bool std)
202  : Param(std::move(_Param)), name(std::move(library_name)), is_std(std)
203 {
205 }
206 
208 
210 {
211 #ifndef NDEBUG
212  int debug_level = Param->get_class_debug_level("library_manager");
213 #endif
214  auto output_level = Param->getOption<int>(OPT_output_level);
215  const xml_node::node_list& list_int = node->get_children();
216  for(const auto& iter_int : list_int)
217  {
218  const auto* EnodeC = GetPointer<const xml_element>(iter_int);
219  if(!EnodeC)
220  {
221  continue;
222  }
223  if(EnodeC->get_name() == "information")
224  {
225  }
226  if(EnodeC->get_name() == "name")
227  {
228  const xml_text_node* text = EnodeC->get_child_text();
229  LM->name = text->get_content();
230  }
231  else if(EnodeC->get_name() == "attribute")
232  {
234  }
235  else if(EnodeC->get_name() == "operating_conditions")
236  {
237  }
238  else if(EnodeC->get_name() == "wire_load")
239  {
240  }
241  else if(EnodeC->get_name() == "power_lut_template")
242  {
243  }
244  else if(EnodeC->get_name() == "lu_table_template")
245  {
246  }
247  else if(EnodeC->get_name() == "output_current_template")
248  {
249  }
250  else if(EnodeC->get_name() == "cell")
251  {
252  technology_nodeRef fu_curr = technology_nodeRef(new functional_unit(iter_int));
253  fu_curr->xload(EnodeC, fu_curr, Param);
254 
255  const auto cell_name = fu_curr->get_name();
256 
258  THROW_ASSERT(not LM->is_fu(cell_name), cell_name + " already present");
259  LM->add(fu_curr);
260  }
261  else if(EnodeC->get_name() == "template")
262  {
264  fut_curr->xload(EnodeC, fut_curr, Param);
265  LM->add(fut_curr);
266  }
267 #ifndef NDEBUG
268  else if(debug_level >= DEBUG_LEVEL_VERBOSE)
269  {
270  THROW_WARNING("library_manager - not yet supported: " + EnodeC->get_name());
271  }
272 #endif
273  }
274 
275  if(output_level >= OUTPUT_LEVEL_MINIMUM)
276  {
277  unsigned int combinational = 0;
278  unsigned int others = 0;
279  unsigned int total = 0;
280  for(auto& l : LM->fu_map)
281  {
282  /*
283  * If the functional unit is a template skip the counting.
284  */
285  if(GetPointer<functional_unit>(l.second) == nullptr && GetPointer<functional_unit_template>(l.second))
286  {
287  continue;
288  }
289  total++;
290  if(GetPointer<functional_unit>(l.second)->logical_type == functional_unit::COMBINATIONAL)
291  {
292  combinational++;
293  }
294  else
295  {
296  others++;
297  }
298  }
299  PRINT_OUT_MEX(OUTPUT_LEVEL_VERBOSE, output_level, "Library Name : " << LM->name);
300  PRINT_OUT_MEX(OUTPUT_LEVEL_VERBOSE, output_level, " Total cells : " << total);
301  PRINT_OUT_MEX(OUTPUT_LEVEL_VERBOSE, output_level, " - combinational: " << combinational);
302  PRINT_OUT_MEX(OUTPUT_LEVEL_VERBOSE, output_level, " - others: " << others);
303  PRINT_OUT_MEX(OUTPUT_LEVEL_VERBOSE, output_level, "");
304  }
305 }
306 
308 {
309  xml_element* library = node->add_child_element("library");
310 
311  xml_element* xml_name = library->add_child_element("name");
312  xml_name->add_child_text(name);
313 
314  for(const auto& ordered_attribute : ordered_attributes)
315  {
316  const attributeRef& attr = attributes[ordered_attribute];
317  attr->xwrite(library, ordered_attribute);
318  }
319 
320  for(auto& f : fu_map)
321  {
322  xml_element* xml_cell;
323  if(GetPointer<functional_unit>(f.second))
324  {
325  xml_cell = library->add_child_element("cell");
326  }
327  else
328  {
329  xml_cell = library->add_child_element("template");
330  }
331  f.second->xwrite(xml_cell, f.second, Param);
332  }
333 }
334 
336 {
337  return name;
338 }
339 
341 {
343  erase_info();
344  std::string _name = node->get_name();
345  fu_map[_name] = node;
346 }
347 
349 {
351  erase_info();
352  std::string _name = fu_node->get_name();
353  technology_nodeRef fu = fu_map[_name];
354  technology_nodeRef node = fu_node;
355  if(!GetPointer<functional_unit>(node))
356  {
357  node = GetPointer<functional_unit_template>(node)->FU;
358  }
359  auto* current_fu = GetPointer<functional_unit>(fu);
360  if(!current_fu)
361  {
362  current_fu = GetPointer<functional_unit>(GetPointer<functional_unit_template>(fu)->FU);
363  }
364  THROW_ASSERT(current_fu, "unexpected condition");
365  current_fu->ordered_attributes = GetPointer<functional_unit>(node)->ordered_attributes;
366  current_fu->attributes = GetPointer<functional_unit>(node)->attributes;
367  if(GetPointer<functional_unit>(node)->area_m)
368  {
369  current_fu->area_m = GetPointer<functional_unit>(node)->area_m;
370  }
371  const functional_unit::operation_vec& operations = GetPointer<functional_unit>(node)->get_operations();
372  for(const auto& o : operations)
373  {
374  const operation* op = GetPointer<operation>(o);
375  const technology_nodeRef op_fu = current_fu->get_operation(op->operation_name);
376  THROW_ASSERT(op_fu, "Missing operation: " + op->operation_name + "-" + _name);
377  if(op->time_m)
378  {
379  GetPointer<operation>(op_fu)->time_m = op->time_m;
380  }
381  if(GetPointer<functional_unit_template>(fu_node))
382  {
383  GetPointer<operation>(op_fu)->pipe_parameters = op->pipe_parameters;
384  }
385  if(GetPointer<functional_unit_template>(fu_node))
386  {
387  GetPointer<operation>(op_fu)->portsize_parameters = op->portsize_parameters;
388  }
389  GetPointer<operation>(op_fu)->bounded = op->bounded;
390 #if HAVE_EXPERIMENTAL
391  if(op->power_m)
392  GetPointer<operation>(op_fu)->power_m = op->power_m;
393 #endif
394  }
395 
396 #if HAVE_CIRCUIT_BUILT
397  if(GetPointer<functional_unit>(node) && GetPointer<functional_unit>(node)->CM)
399  {
400  current_fu->CM = GetPointer<functional_unit>(node)->CM;
401  }
402 #endif
403  if(GetPointer<functional_unit_template>(fu_node) &&
404  !GetPointer<functional_unit_template>(fu_node)->specialized.empty())
405  {
406  GetPointer<functional_unit_template>(fu)->specialized =
407  GetPointer<functional_unit_template>(fu_node)->specialized;
408  }
409  if((GetPointer<functional_unit>(node) && !GetPointer<functional_unit>(node)->fu_template_name.empty()) ||
410  GetPointer<functional_unit_template>(fu_node))
411  {
412  current_fu->fu_template_name = GetPointer<functional_unit>(node)->fu_template_name;
413  }
414  if((GetPointer<functional_unit>(node) && !GetPointer<functional_unit>(node)->fu_template_parameters.empty()) ||
415  GetPointer<functional_unit_template>(fu_node))
416  {
417  current_fu->fu_template_parameters = GetPointer<functional_unit>(node)->fu_template_parameters;
418  }
419  if((GetPointer<functional_unit>(node) &&
420  !GetPointer<functional_unit>(node)->characterizing_constant_value.empty()) ||
421  GetPointer<functional_unit_template>(fu_node))
422  {
423  current_fu->characterizing_constant_value = GetPointer<functional_unit>(node)->characterizing_constant_value;
424  }
425  if((GetPointer<functional_unit>(node) && !GetPointer<functional_unit>(node)->memory_type.empty()) ||
426  GetPointer<functional_unit_template>(fu_node))
427  {
428  current_fu->memory_type = GetPointer<functional_unit>(node)->memory_type;
429  }
430  if((GetPointer<functional_unit>(node) && !GetPointer<functional_unit>(node)->channels_type.empty()) ||
431  GetPointer<functional_unit_template>(fu_node))
432  {
433  current_fu->channels_type = GetPointer<functional_unit>(node)->channels_type;
434  }
435  if((GetPointer<functional_unit>(node) && !GetPointer<functional_unit>(node)->memory_ctrl_type.empty()) ||
436  GetPointer<functional_unit_template>(fu_node))
437  {
438  current_fu->memory_ctrl_type = GetPointer<functional_unit>(node)->memory_ctrl_type;
439  }
440  if((GetPointer<functional_unit>(node) && !GetPointer<functional_unit>(node)->bram_load_latency.empty()) ||
441  GetPointer<functional_unit_template>(fu_node))
442  {
443  current_fu->bram_load_latency = GetPointer<functional_unit>(node)->bram_load_latency;
444  }
445 
446  THROW_ASSERT(current_fu->characterization_timestamp <= GetPointer<functional_unit>(node)->characterization_timestamp,
447  STR(current_fu->characterization_timestamp) + " vs " +
448  STR(GetPointer<functional_unit>(node)->characterization_timestamp));
449  current_fu->characterization_timestamp = GetPointer<functional_unit>(node)->characterization_timestamp;
450 }
451 
452 bool library_manager::is_fu(const std::string& _name) const
453 {
454  return fu_map.count(_name);
455 }
456 
457 technology_nodeRef library_manager::get_fu(const std::string& _name) const
458 {
459  THROW_ASSERT(is_fu(_name), "functional unit " + _name + " not stored");
460  return fu_map.at(_name);
461 }
462 
464 {
465  return static_cast<unsigned int>(fu_map.size());
466 }
467 
468 void library_manager::set_info(unsigned int type, const std::string& information)
469 {
470  info[type] = information;
471 }
472 
474 {
475  info.clear();
476 }
477 
478 bool library_manager::is_info(unsigned int type) const
479 {
480  return info.find(type) != info.end();
481 }
482 
484 {
485  return !is_std;
486 }
487 
488 void library_manager::remove_fu(const std::string& _name)
489 {
490  if(fu_map.find(_name) == fu_map.end())
491  {
492  return;
493  }
494  fu_map.erase(_name);
495  erase_info();
496 }
497 
498 void library_manager::set_dont_use(const std::string& _name)
499 {
500  if(fu_map.find(_name) == fu_map.end())
501  {
502  return;
503  }
504  dont_use.insert(_name);
505 }
506 
508 {
509  return dont_use;
510 }
511 
513 {
514  return static_cast<unsigned int>(dont_use.size());
515 }
516 
517 void library_manager::remove_dont_use(const std::string& _name)
518 {
519  dont_use.erase(_name);
520 }
std::string get_value_type_str() const
Input function used to read the technology data structures.
std::string get_value() const
Get the value of this attribute.
bool has_list() const
void remove_dont_use(const std::string &name)
Set a cell to be used.
unsigned int get_value_type() const
Collect information about resource area.
std::map< std::string, attributeRef > attributes
attributes of the library
File containing functions and utilities to support the printing of debug messagges.
std::vector< attributeRef > content_list
refcount< attribute > attributeRef
bool is_std
flag to check if the library is standard (i.e., provided in input) or virtual
std::string pipe_parameters
comma separated string with the parameter for the different implementation of the pipeline...
std::string operation_name
name of the operation mappen on a given functional unit.
void remove_fu(const std::string &name)
std::string content
technology_nodeRef get_fu(const std::string &name) const
void set_info(unsigned int type, const std::string &information)
bool is_virtual() const
Check if the library is virtual or not.
exceptions managed by PandA
static void xload(const xml_element *node, const library_managerRef &LM, const ParameterConstRef &Param)
void xwrite(xml_element *rootnode)
time_infoRef time_m
class representing the timing information associated with this operation
Definition of hash function for EdgeDescriptor.
Definition: graph.hpp:1321
xml_text_node * add_child_text(const std::string &content)
Append a new text node.
Definition: xml_node.cpp:68
This class specifies the characteristic of a particular functional unit.
std::string portsize_parameters
comma separed string with the parameter for different portsize values.
void add(const technology_nodeRef &node)
std::string name
string identifier of the library
#define OUTPUT_LEVEL_MINIMUM
minimum debugging print is performed.
refcount< technology_node > technology_nodeRef
refcount definition of the class
#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
Definition: exceptions.hpp:300
#define STR(s)
Macro which performs a lexical_cast to a string.
void update(const technology_nodeRef &node)
fu_map_type fu_map
data-structure to identify the units that are contained into the library
void set_dont_use(const std::string &name)
Set a cell to be not used.
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. ...
unsigned int INT32
Definition: sha.h:28
void xwrite(xml_element *xml_node, const std::string &name)
bool bounded
flag to determine if the operation is bounded or not
size_t get_dont_use_num() const
~library_manager()
Destructor.
CustomOrderedSet< std::string > dont_use
xml_attribute * get_attribute(const std::string &name) const
Obtain the attribute with this name.
struct definition of the field attr on function_decl, field_decl, var_decl tree node.
Definition: tree_node.hpp:774
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
CustomOrderedSet< std::string > get_dont_use_cells() const
Return the cells not to be used for the synthesis.
This class describe a functional unit template.
bool is_fu(const std::string &name) const
int el
Definition: adpcm.c:105
virtual const std::string & get_name() const =0
Return the name of the technology node.
xml_text_node * get_child_text()
Get the first child text content node.
Definition: xml_node.hpp:272
std::string get_content() const
Get the text of this content node.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
void set_default_attributes()
Set the default attributes for the library.
std::map< unsigned int, std::string > info
files that provide information about the library
library_manager(ParameterConstRef Param, bool std=true)
Constructor.
this class is used to manage the command-line or XML options.
std::string get_content_str() const
constant strings
node_list const & get_children()
Obtain the list of child nodes.
Definition: xml_node.hpp:310
std::string get_library_name() const
value_t value_type
Class specification of the manager for each library.
#define PRINT_OUT_MEX(profLevel, curprofLevel, mex)
#define OUTPUT_LEVEL_VERBOSE
verbose debugging print is performed.
std::vector< technology_nodeRef > operation_vec
Type definition of a vector of functional_unit.
bool is_info(unsigned int type) const
virtual void xload(const xml_element *Enode, const technology_nodeRef owner, const ParameterConstRef Param)=0
Load a technology_node starting from an xml file.
static void convert_escaped(std::string &ioString)
Convert escaped characters.
Definition: xml_node.hpp:197
static void xload(const xml_element *EnodeC, std::vector< std::string > &ordered_attributes, std::map< std::string, attributeRef > &attributes)
attribute(const value_t _value_type, std::string _content)
#define DEBUG_LEVEL_VERBOSE
verbose debugging print is performed.
std::vector< std::string > ordered_attributes
xml_element * add_child_element(const std::string &name)
Add a child element to this node.
Definition: xml_node.cpp:54
size_t get_gate_count() const
xml_attribute * set_attribute(const std::string &name, const std::string &value)
Set the value of the attribute with this name, and optionally with this namespace.
const ParameterConstRef Param
class containing all the parameters
enum { FLOAT64=0, BOOLEAN, INT32, STRING } value_t
#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