PandA-2024.02
structural_objects.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  */
42 #include "structural_objects.hpp"
43 
44 #include "config_HAVE_ASSERTS.hpp"
45 #include "config_HAVE_TECHNOLOGY_BUILT.hpp"
46 #include "config_RELEASE.hpp"
47 
48 #include "HDL_manager.hpp"
49 #include "NP_functionality.hpp"
50 #include "behavioral_helper.hpp"
51 #include "custom_set.hpp"
52 #include "dbgPrintHelper.hpp"
53 #include "exceptions.hpp"
54 #include "library_manager.hpp"
55 #include "simple_indent.hpp"
56 #include "string_manipulation.hpp"
57 #include "structural_manager.hpp"
58 #include "technology_manager.hpp"
59 #include "technology_node.hpp"
60 #include "utility.hpp"
61 #include "xml_attribute.hpp"
62 #include "xml_element.hpp"
63 #include "xml_helper.hpp"
64 #include "xml_node.hpp"
65 #include "xml_text_node.hpp"
66 
67 #include <algorithm>
68 #include <boost/algorithm/string/replace.hpp>
69 #include <boost/iterator/iterator_facade.hpp>
70 #include <boost/iterator/iterator_traits.hpp>
71 #include <climits>
72 #include <iostream>
73 #include <list>
74 #include <memory>
75 #include <regex>
76 #include <utility>
77 
78 inline std::string legalize(const std::string& id)
79 {
80  // boost::replace_all(id, "[", "_");
81  // boost::replace_all(id, "]", "_");
82  // boost::replace_all(id, "\\", "s_");
83  return id;
84 }
85 
86 const char* structural_type_descriptor::s_typeNames[] = {"OTHER", "BOOL", "INT", "UINT",
87  "REAL", "USER", "VECTOR_BOOL", "VECTOR_INT",
88  "VECTOR_UINT", "VECTOR_REAL", "VECTOR_USER", "UNKNOWN"};
89 
90 const std::string structural_type_descriptor::get_name() const
91 {
92  for(int i = 0; i < UNKNOWN; i++)
93  {
94  if(type == i)
95  {
96  return std::string(s_typeNames[i]);
97  }
98  }
99  return "UNKNOWN";
100 }
101 
103 {
104  if(CE_XVM(type, Enode))
105  {
106  unsigned int i;
107  std::string type_string;
108  LOAD_XVFM(type_string, Enode, type);
109  for(i = 0; i < UNKNOWN; i++)
110  {
111  if(type_string == s_typeNames[i])
112  {
113  break;
114  }
115  }
116  this->type = s_type(i);
117  }
118  else
119  {
120  type = type_DEFAULT;
121  }
122  if(type == BOOL)
123  {
124  size = 1;
125  }
126  if(CE_XVM(size, Enode))
127  {
128  LOAD_XVM(size, Enode);
129  }
130  if(CE_XVM(vector_size, Enode))
131  {
132  LOAD_XVM(vector_size, Enode);
133  }
134  if(CE_XVM(id_type, Enode))
135  {
136  LOAD_XVM(id_type, Enode);
137  }
138  if(CE_XVM(treenode, Enode))
139  {
140  LOAD_XVM(treenode, Enode);
141  }
142  THROW_ASSERT(type != type_DEFAULT or id_type.size(), "Wrong type descriptor");
143 }
144 
146 {
147  xml_element* Enode = rootnode->add_child_element(get_kind_text());
148  if(type != type_DEFAULT)
149  {
150  WRITE_XNVM(type, s_typeNames[type], Enode);
151  }
152  if(size != size_DEFAULT)
153  {
154  WRITE_XVM(size, Enode);
155  }
157  {
158  WRITE_XVM(vector_size, Enode);
159  }
160  if(id_type != "")
161  {
162  WRITE_XVM(id_type, Enode);
163  }
165  {
166  WRITE_XVM(treenode, Enode);
167  }
168 }
169 
171 {
172  dest->id_type = id_type;
173  dest->type = type;
174  dest->size = size;
175  dest->vector_size = vector_size;
176  dest->treenode = treenode;
177 }
178 
179 void structural_type_descriptor::print(std::ostream& os) const
180 {
181  switch(type)
182  {
183  case BOOL:
184  {
185  THROW_ASSERT(size == 1 && vector_size == 0,
186  "bool type descriptor not correctly defined " + STR(size) + " | " + STR(vector_size));
187  os << "Bool {" << id_type << "} ";
188  if(treenode > 0)
189  {
190  os << "(@" << treenode << ") ";
191  }
192  break;
193  }
194  case INT:
195  {
196  THROW_ASSERT(size > 0 && vector_size == 0, "int type descriptor not correctly defined");
197  os << "Int {" << id_type << "} ";
198  if(treenode > 0)
199  {
200  os << "(@" << treenode << ") ";
201  }
202  os << "size=" << size << " ";
203  break;
204  }
205  case UINT:
206  {
207  THROW_ASSERT(size > 0 && vector_size == 0, "unsigned int type descriptor not correctly defined");
208  os << "Unsigned Int {" << id_type << "} ";
209  if(treenode > 0)
210  {
211  os << "(@" << treenode << ") ";
212  }
213  os << "size=" << size << " ";
214  break;
215  }
216  case REAL:
217  {
218  THROW_ASSERT((size > 0 && vector_size == 0) || (size == 1 && (vector_size == 32 || vector_size == 64 ||
219  vector_size == 96 || vector_size == 128)),
220  "real type descriptor not correctly defined " + STR(size) + " " + STR(vector_size));
221  os << "Real {" << id_type << "} ";
222  if(treenode > 0)
223  {
224  os << "(@" << treenode << ") ";
225  }
226  os << "size=" << size << " ";
227  break;
228  }
229  case USER:
230  {
231  os << "User type {" << id_type << "} ";
232  if(treenode > 0)
233  {
234  os << "(@" << treenode << ") ";
235  }
236  os << "size=" << size << " ";
237  break;
238  }
239  case VECTOR_BOOL:
240  {
241  THROW_ASSERT(size == 1 && vector_size > 0, "bool vector type descriptor not correctly defined");
242  os << "Bool Vector [" << vector_size << "] {" << id_type << "} ";
243  if(treenode > 0)
244  {
245  os << "(@" << treenode << ") ";
246  }
247  break;
248  }
249  case VECTOR_INT:
250  {
251  THROW_ASSERT(size > 0 && vector_size > 0, "int vector type descriptor not correctly defined");
252  os << "Int Vector [" << vector_size << "] {" << id_type << "} ";
253  if(treenode > 0)
254  {
255  os << "(@" << treenode << ") ";
256  }
257  os << "size=" << size << " ";
258  break;
259  }
260  case VECTOR_UINT:
261  {
262  THROW_ASSERT(size > 0 && vector_size > 0, "unsigned int vector type descriptor not correctly defined");
263  os << "Unsigned Int Vector [" << vector_size << "] {" << id_type << "} ";
264  if(treenode > 0)
265  {
266  os << "(@" << treenode << ") ";
267  }
268  os << "size=" << size << " ";
269  break;
270  }
271  case VECTOR_REAL:
272  {
273  THROW_ASSERT(size > 0 && vector_size > 0, "real vector type descriptor not correctly defined");
274  os << "Real Vector [" << vector_size << "] {" << id_type << "} ";
275  if(treenode > 0)
276  {
277  os << "(@" << treenode << ") ";
278  }
279  os << "size=" << size << " ";
280  break;
281  }
282  case VECTOR_USER:
283  {
284  THROW_ASSERT(vector_size > 0, "Vector User type descriptor not correctly defined");
285  os << "User Vector type [" << vector_size << "] {" << id_type << "} ";
286  if(treenode > 0)
287  {
288  os << "(@" << treenode << ") ";
289  }
290  os << "size=" << size << " ";
291  break;
292  }
293  case OTHER:
294  os << "Other type {" << id_type << "} ";
295  if(treenode > 0)
296  {
297  os << "(@" << treenode << ") ";
298  }
299  break;
300  case UNKNOWN:
301  default:
302  THROW_ERROR("Not initialized type");
303  }
304 }
305 
306 structural_type_descriptor::structural_type_descriptor(const std::string& type_name, unsigned long long _vector_size)
308 {
310  type = UNKNOWN;
311  size = size_DEFAULT;
312  if(_vector_size == 0)
313  {
314  if(type_name == "bool")
315  {
316  type = BOOL;
317  size = 1;
318  }
319  else if(type_name == "int")
320  {
321  type = INT;
322  size = 32;
323  }
324  else if(type_name == "unsigned int")
325  {
326  type = UINT;
327  size = 32;
328  }
329  else if(type_name == "float")
330  {
331  type = REAL;
332  size = 32;
333  }
334  else if(type_name == "double")
335  {
336  type = REAL;
337  size = 64;
338  }
339  else if(type_name == "long double")
340  {
341  type = REAL;
342  size = 96;
343  }
344  else if(type_name == "long long double")
345  {
346  type = REAL;
347  size = 128;
348  }
349  else
350  {
351  THROW_ERROR("not supported type name");
352  }
353  }
354  else
355  {
356  if(type_name == "bool")
357  {
358  type = VECTOR_BOOL;
359  size = 1;
360  }
361  else if(type_name == "int")
362  {
363  type = VECTOR_INT;
364  size = 32;
365  }
366  else if(type_name == "unsigned int")
367  {
368  type = VECTOR_UINT;
369  size = 32;
370  }
371  else if(type_name == "float")
372  {
373  type = VECTOR_REAL;
374  size = 32;
375  }
376  else if(type_name == "double")
377  {
378  type = VECTOR_REAL;
379  size = 64;
380  }
381  else if(type_name == "long double")
382  {
383  type = VECTOR_REAL;
384  size = 96;
385  }
386  else if(type_name == "long long double")
387  {
388  type = VECTOR_REAL;
389  size = 128;
390  }
391  else
392  {
393  THROW_ERROR("not supported type name");
394  }
395  }
396 }
397 
399 {
400  unsigned int type_index = helper->get_type(index);
402  type = UNKNOWN;
403  size = size_DEFAULT;
405  treenode = type_index;
406  const unsigned int unqualified_type = helper->GetUnqualified(type_index);
407  if(unqualified_type == 0)
408  {
409  id_type = helper->print_type(type_index);
410  }
411  else
412  {
413  id_type = helper->print_type(unqualified_type);
414  }
415  size = helper->get_size(index);
416  vector_size = 0;
417  if(helper->is_a_pointer(index))
418  {
419  type = VECTOR_BOOL;
420  vector_size = size;
421  size = 1;
422  }
423  else if(helper->is_an_array(index) && !helper->is_a_struct(index) && !helper->is_an_union(index))
424  {
425  const auto element_type = helper->GetElements(type_index);
426  const auto element_size = helper->get_size(element_type);
427  vector_size = size / element_size;
428  size = element_size;
429  if(helper->is_bool(element_type) || helper->is_a_complex(index))
430  {
431  type = VECTOR_BOOL;
432  }
433  else if(helper->is_int(element_type))
434  {
435  type = VECTOR_INT;
436  }
437  else if(helper->is_unsigned(element_type))
438  {
439  type = VECTOR_UINT;
440  }
441  else if(helper->is_real(element_type))
442  {
443  type = VECTOR_REAL;
444  }
445  else
446  {
447  THROW_ERROR("vector user type not supported");
448  type = VECTOR_USER;
449  }
450  }
451  else if(helper->is_a_vector(index))
452  {
453  const auto element_type = helper->GetElements(type_index);
454  const auto element_size = helper->get_size(element_type);
455  vector_size = size / element_size;
456  size = element_size;
457  if(helper->is_bool(element_type) || helper->is_a_complex(index))
458  {
459  type = VECTOR_BOOL;
460  }
461  else if(helper->is_int(element_type))
462  {
463  type = VECTOR_INT;
464  }
465  else if(helper->is_unsigned(element_type))
466  {
467  type = VECTOR_UINT;
468  }
469  else if(helper->is_real(element_type))
470  {
471  type = VECTOR_REAL;
472  }
473  else
474  {
475  THROW_ERROR("vector user type not supported");
476  type = VECTOR_USER;
477  }
478  }
479  else
480  {
481  if(helper->is_bool(index))
482  {
483  type = BOOL;
484  }
485  else if(helper->is_int(index))
486  {
487  type = INT;
488  }
489  else if(helper->is_unsigned(index))
490  {
491  type = UINT;
492  }
493  else if(helper->is_real(index))
494  {
495  type = REAL;
496  }
497  else if(helper->is_a_complex(index))
498  {
499  type = VECTOR_BOOL;
500  vector_size = size;
501  size = 1;
502  }
503  else
504  {
505  THROW_ERROR("user type not supported: " + STR(index) + "-" + id_type);
506  type = USER;
507  }
508  }
509 }
510 
513 {
514  if((src_type->type == dest_type->type && src_type->type != USER && src_type->type != UNKNOWN) ||
515  (src_type->type == BOOL && (dest_type->type == INT || dest_type->type == UINT ||
516  (dest_type->type == VECTOR_BOOL && dest_type->vector_size == 1))) ||
517  (dest_type->type == BOOL && (src_type->type == INT || src_type->type == UINT ||
518  (src_type->type == VECTOR_BOOL && src_type->vector_size == 1))) ||
519  (src_type->type == VECTOR_BOOL &&
520  (dest_type->type == INT || dest_type->type == UINT || dest_type->type == REAL)) ||
521  (dest_type->type == VECTOR_BOOL && (src_type->type == INT || src_type->type == UINT || src_type->type == REAL)) ||
522  (src_type->type == VECTOR_BOOL && (dest_type->type == VECTOR_INT || dest_type->type == VECTOR_UINT) &&
523  (src_type->size * src_type->vector_size == dest_type->size * dest_type->vector_size)) ||
524  (dest_type->type == VECTOR_BOOL && (src_type->type == VECTOR_INT || src_type->type == VECTOR_UINT) &&
525  (src_type->size * src_type->vector_size == dest_type->size * dest_type->vector_size)) ||
526  (src_type->id_type == dest_type->id_type && src_type->id_type != "") ||
527  (src_type->treenode == dest_type->treenode && src_type->type > 0) ||
528 #ifndef NDEBUG
529  // Add some SystemC specialization
530  (src_type->id_type.find("tlm_fifo<") != std::string::npos &&
531  (dest_type->id_type.find("tlm_blocking_put_if<") != std::string::npos ||
532  dest_type->id_type.find("tlm_blocking_get_if<") != std::string::npos)) ||
533  (dest_type->id_type.find("tlm_fifo<") != std::string::npos &&
534  (src_type->id_type.find("tlm_blocking_put_if<") != std::string::npos ||
535  src_type->id_type.find("tlm_blocking_get_if<") != std::string::npos))
536 #else
537  // compatibility verified by the gcc compiler!
538  (src_type->treenode != treenode_DEFAULT && dest_type->treenode != treenode_DEFAULT)
539 #endif
540  )
541  return true;
542  else
543  {
544  src_type->print(std::cout);
545  dest_type->print(std::cout);
546  THROW_WARNING(std::string("Different types are used " + src_type->id_type + " -- " + dest_type->id_type));
547  return false;
548  }
549 }
550 
552 
554 
556 {
557  switch(in)
558  {
559  case component_o_K:
560  return "M";
561  case channel_o_K:
562  return "C";
563  case constant_o_K:
564  return "c";
565  case bus_connection_o_K:
566  return "B";
567  case signal_o_K:
568  return "S";
569  case signal_vector_o_K:
570  return "S";
571  case port_o_K:
572  return "P";
573  case port_vector_o_K:
574  return "P";
575  case event_o_K:
576  return "E";
577  case data_o_K:
578  return "D";
579  case action_o_K:
580  return "A";
581  default:
582  THROW_UNREACHABLE("");
583  }
584  return "";
585 }
586 
588  : owner(o),
590  black_box(o ? o->black_box : black_box_DEFAULT),
591  debug_level(debug)
592 {
593 }
594 
596 {
597  return owner.lock();
598 }
599 
601 {
602  owner = new_owner;
603 }
604 
605 #if HAVE_TECHNOLOGY_BUILT
606 void structural_object::add_attribute(const std::string& name, const attributeRef& attribute)
607 {
608  if(std::find(attribute_list.begin(), attribute_list.end(), name) == attribute_list.end())
609  {
610  attribute_list.push_back(name);
611  }
612  attributes[name] = attribute;
613 }
614 
615 attributeRef structural_object::get_attribute(const std::string& name) const
616 {
617  THROW_ASSERT(attributes.find(name) != attributes.end(), "attribute " + name + " does not exist");
618  return attributes.find(name)->second;
619 }
620 
621 const std::vector<std::string>& structural_object::get_attribute_list() const
622 {
623  return attribute_list;
624 }
625 #endif
626 
628 {
629  treenode = n;
630 }
631 
633 {
634  return treenode;
635 }
636 
637 void structural_object::set_id(const std::string& s)
638 {
639  id = s;
640 }
641 
642 const std::string& structural_object::get_id() const
643 {
644  return id;
645 }
646 
648 {
649  type = s;
650 }
651 
653 {
654  THROW_ASSERT(type, "Structural type descriptor not available for " + get_id());
655  return type;
656 }
657 
658 void structural_object::type_resize(unsigned long long new_bit_size)
659 {
660  switch(type->type)
661  {
665  {
666  if(type->size < new_bit_size)
667  {
668  type->size = new_bit_size;
669  }
670  break;
671  }
673  {
674  if(type->vector_size < new_bit_size)
675  {
676  type->vector_size = new_bit_size;
677  }
678  break;
679  }
681  {
682  THROW_ASSERT(new_bit_size == 1,
683  "BOOL only supports single bit values: " + std::to_string(new_bit_size) + " - " + get_path());
684  type->size = new_bit_size;
685  break;
686  }
694  default:
695  THROW_ERROR("Not correct resizing " + get_path() + " (" + type->id_type + ") New size " +
696  std::to_string(new_bit_size));
697  }
698 }
699 
700 void structural_object::type_resize(unsigned long long new_bit_size, unsigned long long new_vec_size)
701 {
702  switch(type->type)
703  {
707  {
708  if(type->size < new_bit_size)
709  {
710  type->size = new_bit_size;
711  }
712  if(type->vector_size < new_vec_size)
713  {
714  type->vector_size = new_vec_size;
715  }
716  break;
717  }
719  {
720  if(type->vector_size < new_bit_size * new_vec_size)
721  {
722  type->vector_size = new_bit_size * new_vec_size;
723  }
724  break;
725  }
728  {
729  if(type->size < new_bit_size * new_vec_size)
730  {
731  type->size = new_bit_size * new_vec_size;
732  }
733  break;
734  }
741  default:
742  THROW_ERROR("Not correct resizing " + get_path() + " (" + type->id_type + ") New size " +
743  std::to_string(new_bit_size) + "(" + STR(new_vec_size) + ")");
744  }
745 }
746 
748 {
750  dest->id = id;
752  type->copy(dest->type);
753  dest->treenode = treenode;
754  dest->black_box = black_box;
755  dest->debug_level = debug_level;
756  dest->default_parameters = default_parameters;
757  dest->parameters = parameters;
758 
759 #if HAVE_TECHNOLOGY_BUILT
760  dest->attribute_list = attribute_list;
761  dest->attributes = attributes;
762 #endif
763 }
764 
766 {
767  black_box = bb;
768 }
769 
771 {
772  return black_box;
773 }
774 
775 void structural_object::SetParameter(const std::string& name, const std::string& value)
776 {
778  "Parameter " + name + " does not exist in " + get_typeRef()->id_type);
779  parameters[name] = value;
780 }
781 
782 std::string structural_object::GetParameter(std::string name) const
783 {
784  if(parameters.find(name) != parameters.end())
785  {
786  return parameters.at(name);
787  }
789  "Parameter " + name + " has no value associated for unit " + get_typeRef()->id_type);
790  return default_parameters.at(name);
791 }
792 
793 void structural_object::AddParameter(const std::string& name, const std::string& default_value)
794 {
795  THROW_ASSERT(default_parameters.find(name) == default_parameters.end() or
796  default_parameters.at(name) == default_value,
797  "Parameter " + name + " already added. Old default: " + default_parameters.at(name) +
798  " New default: " + default_value);
799  default_parameters[name] = default_value;
800 }
801 
802 std::string structural_object::GetDefaultParameter(std::string name) const
803 {
804  THROW_ASSERT(default_parameters.find(name) != default_parameters.end(), "Parameter " + name + " does not exist");
805  return default_parameters.at(name);
806 }
807 
809 {
811  for(const auto& default_parameter : default_parameters)
812  {
813  ret[default_parameter.first] = default_parameter.second;
814  }
815  for(const auto& parameter : parameters)
816  {
817  ret[parameter.first] = parameter.second;
818  }
819  return ret;
820 }
821 
822 #if HAVE_TECHNOLOGY_BUILT
823 structural_objectRef module::get_generic_object(const technology_managerConstRef TM) const
824 {
825  const auto module_type = get_typeRef()->id_type;
826  technology_nodeRef tn = TM->get_fu(module_type, TM->get_library(module_type));
827  if(tn->get_kind() == functional_unit_K)
828  {
829  return GetPointer<functional_unit>(tn)->CM->get_circ();
830  }
831  else if(tn->get_kind() == functional_unit_template_K &&
832  GetPointer<functional_unit>(GetPointer<functional_unit_template>(tn)->FU))
833  {
834  return GetPointer<functional_unit>(GetPointer<functional_unit_template>(tn)->FU)->CM->get_circ();
835  }
836  else
837  {
838  THROW_UNREACHABLE("Unexpected pattern");
839  }
840  return structural_objectRef();
841 }
842 
843 structural_type_descriptor::s_type module::get_parameter_type(const technology_managerConstRef TM,
844  const std::string& name) const
845 {
846  const auto module_type = get_generic_object(TM);
847  const auto default_value = module_type->GetDefaultParameter(name);
848  if(default_value.substr(0, 2) == "\"\"" and default_value.substr(default_value.size() - 2, 2) == "\"\"")
849  {
851  }
852  if(default_value.front() == '\"' and default_value.back() == '\"')
853  {
854  const auto content_string = default_value.substr(1, default_value.size() - 2);
855  for(const auto character : content_string)
856  {
857  if(character != '0' and character != '1')
858  {
860  }
861  }
863  }
864  if(std::regex_search(default_value, std::regex("^\\d+\\.\\d+$")))
865  {
867  }
868  if(default_value.front() >= '0' and default_value.front() <= '9')
869  {
871  }
872  if(default_value == "-1")
873  {
875  }
876  THROW_UNREACHABLE("Value of " + name + " is " + default_value);
877  if(get_owner() and GetPointer<const module>(get_owner()))
878  {
879  return GetPointer<const module>(GetPointer<const module>(get_owner())->get_generic_object(TM))
880  ->get_parameter_type(TM, name);
881  }
883 }
884 #endif
885 
886 bool structural_object::ExistsParameter(std::string name) const
887 {
888  return default_parameters.count(name);
889 }
890 
892 {
894  if(CE_XVM(id, Enode))
895  {
896  LOAD_XVM(id, Enode);
897  }
898  if(CE_XVM(treenode, Enode))
899  {
900  LOAD_XVM(treenode, Enode);
901  }
902  if(CE_XVM(black_box, Enode))
903  {
904  LOAD_XVM(black_box, Enode);
905  }
906  // Recourse through child nodes
907 #if HAVE_ASSERTS
908  bool has_structural_type_descriptor = false;
909 #endif
910  const xml_node::node_list list = Enode->get_children();
911  for(const auto& iter : list)
912  {
913  const auto* EnodeC = GetPointer<const xml_element>(iter);
914  if(!EnodeC)
915  {
916  continue;
917  }
918  if(EnodeC->get_name() == GET_CLASS_NAME(structural_type_descriptor))
919  {
921  type->xload(EnodeC, type);
922 #if HAVE_ASSERTS
923  has_structural_type_descriptor = true;
924 #endif
925  }
926  else if(EnodeC->get_name() == "parameter")
927  {
928  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - Parameter specification");
929  std::string name;
930  LOAD_XVM(name, EnodeC);
931  const xml_text_node* text = EnodeC->get_child_text();
932  if(!text)
933  {
934  THROW_ERROR("parameter definition is missing");
935  }
936  std::string default_value = text->get_content();
937  xml_node::convert_escaped(default_value);
938  default_parameters[name] = default_value;
939  }
940  }
941  THROW_ASSERT(has_structural_type_descriptor,
942  "A structural object has to have a type." + std::to_string(Enode->get_line()));
943 }
944 
946 {
947  WRITE_XVM(id, Enode);
948  std::string path = get_path();
949  WRITE_XVM(path, Enode);
951  {
952  WRITE_XVM(treenode, Enode);
953  }
955  {
956  WRITE_XVM(black_box, Enode);
957  }
958  if(type)
959  {
960  type->xwrite(Enode);
961  }
962  if(!default_parameters.empty())
963  {
964  for(const auto& default_parameter : default_parameters)
965  {
966  xml_element* Enode_parameter = Enode->add_child_element("parameter");
967  WRITE_XNVM2("name", default_parameter.first, Enode_parameter);
968  Enode_parameter->add_child_text(STR(default_parameter.second));
969  }
970  }
971 }
972 
973 #if HAVE_TECHNOLOGY_BUILT
974 void structural_object::xwrite_attributes(xml_element*, const technology_nodeRef&)
975 {
976 }
977 #endif
978 
979 void structural_object::print(std::ostream& os) const
980 {
981  os << "SO: " << id << " {" << type << "}";
982  if(treenode > 0)
983  {
984  os << " (@" << treenode << ")";
985  }
986  os << (black_box ? " (BLACK BOX)" : "");
987  os << " Path: " << get_path();
988  PP(os, "\n");
989 }
990 
991 const std::string structural_object::get_path() const
992 {
993  if(!get_owner())
994  {
995  return get_id();
996  }
997  else
998  {
999  return get_owner()->get_path() + HIERARCHY_SEPARATOR + get_id();
1000  }
1001 }
1002 
1003 port_o::port_o(int _debug_level, const structural_objectRef o, port_direction _dir, so_kind _port_type)
1004  : structural_object(_debug_level, o),
1005  dir(_dir),
1006  end(NONE),
1007  pi(port_interface::PI_DEFAULT),
1008  aligment(port_interface_alignment_DEFAULT),
1009  is_var_args(is_var_args_DEFAULT),
1010  is_clock(is_clock_DEFAULT),
1011  is_extern(is_extern_DEFAULT),
1012  is_global(is_global_DEFAULT),
1013  is_reverse(is_reverse_DEFAULT),
1014  is_memory(is_memory_DEFAULT),
1015  is_slave(is_slave_DEFAULT),
1016  is_master(is_master_DEFAULT),
1017  is_data_bus(is_data_bus_DEFAULT),
1018  is_addr_bus(is_addr_bus_DEFAULT),
1019  is_size_bus(is_size_bus_DEFAULT),
1020  is_tag_bus(is_tag_bus_DEFAULT),
1021  is_doubled(is_doubled_DEFAULT),
1022  is_halved(is_halved_DEFAULT),
1023  is_critical(is_critical_DEFAULT),
1024  lsb(0),
1025  port_type(_port_type)
1026 {
1027 #if HAVE_TECHNOLOGY_BUILT
1028  std::string direction;
1029  if(_dir == IN)
1030  {
1031  direction = "input";
1032  }
1033  else
1034  {
1035  direction = "output";
1036  }
1037  attributeRef dir_attribute(new attribute(attribute::STRING, direction));
1038  add_attribute("direction", dir_attribute);
1039 #endif
1040 }
1041 
1043 {
1044  THROW_ASSERT(s, get_path() + ": NULL object received: ");
1045  THROW_ASSERT(
1046  (get_kind() == port_o_K &&
1047  (s->get_kind() == port_o_K || s->get_kind() == signal_o_K || s->get_kind() == constant_o_K)) ||
1049  get_path() + ": port cannot be connected to an object of type: " + std::string(s->get_kind_text()));
1050  for(auto& connected_object : connected_objects)
1051  {
1052  if(connected_object.lock() == s)
1053  {
1054  return;
1055  }
1056  THROW_ASSERT(
1057  !(((s->get_kind() == signal_o_K and connected_object.lock()->get_kind() == signal_o_K) ||
1058  (s->get_kind() == signal_vector_o_K and connected_object.lock()->get_kind() == signal_vector_o_K)) and
1059  s->get_owner() == connected_object.lock()->get_owner()),
1060  "The port " + get_path() + " can have only one signal. " + s->get_path() + " and " +
1061  connected_object.lock()->get_path());
1062  }
1063  connected_objects.push_back(s);
1064 }
1065 
1067 {
1068  THROW_ASSERT(s, get_path() + ": NULL object received");
1069  auto del = connected_objects.begin();
1070  for(; del != connected_objects.end(); ++del)
1071  {
1072  if((*del).lock() == s)
1073  {
1074  break;
1075  }
1076  }
1077  if(del != connected_objects.end())
1078  {
1079  connected_objects.erase(del);
1080  }
1081 }
1082 
1084 {
1085  THROW_ASSERT(s, "NULL object received");
1086  if(connected_objects.size() == 0)
1087  {
1088  return false;
1089  }
1090  auto del = connected_objects.begin();
1091  for(; del != connected_objects.end(); ++del)
1092  {
1093  if((*del).lock() == s)
1094  {
1095  return true;
1096  }
1097  }
1098  return false;
1099 }
1100 
1102 {
1103  structural_objectRef sigObj;
1104  for(const auto& connected_object : connected_objects)
1105  {
1106  if(connected_object.lock()->get_kind() == signal_o_K || connected_object.lock()->get_kind() == signal_vector_o_K)
1107  {
1108  THROW_ASSERT(!sigObj or sigObj->get_owner() != connected_object.lock()->get_owner(),
1109  "Multiple signal connected to the same port: " + get_path());
1110  sigObj = connected_object.lock();
1111  }
1112  }
1113  return sigObj;
1114 }
1115 
1117 {
1119  bool existing = false;
1120  for(auto del = connected_objects.begin(); del != connected_objects.end();)
1121  {
1122  auto del_curr = del;
1123  ++del;
1124  if(del_curr->lock() == new_conn)
1125  {
1126  existing = true;
1127  }
1128  else if(del_curr->lock() == old_conn)
1129  {
1130  removed.insert(del_curr);
1131  }
1132  else if(del_curr->lock()->get_kind() == signal_o_K and new_conn->get_kind() == signal_o_K)
1133  {
1134  THROW_ERROR("Multiple signals for object: " + get_path());
1135  }
1136  }
1137  if(existing)
1138  {
1139  auto deli = removed.begin();
1140  for(; deli != removed.end(); ++deli)
1141  {
1142  connected_objects.erase(*deli);
1143  }
1144  }
1145  else
1146  {
1147  for(auto& connected_object : connected_objects)
1148  {
1149  if(connected_object.lock() == old_conn)
1150  {
1151  connected_object = new_conn;
1152  }
1153  }
1154  }
1155 }
1156 
1158 {
1159  THROW_ASSERT(n < connected_objects.size(), "index out of range");
1160  return connected_objects[n].lock();
1161 }
1162 
1163 unsigned int port_o::get_connections_size() const
1164 {
1165  return static_cast<unsigned int>(connected_objects.size());
1166 }
1167 
1169 {
1170  return dir;
1171 }
1172 
1174 {
1175  dir = _dir;
1176  for(const auto& p : ports)
1177  {
1178  GetPointer<port_o>(p)->set_port_direction(_dir);
1179  }
1180 }
1181 
1183 {
1184  return end;
1185 }
1186 
1188 {
1189  end = _end;
1190 }
1191 
1193 {
1194  return pi;
1195 }
1196 
1198 {
1199  pi = _pi;
1200 }
1201 
1202 unsigned int port_o::get_port_alignment() const
1203 {
1204  return aligment;
1205 }
1206 
1207 void port_o::set_port_alignment(unsigned int algn)
1208 {
1209  aligment = algn;
1210 }
1211 
1213 {
1214  is_var_args = c;
1215 }
1216 
1218 {
1219  return is_var_args;
1220 }
1221 
1223 {
1224  is_clock = c;
1225 }
1226 
1228 {
1229  return is_clock;
1230 }
1231 
1233 {
1234  is_extern = c;
1235 }
1236 
1238 {
1239  return is_extern;
1240 }
1241 
1242 void port_o::set_bus_bundle(const std::string& name)
1243 {
1244  bus_bundle = name;
1245 }
1246 
1247 std::string port_o::get_bus_bundle() const
1248 {
1249  return bus_bundle;
1250 }
1251 
1253 {
1254  is_global = c;
1255 }
1256 
1258 {
1259  return is_global;
1260 }
1261 
1263 {
1264  is_memory = c;
1265 }
1266 
1268 {
1269  return is_memory;
1270 }
1271 
1273 {
1274  is_slave = c;
1275 }
1276 
1278 {
1279  return is_slave;
1280 }
1281 
1283 {
1284  is_master = c;
1285 }
1286 
1288 {
1289  return is_master;
1290 }
1291 
1293 {
1294  is_data_bus = c;
1295 }
1296 
1298 {
1299  return is_data_bus;
1300 }
1301 
1303 {
1304  is_addr_bus = c;
1305 }
1306 
1308 {
1309  return is_addr_bus;
1310 }
1311 
1313 {
1314  is_size_bus = c;
1315 }
1316 
1318 {
1319  return is_size_bus;
1320 }
1321 
1323 {
1324  is_tag_bus = c;
1325 }
1326 
1328 {
1329  return is_tag_bus;
1330 }
1331 
1333 {
1334  is_doubled = c;
1335 }
1336 
1338 {
1339  return is_doubled;
1340 }
1341 
1343 {
1344  is_halved = c;
1345 }
1346 
1348 {
1349  return is_halved;
1350 }
1351 
1352 structural_objectRef port_o::find_bounded_object(const structural_objectConstRef f_owner) const
1353 {
1354  THROW_ASSERT(get_owner(), "The port has to have an owner " + get_id());
1355  // THROW_ASSERT(get_owner()->get_owner(), "The owner of the port has to have an owner " + get_id());
1357  "The owner of the port_vector has to have an owner " + get_id());
1358  THROW_ASSERT(get_kind() == port_o_K || get_kind() == port_vector_o_K, "Expected a port got something of different");
1360  unsigned int port_count = 0;
1361  structural_objectRef _owner;
1362  if(get_owner()->get_kind() == port_vector_o_K)
1363  {
1364  _owner = get_owner()->get_owner();
1365  }
1366  else
1367  {
1368  _owner = get_owner();
1369  }
1370 
1371  for(const auto& connected_object : connected_objects)
1372  {
1373  if(f_owner)
1374  {
1375  if(connected_object.lock()->get_kind() == port_o_K || connected_object.lock()->get_kind() == signal_o_K ||
1376  connected_object.lock()->get_kind() == constant_o_K)
1377  {
1378  if(connected_object.lock()->get_owner()->get_kind() == port_vector_o_K and
1379  connected_object.lock()->get_owner()->get_owner() != f_owner)
1380  {
1381  continue;
1382  }
1383  if((connected_object.lock()->get_owner()->get_kind() != port_vector_o_K and
1384  connected_object.lock()->get_owner() != f_owner))
1385  {
1386  continue;
1387  }
1388  }
1389  else if(connected_object.lock()->get_owner()->get_kind() == port_vector_o_K ||
1390  connected_object.lock()->get_owner()->get_kind() == signal_vector_o_K)
1391  {
1392  if(connected_object.lock()->get_owner()->get_owner() != f_owner)
1393  {
1394  continue;
1395  }
1396  }
1397  }
1398  THROW_ASSERT(connected_object.lock(), "");
1399 
1400  if(connected_object.lock()->get_owner() == _owner->get_owner())
1401  {
1402  res = connected_object.lock();
1403  port_count++;
1404  }
1405  else if((connected_object.lock()->get_owner()->get_kind() == port_vector_o_K ||
1406  connected_object.lock()->get_owner()->get_kind() == signal_vector_o_K) and
1407  (connected_object.lock()->get_owner()->get_owner() == _owner->get_owner() ||
1408  connected_object.lock()->get_owner()->get_owner() == _owner->get_owner()->get_owner()))
1409  {
1410  res = connected_object.lock();
1411  port_count++;
1412  }
1413  else if(connected_object.lock()->get_kind() == constant_o_K)
1414  {
1415  res = connected_object.lock();
1416  port_count++;
1417  }
1418  }
1419  if(!port_count)
1420  {
1421  return res;
1422  }
1423 
1424  if(port_count > 1)
1425  {
1426  INDENT_DBG_MEX(0, 0, "Too many bindings to " + get_path());
1427 #ifndef NDEBUG
1428  for(const auto& connected_object : connected_objects)
1429  {
1430  INDENT_DBG_MEX(0, 0, "---" + connected_object.lock()->get_path());
1431  }
1432 #endif
1433  THROW_UNREACHABLE("");
1434  }
1435  return res;
1436 }
1437 
1439 {
1440  THROW_ASSERT(get_owner() && key->get_owner(), "Something went wrong!");
1441  switch(key->get_kind())
1442  {
1443  case signal_o_K:
1444  {
1445  auto* conn = GetPointer<signal_o>(key);
1446  for(unsigned int k = 0; k < conn->get_connected_objects_size(); k++)
1447  {
1448  if(conn->get_port(k)->get_id() == get_id())
1449  {
1450  return get_owner()->find_isomorphic(conn->get_port(k)->get_owner())->find_isomorphic(key);
1451  }
1452  }
1453  THROW_ERROR("Something went wrong!");
1454  break;
1455  }
1456  case component_o_K:
1457  case channel_o_K:
1458  {
1459  THROW_ASSERT(key->get_id() == get_owner()->get_id(), "Something went wrong!");
1460  return get_owner();
1461  }
1462  case port_o_K:
1463  {
1464  for(const auto& port : ports)
1465  {
1466  if(port->get_id() == key->get_id())
1467  {
1468  return port;
1469  }
1470  }
1471  break;
1472  }
1473  case action_o_K:
1474  case bus_connection_o_K:
1475  case constant_o_K:
1476  case data_o_K:
1477  case event_o_K:
1478  case port_vector_o_K:
1479  case signal_vector_o_K:
1480  default:
1481  THROW_ERROR("Something went wrong!");
1482  }
1483  return structural_objectRef();
1484 }
1485 
1486 structural_objectRef port_o::find_member(const std::string& _id, so_kind _type, const structural_objectRef _owner) const
1487 {
1488  switch(_type)
1489  {
1490  case channel_o_K:
1491  case constant_o_K:
1492  case signal_o_K:
1493  case signal_vector_o_K:
1494  case port_o_K:
1495  case port_vector_o_K:
1496  {
1497  for(const auto& connected_object : connected_objects)
1498  {
1499  THROW_ASSERT(port_type == port_o_K || port_type == port_vector_o_K, "inconsistently organized port");
1500  if(connected_object.lock()->get_kind() == _type && connected_object.lock()->get_id() == _id &&
1501  connected_object.lock()->get_owner() == _owner)
1502  {
1503  return connected_object.lock();
1504  }
1505  }
1506  for(const auto& port : ports)
1507  {
1508  if(port->get_id() == _id && port->get_owner() == _owner)
1509  {
1510  return port;
1511  }
1512  }
1513  break;
1514  }
1515  case action_o_K:
1516  case component_o_K:
1517  case bus_connection_o_K:
1518  case data_o_K:
1519  case event_o_K:
1520  default:
1521  THROW_ERROR("Structural object not foreseen");
1522  }
1523  return structural_objectRef();
1524 }
1525 
1527 {
1530  GetPointer<port_o>(dest)->dir = dir;
1531  GetPointer<port_o>(dest)->end = end;
1532  GetPointer<port_o>(dest)->pi = pi;
1533  GetPointer<port_o>(dest)->aligment = aligment;
1534  GetPointer<port_o>(dest)->bus_bundle = bus_bundle;
1535  GetPointer<port_o>(dest)->size_parameter = size_parameter;
1536  GetPointer<port_o>(dest)->is_var_args = is_var_args;
1537  GetPointer<port_o>(dest)->is_clock = is_clock;
1538  GetPointer<port_o>(dest)->is_extern = is_extern;
1539  GetPointer<port_o>(dest)->is_global = is_global;
1540  GetPointer<port_o>(dest)->is_memory = is_memory;
1541  GetPointer<port_o>(dest)->is_slave = is_slave;
1542  GetPointer<port_o>(dest)->is_master = is_master;
1543  GetPointer<port_o>(dest)->is_data_bus = is_data_bus;
1544  GetPointer<port_o>(dest)->is_addr_bus = is_addr_bus;
1545  GetPointer<port_o>(dest)->is_size_bus = is_size_bus;
1546  GetPointer<port_o>(dest)->is_tag_bus = is_tag_bus;
1547  GetPointer<port_o>(dest)->is_doubled = is_doubled;
1548  GetPointer<port_o>(dest)->is_halved = is_halved;
1549  GetPointer<port_o>(dest)->is_critical = is_critical;
1550  GetPointer<port_o>(dest)->is_reverse = is_reverse;
1551  if(GetPointer<port_o>(dest)->ports.size() == ports.size())
1552  {
1553  unsigned index = 0;
1554  for(const auto& i : ports)
1555  {
1556  structural_objectRef port = GetPointer<port_o>(dest)->get_port(index);
1557  i->copy(port);
1558  ++index;
1559  }
1560  }
1561  else if(GetPointer<port_o>(dest)->ports.size() == 0)
1562  {
1563  for(const auto& i : ports)
1564  {
1565  structural_objectRef port(new port_o(debug_level, dest, dir, port_o_K));
1566  i->copy(port);
1567  GetPointer<port_o>(dest)->ports.push_back(port);
1568  }
1569  }
1570  else if(ports.size() != 0)
1571  {
1572  THROW_ERROR("unexpected copy: src=" + get_path() + " dest=" + dest->get_path() + " sizeSRC=" + STR(ports.size()) +
1573  " sizeDST=" + STR(GetPointer<port_o>(dest)->ports.size()));
1574  }
1575  GetPointer<port_o>(dest)->lsb = lsb;
1577 }
1578 
1580 {
1581  is_critical = true;
1582 }
1583 
1585 {
1586  return is_critical;
1587 }
1588 
1590 {
1591  is_reverse = true;
1592 }
1593 
1595 {
1596  return is_reverse;
1597 }
1598 
1600 {
1601  structural_object::xload(Enode, _owner, CM);
1602  if(CE_XVM(dir, Enode))
1603  {
1604  std::string dir_string;
1605  LOAD_XVFM(dir_string, Enode, dir);
1606  dir = to_port_direction(dir_string);
1607  }
1608  if(CE_XVM(pi, Enode))
1609  {
1610  std::string pi_string;
1611  LOAD_XVFM(pi_string, Enode, pi);
1612  pi = to_port_interface(pi_string);
1613  }
1614  if(CE_XVM(aligment, Enode))
1615  {
1616  LOAD_XVM(aligment, Enode);
1617  }
1618  if(CE_XVM(is_var_args, Enode))
1619  {
1620  LOAD_XVM(is_var_args, Enode);
1621  }
1622  if(CE_XVM(is_clock, Enode))
1623  {
1624  LOAD_XVM(is_clock, Enode);
1625  }
1626  if(CE_XVM(is_extern, Enode))
1627  {
1628  LOAD_XVM(is_extern, Enode);
1629  }
1630  if(CE_XVM(is_global, Enode))
1631  {
1632  LOAD_XVM(is_global, Enode);
1633  }
1634  if(CE_XVM(is_memory, Enode))
1635  {
1636  LOAD_XVM(is_memory, Enode);
1637  }
1638  if(CE_XVM(is_slave, Enode))
1639  {
1640  LOAD_XVM(is_slave, Enode);
1641  }
1642  if(CE_XVM(is_master, Enode))
1643  {
1644  LOAD_XVM(is_master, Enode);
1645  }
1646  if(CE_XVM(is_data_bus, Enode))
1647  {
1648  LOAD_XVM(is_data_bus, Enode);
1649  }
1650  if(CE_XVM(is_addr_bus, Enode))
1651  {
1652  LOAD_XVM(is_addr_bus, Enode);
1653  }
1654  if(CE_XVM(is_size_bus, Enode))
1655  {
1656  LOAD_XVM(is_size_bus, Enode);
1657  }
1658  if(CE_XVM(is_tag_bus, Enode))
1659  {
1660  LOAD_XVM(is_tag_bus, Enode);
1661  }
1662  if(CE_XVM(is_doubled, Enode))
1663  {
1664  LOAD_XVM(is_doubled, Enode);
1665  }
1666  if(CE_XVM(is_halved, Enode))
1667  {
1668  LOAD_XVM(is_halved, Enode);
1669  }
1670  if(CE_XVM(is_critical, Enode))
1671  {
1672  LOAD_XVM(is_critical, Enode);
1673  }
1674  if(CE_XVM(is_reverse, Enode))
1675  {
1676  LOAD_XVM(is_reverse, Enode);
1677  }
1678  if(CE_XVM(size_parameter, Enode))
1679  {
1680  LOAD_XVM(size_parameter, Enode);
1681  }
1682 
1684  auto minBit = std::numeric_limits<unsigned>::max();
1685  // Recourse through child nodes:
1686  const xml_node::node_list list = Enode->get_children();
1687  for(const auto& iter : list)
1688  {
1689  const auto* EnodeC = GetPointer<const xml_element>(iter);
1690  if(!EnodeC)
1691  {
1692  continue;
1693  }
1694  if(EnodeC->get_name() == GET_CLASS_NAME(port_o))
1695  {
1696  THROW_ASSERT(CE_XVM(dir, EnodeC), "Port has to have a direction." + std::to_string(EnodeC->get_line()));
1697  std::string dir_string;
1698  LOAD_XVFM(dir_string, EnodeC, dir);
1700  "port and port_vector objects has to have the same direction");
1701  obj = structural_objectRef(new port_o(CM->get_debug_level(), _owner, dir, port_o_K));
1702  obj->xload(EnodeC, obj, CM);
1703  ports.push_back(obj);
1704  auto _id = static_cast<unsigned>(std::stoul(obj->get_id()));
1705  minBit = std::min(minBit, _id);
1707  }
1708  }
1709  if(minBit == std::numeric_limits<unsigned>::max())
1710  {
1711  lsb = 0;
1712  }
1713  else
1714  {
1715  lsb = minBit;
1716  }
1718 }
1719 
1721 {
1722  unsigned int i;
1723  for(i = 0; i < port_direction::UNKNOWN; i++)
1724  {
1725  if(val == GetString(static_cast<port_direction>(i)))
1726  {
1727  break;
1728  }
1729  }
1730  return port_direction(i);
1731 }
1732 
1734 {
1735  unsigned int i;
1736  for(i = 0; i <= port_interface::PI_DEFAULT; i++)
1737  {
1738  if(val == GetString(static_cast<port_interface>(i)))
1739  {
1740  break;
1741  }
1742  }
1743  return port_interface(i);
1744 }
1745 
1747 {
1748  xml_element* Enode = rootnode->add_child_element(get_kind_text());
1750 #if !RELEASE
1751  std::string tlm_directionality;
1752  std::string id_type = structural_object::get_typeRef()->id_type;
1753  if(id_type.find("put_if", 0) != std::string::npos)
1754  {
1755  tlm_directionality = "->";
1756  }
1757  else if(id_type.find("get_if", 0) != std::string::npos)
1758  {
1759  tlm_directionality = "<-";
1760  }
1761  else if(id_type.find("transport_if", 0) != std::string::npos)
1762  {
1763  tlm_directionality = "<->";
1764  }
1765  else
1766  {
1767  tlm_directionality = "--";
1768  }
1769  if(tlm_directionality != "--")
1770  {
1771  WRITE_XVM(tlm_directionality, Enode);
1772  }
1773 #endif
1774  // WRITE_XVM(structural_object::get_typeRef()->id_type,Enode);
1775  WRITE_XNVM(dir, GetString(dir), Enode);
1776  if(pi != port_interface::PI_DEFAULT)
1777  {
1778  WRITE_XNVM(pi, GetString(pi), Enode);
1779  }
1781  {
1782  WRITE_XVM(aligment, Enode);
1783  }
1784  xml_element* Enode_CO = Enode->add_child_element("connected_objects");
1785  for(unsigned int i = 0; i < connected_objects.size(); i++)
1786  {
1787  WRITE_XNVM2("CON" + std::to_string(i), connected_objects[i].lock()->get_path(), Enode_CO);
1788  }
1789  if(is_clock != is_clock_DEFAULT)
1790  {
1791  WRITE_XVM(is_clock, Enode);
1792  }
1794  {
1795  WRITE_XVM(is_extern, Enode);
1796  }
1798  {
1799  WRITE_XVM(is_global, Enode);
1800  }
1802  {
1803  WRITE_XVM(is_memory, Enode);
1804  }
1805  if(is_slave != is_slave_DEFAULT)
1806  {
1807  WRITE_XVM(is_slave, Enode);
1808  }
1810  {
1811  WRITE_XVM(is_master, Enode);
1812  }
1814  {
1815  WRITE_XVM(is_data_bus, Enode);
1816  }
1818  {
1819  WRITE_XVM(is_addr_bus, Enode);
1820  }
1822  {
1823  WRITE_XVM(is_size_bus, Enode);
1824  }
1826  {
1827  WRITE_XVM(is_tag_bus, Enode);
1828  }
1830  {
1831  WRITE_XVM(is_doubled, Enode);
1832  }
1834  {
1835  WRITE_XVM(is_halved, Enode);
1836  }
1838  {
1839  WRITE_XVM(is_critical, Enode);
1840  }
1842  {
1843  WRITE_XVM(is_reverse, Enode);
1844  }
1846  {
1847  WRITE_XVM(is_var_args, Enode);
1848  }
1849  for(auto& port : ports)
1850  {
1851  port->xwrite(Enode);
1852  }
1853 }
1854 
1855 #if HAVE_TECHNOLOGY_BUILT
1856 void port_o::xwrite_attributes(xml_element* rootnode, const technology_nodeRef&)
1857 {
1858  xml_element* pin_node = rootnode->add_child_element("pin");
1859 
1860  xml_element* name_node = pin_node->add_child_element("name");
1861  name_node->add_child_text(get_id());
1862 
1863  for(const auto& o : attribute_list)
1864  {
1865  const attributeRef attr = attributes[o];
1866  attr->xwrite(pin_node, o);
1867  }
1868 }
1869 #endif
1870 
1871 void port_o::print(std::ostream& os) const
1872 {
1873  PP(os, "PORT:\n");
1875  PP(os, "[Dir: " + GetString(dir));
1876  if(pi != port_interface::PI_DEFAULT)
1877  {
1878  PP(os, "[Interface: " + GetString(pi));
1879  }
1881  {
1882  PP(os, "[Interface: " + STR(aligment));
1883  }
1884  if(connected_objects.size())
1885  {
1886  PP(os, " [CON: ");
1887  }
1888  for(const auto& connected_object : connected_objects)
1889  {
1890  os << connected_object.lock()->get_path() + "-" + convert_so_short(connected_object.lock()->get_kind()) << " ";
1891  }
1892  if(connected_objects.size())
1893  {
1894  PP(os, "]");
1895  }
1896  PP(os, "]\n");
1897  if(ports.size())
1898  {
1899  PP(os, "[Ports:\n");
1900  }
1901  for(const auto& port : ports)
1902  {
1903  port->print(os);
1904  }
1905  if(ports.size())
1906  {
1907  PP(os, "]");
1908  }
1909 }
1910 
1911 event_o::event_o(int _debug_level, const structural_objectRef o) : structural_object(_debug_level, o)
1912 {
1913 }
1914 
1916 {
1917  THROW_ERROR("Events do not have associated any structural object");
1918  return structural_objectRef();
1919 }
1920 
1922 {
1924 }
1925 
1927 {
1928  THROW_ERROR("Something went wrong!");
1929  return structural_objectRef();
1930 }
1931 
1933 {
1934  structural_object::xload(Enode, _owner, CM);
1935 }
1936 
1938 {
1939  xml_element* Enode = rootnode->add_child_element(get_kind_text());
1941 }
1942 
1943 void event_o::print(std::ostream& os) const
1944 {
1945  PP(os, "EVENT:\n");
1947  PP(os, "\n");
1948 }
1949 
1950 data_o::data_o(int _debug_level, const structural_objectRef o) : structural_object(_debug_level, o)
1951 {
1952 }
1953 
1955 {
1956  THROW_ERROR("data objects do not have associated any structural object");
1957  return structural_objectRef();
1958 }
1959 
1961 {
1963 }
1964 
1966 {
1967  THROW_ERROR("Something went wrong!");
1968  return structural_objectRef();
1969 }
1970 
1972 {
1973  structural_object::xload(Enode, _owner, CM);
1974 }
1975 
1977 {
1978  xml_element* Enode = rootnode->add_child_element(get_kind_text());
1980 }
1981 
1982 void data_o::print(std::ostream& os) const
1983 {
1984  PP(os, "DATA:\n");
1986  PP(os, "\n");
1987 }
1988 
1989 action_o::action_o(int _debug_level, const structural_objectRef o)
1990  : structural_object(_debug_level, o), function_id(0), action_type(UNKNOWN)
1991 {
1992 }
1993 
1995 {
1996  THROW_ASSERT(d, "NULL object received");
1997  parameters.push_back(d);
1998 }
1999 
2001 {
2002  THROW_ASSERT(n < parameters.size(), "index out of range");
2003  return parameters[n];
2004 }
2005 
2006 unsigned int action_o::get_parameters_size() const
2007 {
2008  return static_cast<unsigned int>(parameters.size());
2009 }
2010 
2011 void action_o::set_fun_id(unsigned int _id)
2012 {
2013  function_id = _id;
2014 }
2015 
2016 unsigned int action_o::get_fun_id() const
2017 {
2018  return function_id;
2019 }
2020 
2022 {
2023  action_type = at;
2024 }
2025 
2027 {
2028  return action_type;
2029 }
2030 
2032 {
2033  THROW_ASSERT(e, "NULL object received");
2034  action_sensitivity.push_back(e);
2035 }
2036 
2038 {
2039  return static_cast<unsigned int>(action_sensitivity.size());
2040 }
2041 
2043 {
2044  THROW_ASSERT(n < action_sensitivity.size(), "index out of range");
2045  return action_sensitivity[n];
2046 }
2047 
2048 void action_o::set_scope(const std::string& sc)
2049 {
2050  scope = sc;
2051 }
2052 
2053 const std::string& action_o::get_scope() const
2054 {
2055  return scope;
2056 }
2057 
2059 {
2060  return action_type != SERVICE;
2061 }
2062 
2064 {
2067  for(const auto& parameter : parameters)
2068  {
2069  obj = structural_objectRef(new data_o(debug_level, dest));
2070  parameter->copy(obj);
2071  GetPointer<action_o>(dest)->add_parameter(obj);
2072  }
2073  GetPointer<action_o>(dest)->function_id = function_id;
2074  GetPointer<action_o>(dest)->action_type = action_type;
2075  for(const auto& i : action_sensitivity)
2076  {
2077  obj = structural_objectRef(new event_o(debug_level, dest));
2078  i->copy(obj);
2079  GetPointer<action_o>(dest)->add_event_to_sensitivity(obj);
2080  }
2081  GetPointer<action_o>(dest)->scope = scope;
2082 }
2083 
2085 {
2086  THROW_ERROR("Something went wrong!");
2087  return structural_objectRef();
2088 }
2089 
2090 structural_objectRef action_o::find_member(const std::string& _id, so_kind _type, const structural_objectRef) const
2091 {
2092  switch(_type)
2093  {
2094  case data_o_K:
2095  {
2096  for(const auto& parameter : parameters)
2097  {
2098  if(parameter->get_id() == _id)
2099  {
2100  return parameter;
2101  }
2102  }
2103  break;
2104  }
2105  case event_o_K:
2106  {
2107  for(const auto& i : action_sensitivity)
2108  {
2109  if(i->get_id() == _id)
2110  {
2111  return i;
2112  }
2113  }
2114  break;
2115  }
2116  case action_o_K:
2117  case component_o_K:
2118  case bus_connection_o_K:
2119  case channel_o_K:
2120  case constant_o_K:
2121  case port_o_K:
2122  case port_vector_o_K:
2123  case signal_o_K:
2124  case signal_vector_o_K:
2125  default:
2126  THROW_ERROR("Structural object not foreseen");
2127  }
2128  return structural_objectRef();
2129 }
2130 
2131 const char* action_o::process_typeNames[] = {"THREAD", "CTHREAD", "METHOD", "SERVICE", "UNKNOWN"};
2132 
2134 {
2135  structural_object::xload(Enode, _owner, CM);
2136  LOAD_XVM(scope, Enode);
2137  if(CE_XVM(action_type, Enode))
2138  {
2139  unsigned int i;
2140  std::string val;
2141  LOAD_XVFM(val, Enode, action_type);
2142  for(i = 0; i < UNKNOWN; i++)
2143  {
2144  if(val == process_typeNames[i])
2145  {
2146  break;
2147  }
2148  }
2150  }
2153  // Recourse through child nodes:
2154  const xml_node::node_list list = Enode->get_children();
2155  for(const auto& iter : list)
2156  {
2157  const auto* EnodeC = GetPointer<const xml_element>(iter);
2158  if(!EnodeC)
2159  {
2160  continue;
2161  }
2162  if(EnodeC->get_name() == GET_CLASS_NAME(data_o))
2163  {
2164  obj = structural_objectRef(new data_o(CM->get_debug_level(), _owner));
2165  obj->xload(EnodeC, obj, CM);
2166  GetPointer<action_o>(_owner)->add_parameter(obj);
2167  }
2168  else if(EnodeC->get_name() == GET_CLASS_NAME(event_o))
2169  {
2170  obj = structural_objectRef(new event_o(CM->get_debug_level(), _owner));
2171  obj->xload(EnodeC, obj, CM);
2172  GetPointer<action_o>(_owner)->add_event_to_sensitivity(obj);
2173  }
2174  }
2175 }
2176 
2178 {
2179  xml_element* Enode = rootnode->add_child_element(get_kind_text());
2181  if(parameters.size())
2182  {
2183  for(auto& parameter : parameters)
2184  {
2185  parameter->xwrite(Enode);
2186  }
2187  }
2190  if(action_sensitivity.size())
2191  {
2192  for(auto& i : action_sensitivity)
2193  {
2194  i->xwrite(Enode);
2195  }
2196  }
2197  WRITE_XVM(scope, Enode);
2198 }
2199 
2200 void action_o::print(std::ostream& os) const
2201 {
2202  PP(os, "ACTION:\n");
2204  PP(os, "[\n");
2205  if(parameters.size())
2206  {
2207  PP(os, "Method/procedure Parameters:\n");
2208  }
2209  for(const auto& parameter : parameters)
2210  {
2211  parameter->print(os);
2212  }
2213  // if (GM) GM->print(os); //too verbose
2214  PP(os, "Action type: " + std::string(process_typeNames[action_type]) + "\n");
2215 
2216  if(action_sensitivity.size())
2217  {
2218  PP(os, "Sensitivity List:\n");
2219  }
2220  for(const auto& i : action_sensitivity)
2221  {
2222  i->print(os);
2223  }
2224  os << "Scope " << scope << " ";
2225  os << (action_type != SERVICE ? "PROCESS" : "SERVICE");
2226  PP(os, "]\n");
2227 }
2228 
2229 constant_o::constant_o(int _debug_level, const structural_objectRef o) : structural_object(_debug_level, o)
2230 {
2231 }
2232 
2233 constant_o::constant_o(int _debug_level, const structural_objectRef o, std::string _value)
2234  : structural_object(_debug_level, o), value(std::move(_value))
2235 {
2236 }
2237 
2239 {
2240  return static_cast<unsigned int>(connected_objects.size());
2241 }
2242 
2244 {
2245  THROW_ASSERT(idx < connected_objects.size(), "index out of range");
2246  return connected_objects[idx].lock();
2247 }
2248 
2250 {
2251  THROW_ASSERT(p, "NULL object received");
2252  THROW_ASSERT(p->get_kind() == port_o_K || p->get_kind() == signal_o_K,
2253  "constant can be connected only to ports and signals, but not to " + std::string(p->get_kind_text()));
2255  for(auto& connected_object : connected_objects)
2256  {
2257  if(connected_object.lock() == p)
2258  {
2259  return;
2260  }
2261  }
2262  connected_objects.push_back(p);
2263 }
2264 
2266 {
2267  THROW_ASSERT(dest, "NULL object received");
2269  GetPointer<constant_o>(dest)->value = value;
2271 }
2272 
2273 unsigned long long constant_o::get_size() const
2274 {
2275  return GET_TYPE_SIZE(this);
2276 }
2277 
2278 std::string constant_o::get_value() const
2279 {
2280  return value;
2281 }
2282 
2284  const structural_objectRef _owner) const
2285 {
2286  switch(_type)
2287  {
2288  case signal_o_K:
2289  case port_o_K:
2290  {
2291  for(const auto& connected_object : connected_objects)
2292  {
2293  if(connected_object.lock()->get_kind() == _type && connected_object.lock()->get_id() == _id &&
2294  connected_object.lock()->get_owner() == _owner)
2295  {
2296  return connected_object.lock();
2297  }
2298  }
2299  break;
2300  }
2301  case action_o_K:
2302  case component_o_K:
2303  case bus_connection_o_K:
2304  case channel_o_K:
2305  case constant_o_K:
2306  case data_o_K:
2307  case event_o_K:
2308  case port_vector_o_K:
2309  case signal_vector_o_K:
2310  default:
2311  THROW_ERROR("Structural object not foreseen");
2312  }
2313  return structural_objectRef();
2314 }
2315 
2317 {
2318  THROW_ASSERT(get_owner() && key->get_owner(), "Something went wrong!");
2319  switch(key->get_kind())
2320  {
2321  case signal_o_K:
2322  {
2323  auto* conn = GetPointer<signal_o>(key);
2324  for(unsigned int k = 0; k < conn->get_connected_objects_size(); k++)
2325  {
2326  if(conn->get_port(k)->get_id() == get_id())
2327  {
2328  return get_owner()->find_isomorphic(conn->get_port(k)->get_owner())->find_isomorphic(key);
2329  }
2330  }
2331  THROW_ERROR("Something went wrong!");
2332  break;
2333  }
2334  case component_o_K:
2335  case channel_o_K:
2336  {
2337  THROW_ASSERT(key->get_id() == get_owner()->get_id(), "Something went wrong!");
2338  return get_owner();
2339  }
2340  case action_o_K:
2341  case bus_connection_o_K:
2342  case constant_o_K:
2343  case data_o_K:
2344  case event_o_K:
2345  case port_o_K:
2346  case port_vector_o_K:
2347  case signal_vector_o_K:
2348  default:
2349  THROW_ERROR("Something went wrong!");
2350  }
2351  return structural_objectRef();
2352 }
2353 
2355 {
2356  if(CE_XVM(value, Enode))
2357  {
2358  LOAD_XVM(value, Enode);
2359  }
2360  std::string id_string;
2361  if(CE_XVM(id, Enode))
2362  {
2363  LOAD_XVFM(id_string, Enode, id);
2364  }
2365  else
2366  {
2367  id_string = value;
2368  }
2369  set_id(id_string);
2371 }
2372 
2374 {
2375  xml_element* Enode = rootnode->add_child_element(get_kind_text());
2377  WRITE_XVM(value, Enode);
2378  xml_element* Enode_CO = Enode->add_child_element("connected_objects");
2379  for(unsigned int i = 0; i < connected_objects.size(); i++)
2380  {
2381  WRITE_XNVM2("CON" + std::to_string(i), connected_objects[i].lock()->get_path(), Enode_CO);
2382  }
2383 }
2384 
2385 void constant_o::print(std::ostream& os) const
2386 {
2387  PP(os, "CONSTANT:\n");
2389  PP(os, "[\n");
2390  PP(os, "Value: " + value + "; ");
2391  if(connected_objects.size())
2392  {
2393  PP(os, " [CON: ");
2394  }
2395  for(const auto& connected_object : connected_objects)
2396  {
2397  os << connected_object.lock()->get_path() + "-" + convert_so_short(connected_object.lock()->get_kind()) << " ";
2398  }
2399  if(connected_objects.size())
2400  {
2401  PP(os, "]");
2402  }
2403  PP(os, "]\n");
2404 }
2405 
2406 signal_o::signal_o(int _debug_level, const structural_objectRef o, so_kind _signal_type)
2407  : structural_object(_debug_level, o), is_critical(false), lsb(0), signal_type(_signal_type)
2408 {
2409 }
2410 
2412 {
2413  is_critical = true;
2414 }
2415 
2417 {
2418  return is_critical;
2419 }
2420 
2422 {
2423  THROW_ASSERT(p, "NULL object received");
2424  THROW_ASSERT(GetPointer<port_o>(p), "A port is expected");
2425  for(auto& connected_object : connected_objects)
2426  {
2427  if(connected_object.lock() == p)
2428  {
2429  return;
2430  }
2431  }
2432  connected_objects.push_back(p);
2433 }
2434 
2435 const structural_objectRef signal_o::get_port(unsigned int n) const
2436 {
2437  THROW_ASSERT(n < connected_objects.size(), "index out of range");
2438  return connected_objects[n].lock();
2439 }
2440 
2442 {
2443  THROW_ASSERT(n < connected_objects.size(), "index " + STR(n) + " is out of range for signal " + get_path());
2444  return connected_objects[n].lock();
2445 }
2446 
2448 {
2449  THROW_ASSERT(s, "NULL object received");
2450  THROW_ASSERT(GetPointer<port_o>(s), "A port is expected");
2451  auto del = connected_objects.begin();
2452  for(; del != connected_objects.end(); ++del)
2453  {
2454  if((*del).lock() == s)
2455  {
2456  break;
2457  }
2458  }
2459  if(del != connected_objects.end())
2460  {
2461  connected_objects.erase(del);
2462  }
2463 }
2464 
2466 {
2467  THROW_ASSERT(s, "NULL object received");
2468  if(connected_objects.size() == 0)
2469  {
2470  return false;
2471  }
2472  auto del = connected_objects.begin();
2473  for(; del != connected_objects.end(); ++del)
2474  {
2475  if((*del).lock() == s)
2476  {
2477  return true;
2478  }
2479  }
2480  return false;
2481 }
2482 
2484 {
2485  auto del = connected_objects.begin();
2486  for(; del != connected_objects.end(); ++del)
2487  {
2488  if((*del).lock() == new_conn)
2489  {
2490  break;
2491  }
2492  }
2493  if(del != connected_objects.end())
2494  {
2495  auto del_old = connected_objects.begin();
2496  for(; del_old != connected_objects.end(); ++del_old)
2497  {
2498  if((*del_old).lock() == old_conn)
2499  {
2500  break;
2501  }
2502  }
2503  if(del_old != connected_objects.end())
2504  {
2505  connected_objects.erase(del_old);
2506  }
2507  }
2508  else
2509  {
2510  for(auto& connected_object : connected_objects)
2511  {
2512  if(connected_object.lock() == old_conn)
2513  {
2514  connected_object = new_conn;
2515  }
2516  else
2517  {
2518  THROW_ASSERT(GetPointer<port_o>(connected_object.lock()), "Expected port");
2519  }
2520  }
2521  }
2522 }
2523 
2525 {
2526  return static_cast<unsigned int>(connected_objects.size());
2527 }
2528 
2530 {
2531  if(connected_objects.size() <= 1)
2532  {
2533  return false;
2534  }
2535  bool in_port = false;
2536  bool out_port = false;
2537  auto it_end = connected_objects.end();
2538  auto it2_end = connected_objects.end();
2539  for(auto it = connected_objects.begin(); it != it_end; ++it)
2540  {
2541  if(GetPointer<port_o>((*it).lock()))
2542  {
2543  auto* port = GetPointer<port_o>((*it).lock());
2544  if(port->get_port_direction() == port_o::IN || port->get_port_direction() == port_o::IO)
2545  {
2546  in_port = true;
2547  break;
2548  }
2549  }
2550  }
2551  for(auto it = connected_objects.begin(); it != it_end; ++it)
2552  {
2553  if(GetPointer<port_o>((*it).lock()))
2554  {
2555  auto* port = GetPointer<port_o>((*it).lock());
2556  if(port->get_port_direction() == port_o::OUT || port->get_port_direction() == port_o::IO)
2557  {
2558  out_port = true;
2559  break;
2560  }
2561  }
2562  }
2563  if(in_port && out_port)
2564  {
2565  return true;
2566  }
2567  // At this point ports are all input or all output
2568  for(auto it = connected_objects.begin(); it != it_end; ++it)
2569  {
2570  if(GetPointer<port_o>((*it).lock()))
2571  {
2572  auto* first_port = GetPointer<port_o>((*it).lock());
2573  structural_objectRef first_owner = first_port->get_owner();
2574  for(auto it2 = connected_objects.begin(); it2 != it2_end; ++it2)
2575  {
2576  if(GetPointer<port_o>((*it2).lock()))
2577  {
2578  auto* second_port = GetPointer<port_o>((*it2).lock());
2579  structural_objectRef second_owner = second_port->get_owner();
2580  if(first_owner == second_owner->get_owner() || second_owner == first_owner->get_owner())
2581  {
2582  return true;
2583  }
2584  }
2585  }
2586  }
2587  }
2588  return false;
2589 }
2590 
2592  const structural_objectRef _owner) const
2593 {
2594  switch(_type)
2595  {
2596  case port_vector_o_K:
2597  case port_o_K:
2598  {
2599  for(const auto& connected_object : connected_objects)
2600  {
2601  if(connected_object.lock()->get_id() == _id && connected_object.lock()->get_owner() == _owner)
2602  {
2603  return connected_object.lock();
2604  }
2605  }
2606  break;
2607  }
2608  case signal_o_K:
2609  {
2610  for(const auto& signal : signals_)
2611  {
2612  if(signal->get_id() == _id && signal->get_owner() == _owner)
2613  {
2614  return signal;
2615  }
2616  }
2617  break;
2618  }
2619  case action_o_K:
2620  case component_o_K:
2621  case bus_connection_o_K:
2622  case channel_o_K:
2623  case constant_o_K:
2624  case data_o_K:
2625  case event_o_K:
2626  case signal_vector_o_K:
2627  default:
2628  THROW_ERROR("Structural object not foreseen " + _owner->get_kind_text());
2629  }
2630  return structural_objectRef();
2631 }
2632 
2634 {
2635  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Copying signal: " << get_path());
2637  if(is_critical)
2638  {
2639  GetPointer<signal_o>(dest)->set_critical();
2640  }
2642 
2643  for(const auto& signal : signals_)
2644  {
2646  signal->copy(sig);
2647  GetPointer<signal_o>(dest)->signals_.push_back(sig);
2648  }
2649  GetPointer<signal_o>(dest)->lsb = lsb;
2650 }
2651 
2653 {
2654  THROW_ASSERT(get_owner() && key->get_owner(), "Something went wrong!");
2655  switch(key->get_kind())
2656  {
2657  case port_o_K:
2658  {
2661  if(key->get_owner()->get_kind() == port_vector_o_K)
2662  {
2663  if(key->get_owner()->get_owner()->get_id() == get_owner()->get_id())
2664  {
2666  return get_owner()->find_isomorphic(key->get_owner())->find_isomorphic(key);
2667  }
2668  else
2669  {
2670  return get_owner()
2671  ->find_isomorphic(key->get_owner()->get_owner())
2672  ->find_isomorphic(key->get_owner())
2673  ->find_isomorphic(key);
2674  }
2675  }
2676  else if(key->get_owner()->get_id() == get_owner()->get_id())
2677  {
2678  return get_owner()->find_isomorphic(key);
2680  }
2681  else
2682  {
2684  return get_owner()->find_isomorphic(key->get_owner())->find_isomorphic(key);
2685  }
2686  break;
2687  }
2688  case signal_o_K:
2689  {
2690  for(const auto& signal : signals_)
2691  {
2692  if(signal->get_id() == key->get_id())
2693  {
2694  return signal;
2695  }
2696  }
2697  break;
2698  }
2699  case action_o_K:
2700  case component_o_K:
2701  case bus_connection_o_K:
2702  case channel_o_K:
2703  case constant_o_K:
2704  case data_o_K:
2705  case event_o_K:
2706  case port_vector_o_K:
2707  case signal_vector_o_K:
2708  default:
2709  THROW_ERROR("Something went wrong!");
2710  }
2711  return structural_objectRef();
2712 }
2713 
2715 {
2716  structural_object::xload(Enode, _owner, CM);
2718  std::string _id = get_id();
2719  if(_id.find('\\') != std::string::npos)
2720  {
2721  structural_objectRef module_own = get_owner();
2722  if(module_own->get_kind() != component_o_K)
2723  {
2724  module_own = module_own->get_owner();
2725  }
2726 
2727  std::string base = _id;
2728  boost::replace_all(base, "\\", "");
2729  base = base.substr(0, base.find_first_of('['));
2730  std::string element = _id;
2731  element = element.substr(element.find_first_of('[') + 1, element.size());
2732  element = element.substr(0, element.find_first_of(']'));
2733 
2734  legalize(_id);
2735 
2736  structural_objectRef pv = module_own->find_member(base, port_vector_o_K, module_own);
2737  THROW_ASSERT(pv, "port vector " + base + " not found");
2738  structural_objectRef p = pv->find_member(element, port_o_K, pv);
2739  THROW_ASSERT(p, "port element " + element + " not found");
2740  GetPointer<signal_o>(_owner)->add_port(p);
2741  GetPointer<port_o>(p)->add_connection(_owner);
2742 
2743  set_id(_id);
2744  }
2745  // Recourse through child nodes:
2746  auto minBit = std::numeric_limits<unsigned>::max();
2747 
2748  const xml_node::node_list list = Enode->get_children();
2749  for(const auto& iter : list)
2750  {
2751  const auto* EnodeC = GetPointer<const xml_element>(iter);
2752  if(!EnodeC)
2753  {
2754  continue;
2755  }
2756  if(EnodeC->get_name() == GET_CLASS_NAME(signal_o))
2757  {
2759  obj->xload(EnodeC, obj, CM);
2760  signals_.push_back(obj);
2761  auto sig_id = static_cast<unsigned>(std::stoul(obj->get_id()));
2762  minBit = std::min(minBit, sig_id);
2764  }
2765  }
2766  if(minBit == std::numeric_limits<unsigned>::max())
2767  {
2768  lsb = 0;
2769  }
2770  else
2771  {
2772  lsb = minBit;
2773  }
2774 }
2775 
2777 {
2778  xml_element* Enode = rootnode->add_child_element(get_kind_text());
2780  xml_element* Enode_CO = Enode->add_child_element("connected_objects");
2781  for(unsigned int i = 0; i < connected_objects.size(); i++)
2782  {
2783  WRITE_XNVM2("CON" + std::to_string(i), connected_objects[i].lock()->get_path(), Enode_CO);
2784  }
2785  for(auto& signal : signals_)
2786  {
2787  signal->xwrite(Enode);
2788  }
2789 }
2790 
2791 void signal_o::print(std::ostream& os) const
2792 {
2793  PP(os, "SIGNAL:\n");
2795  if(connected_objects.size())
2796  {
2797  PP(os, "[CON: ");
2798  }
2799  for(const auto& connected_object : connected_objects)
2800  {
2801  os << connected_object.lock()->get_path() + "-" + convert_so_short(connected_object.lock()->get_kind()) << " ";
2802  }
2803  if(connected_objects.size())
2804  {
2805  PP(os, "]\n");
2806  }
2807 
2808  if(signals_.size())
2809  {
2810  PP(os, "[Signals:\n");
2811  }
2812  for(const auto& signal : signals_)
2813  {
2814  signal->print(os);
2815  }
2816  if(signals_.size())
2817  {
2818  PP(os, "]");
2819  }
2820 }
2821 
2822 void signal_o::add_n_signals(unsigned int n_signals, structural_objectRef _owner)
2823 {
2824  THROW_ASSERT(!signals_.size(), "port vector has been already specialized");
2825  THROW_ASSERT(_owner.get() == this, "owner and this has to be the same object");
2826  THROW_ASSERT(n_signals != PARAMETRIC_SIGNAL, "a number of signal different from PARAMETRIC_SIGNAL is expected");
2827  THROW_ASSERT(get_typeRef(), "the port vector has to have a type descriptor");
2828  signals_.resize(n_signals);
2830  for(unsigned int i = 0; i < n_signals; i++)
2831  {
2833  p->set_type(get_typeRef());
2834  p->set_id(std::to_string(i));
2835  signals_[i] = p;
2836  }
2837  THROW_ASSERT(signal_type == signal_vector_o_K, "inconsistent data structure");
2838 }
2839 
2840 const structural_objectRef signal_o::get_signal(unsigned int n) const
2841 {
2842  THROW_ASSERT(signals_.size(), "Signals with zero size");
2843  THROW_ASSERT(n < signals_.size(),
2844  "index " + STR(n) + " out of range [0:" + STR(signals_.size() - 1) + " in signal " + get_path());
2845  return signals_[n];
2846 }
2847 
2849 {
2850  THROW_ASSERT(n - lsb < signals_.size(), "index out of range");
2851  return signals_[n - lsb];
2852 }
2853 
2854 unsigned int signal_o::get_signals_size() const
2855 {
2856  THROW_ASSERT(signals_.size(), "port vector has to be specialized");
2857  return static_cast<unsigned int>(signals_.size());
2858 }
2859 
2860 module::module(int _debug_level, const structural_objectRef o)
2861  : structural_object(_debug_level, o),
2862  last_position_port(0),
2863  is_critical(false),
2864  is_generated(false),
2865  multi_unit_multiplicity(0),
2866  keep_hierarchy(false)
2867 {
2868 }
2869 
2870 unsigned int module::get_num_ports() const
2871 {
2872  return last_position_port;
2873 }
2874 
2876 {
2877  is_critical = true;
2878 }
2879 
2881 {
2882  return is_critical;
2883 }
2884 
2886 {
2887  is_generated = true;
2888 }
2889 
2891 {
2892  return is_generated;
2893 }
2894 
2896 {
2898 }
2899 
2901 {
2902  return multi_unit_multiplicity;
2903 }
2904 
2906 {
2907  keep_hierarchy = ky;
2908 }
2909 
2911 {
2912  return keep_hierarchy;
2913 }
2914 
2916 {
2917  THROW_ASSERT(positional_map.find(index) != positional_map.end(), "no port at index " + std::to_string(index));
2918  return positional_map.find(index)->second;
2919 }
2920 
2922 {
2923  THROW_ASSERT(p, "NULL object received");
2924  THROW_ASSERT((GetPointer<port_o>(p) && GetPointer<port_o>(p)->get_port_direction() == port_o::IN),
2925  "The parameter p is not an input port");
2926  THROW_ASSERT(p->get_owner().get() == this, "owner mismatch");
2927  in_ports.push_back(p);
2930 }
2931 
2932 const structural_objectRef module::get_in_port(unsigned int n) const
2933 {
2934  THROW_ASSERT(n < in_ports.size(), get_path() + ": index out of range (" + STR(n) + "/" + STR(in_ports.size()) +
2935  ") in " + get_path() + " of type " + get_typeRef()->id_type);
2936  return in_ports[n];
2937 }
2938 
2939 unsigned int module::get_in_port_size() const
2940 {
2941  return static_cast<unsigned int>(in_ports.size());
2942 }
2943 
2945 {
2946  THROW_ASSERT(p, "NULL object received");
2947  THROW_ASSERT((GetPointer<port_o>(p) && GetPointer<port_o>(p)->get_port_direction() == port_o::OUT),
2948  "The parameter p is not an output port");
2949  THROW_ASSERT(p->get_owner().get() == this, "owner mismatch");
2950  out_ports.push_back(p);
2953 }
2954 
2955 const structural_objectRef module::get_out_port(unsigned int n) const
2956 {
2957  THROW_ASSERT(n < out_ports.size(), "index out of range");
2958  return out_ports[n];
2959 }
2960 
2961 unsigned int module::get_out_port_size() const
2962 {
2963  return static_cast<unsigned int>(out_ports.size());
2964 }
2965 
2967 {
2968  THROW_ASSERT(p, "NULL object received");
2969  THROW_ASSERT((GetPointer<port_o>(p) && GetPointer<port_o>(p)->get_port_direction() == port_o::IO),
2970  "The parameter p is not an input-output port");
2971  THROW_ASSERT(p->get_owner().get() == this, "owner mismatch");
2972  in_out_ports.push_back(p);
2975 }
2976 
2978 {
2979  THROW_ASSERT(n < in_out_ports.size(), "index out of range");
2980  return in_out_ports[n];
2981 }
2982 
2983 unsigned int module::get_in_out_port_size() const
2984 {
2985  return static_cast<unsigned int>(in_out_ports.size());
2986 }
2987 
2989 {
2990  THROW_ASSERT(p, "NULL object received");
2991  THROW_ASSERT((GetPointer<port_o>(p) && GetPointer<port_o>(p)->get_port_direction() == port_o::GEN),
2992  "The parameter p is not a generic port");
2993  THROW_ASSERT(p->get_owner().get() == this, "owner mismatch");
2994  gen_ports.push_back(p);
2997 }
2998 
2999 const structural_objectRef module::get_gen_port(unsigned int n) const
3000 {
3001  THROW_ASSERT(n < gen_ports.size(), "index out of range");
3002  return gen_ports[n];
3003 }
3004 
3005 unsigned int module::get_gen_port_size() const
3006 {
3007  return static_cast<unsigned int>(gen_ports.size());
3008 }
3009 
3010 void module::remove_port(const std::string& _id)
3011 {
3012  auto num_port = static_cast<unsigned int>(positional_map.size());
3013  structural_objectRef port;
3014  for(auto& l : positional_map)
3015  {
3016  if(l.second->get_id() == _id)
3017  {
3018  num_port = l.first;
3019  port = l.second;
3020  break;
3021  }
3022  }
3023  THROW_ASSERT(port, "port not found: " + get_path() + "->" + _id);
3024 
3025  std::map<unsigned int, structural_objectRef> _positional_map = positional_map;
3026  positional_map.clear();
3027  for(auto& l : _positional_map)
3028  {
3029  if(l.first == num_port)
3030  {
3031  continue;
3032  }
3033  if(l.first < num_port)
3034  {
3035  positional_map[l.first] = l.second;
3036  }
3037  else
3038  {
3039  positional_map[l.first - 1] = l.second;
3040  }
3041  }
3043 
3044  if(GetPointer<port_o>(port)->get_port_direction() == port_o::IN)
3045  {
3046  bool found = false;
3047  for(unsigned int i = 0; i < in_ports.size(); i++)
3048  {
3049  if(in_ports[i]->get_id() == _id || found)
3050  {
3051  found = true;
3052  if(i == in_ports.size() - 1)
3053  {
3054  in_ports.pop_back();
3055  }
3056  else
3057  {
3058  in_ports[i] = in_ports[i + 1];
3059  }
3060  }
3061  }
3062  }
3063 
3064  if(GetPointer<port_o>(port)->get_port_direction() == port_o::OUT)
3065  {
3066  bool found = false;
3067  for(unsigned int i = 0; i < out_ports.size(); i++)
3068  {
3069  if(out_ports[i]->get_id() == _id || found)
3070  {
3071  found = true;
3072  if(i == out_ports.size() - 1)
3073  {
3074  out_ports.pop_back();
3075  }
3076  else
3077  {
3078  out_ports[i] = out_ports[i + 1];
3079  }
3080  }
3081  }
3082  }
3083 
3084  if(GetPointer<port_o>(port)->get_port_direction() == port_o::IO)
3085  {
3086  bool found = false;
3087 
3088  for(unsigned int i = 0; i < in_out_ports.size(); i++)
3089  {
3090  if(in_out_ports[i]->get_id() == _id || found)
3091  {
3092  found = true;
3093  if(i == in_out_ports.size() - 1)
3094  {
3095  in_out_ports.pop_back();
3096  }
3097  else
3098  {
3099  in_out_ports[i] = in_out_ports[i + 1];
3100  }
3101  }
3102  }
3103  }
3104 
3105  if(GetPointer<port_o>(port)->get_port_direction() == port_o::GEN)
3106  {
3107  bool found = false;
3108  for(unsigned int i = 0; i < gen_ports.size(); i++)
3109  {
3110  if(gen_ports[i]->get_id() == _id || found)
3111  {
3112  found = true;
3113  if(i == gen_ports.size() - 1)
3114  {
3115  gen_ports.pop_back();
3116  }
3117  else
3118  {
3119  gen_ports[i] = gen_ports[i + 1];
3120  }
3121  }
3122  }
3123  }
3124 }
3125 
3127 {
3128  THROW_ASSERT(c, "NULL object received");
3129  THROW_ASSERT(c->get_owner().get() == this, "owner mismatch " + c->get_path() + " vs " + get_path());
3130  internal_objects.push_back(c);
3131  switch(c->get_kind())
3132  {
3133  case constant_o_K:
3134  {
3135  index_constants[c->get_id()] = c;
3136  break;
3137  }
3138  case signal_vector_o_K:
3139  case signal_o_K:
3140  {
3141  index_signals[c->get_id()] = c;
3142  break;
3143  }
3144  case component_o_K:
3145  {
3146  index_components[c->get_id()] = c;
3147  break;
3148  }
3149  case channel_o_K:
3150  {
3151  index_channels[c->get_id()] = c;
3152  break;
3153  }
3154  case bus_connection_o_K:
3155  {
3156  index_bus_connections[c->get_id()] = c;
3157  break;
3158  }
3159  case action_o_K:
3160  case data_o_K:
3161  case event_o_K:
3162  case port_o_K:
3163  case port_vector_o_K:
3164  default:
3165  THROW_ERROR("Unexpected component: " + std::string(c->get_kind_text()));
3166  }
3167  set_black_box(false);
3168 }
3169 
3171 {
3172  THROW_ASSERT(s, "NULL object received");
3173  auto del = std::find(internal_objects.begin(), internal_objects.end(), s);
3174  if(del != internal_objects.end())
3175  {
3176  internal_objects.erase(del);
3177  }
3178  switch(s->get_kind())
3179  {
3180  case signal_o_K:
3181  index_signals.erase(s->get_id());
3182  break;
3183  case component_o_K:
3184  index_components.erase(s->get_id());
3185  break;
3186  case channel_o_K:
3187  index_channels.erase(s->get_id());
3188  break;
3189  case bus_connection_o_K:
3190  index_bus_connections.erase(s->get_id());
3191  break;
3192  case action_o_K:
3193  case constant_o_K:
3194  case data_o_K:
3195  case event_o_K:
3196  case port_o_K:
3197  case port_vector_o_K:
3198  case signal_vector_o_K:
3199  default:
3200  THROW_ERROR("Unexpected component");
3201  }
3202 }
3203 
3205 {
3206  THROW_ASSERT(n < internal_objects.size(), "index out of range");
3207  return internal_objects[n];
3208 }
3209 
3211 {
3212  return static_cast<unsigned int>(internal_objects.size());
3213 }
3214 
3216 {
3217  THROW_ASSERT(p, "NULL object received");
3218  THROW_ASSERT(p->get_kind() == action_o_K, "list of processes can have only object of type action_o");
3219  THROW_ASSERT(p->get_owner().get() == this, "owner mismatch");
3220  list_of_process.push_back(p);
3221 }
3222 
3223 const structural_objectRef module::get_process(unsigned int n) const
3224 {
3225  THROW_ASSERT(n < list_of_process.size(), "index out of range");
3226  return list_of_process[n];
3227 }
3228 
3229 unsigned int module::get_process_size() const
3230 {
3231  return static_cast<unsigned int>(list_of_process.size());
3232 }
3233 
3235 {
3236  THROW_ASSERT(p, "NULL object received");
3237  THROW_ASSERT(p->get_kind() == action_o_K, "list of services can have only object of type action_o");
3238  THROW_ASSERT(p->get_owner().get() == this, "owner mismatch");
3239  list_of_service.push_back(p);
3240 }
3241 
3242 const structural_objectRef module::get_service(unsigned int n) const
3243 {
3244  THROW_ASSERT(n < list_of_service.size(), "index out of range");
3245  return list_of_service[n];
3246 }
3247 
3248 unsigned int module::get_service_size() const
3249 {
3250  return static_cast<unsigned int>(list_of_service.size());
3251 }
3252 
3254 {
3255  THROW_ASSERT(e, "NULL object received");
3256  THROW_ASSERT(e->get_kind() == event_o_K, "list of events can have only object of type event_o");
3257  THROW_ASSERT(e->get_owner().get() == this, "owner mismatch");
3258  list_of_event.push_back(e);
3259 }
3260 
3261 const structural_objectRef module::get_event(unsigned int n) const
3262 {
3263  THROW_ASSERT(n < list_of_event.size(), "index out of range");
3264  return list_of_event[n];
3265 }
3266 
3267 unsigned int module::get_event_size() const
3268 {
3269  return static_cast<unsigned int>(list_of_event.size());
3270 }
3271 
3273 {
3274  THROW_ASSERT(d, "NULL object received");
3275  THROW_ASSERT(d->get_kind() == data_o_K, "Local data can have only object of type data_o");
3276  THROW_ASSERT(d->get_owner().get() == this, "owner mismatch");
3277  local_data.push_back(d);
3278 }
3279 
3281 {
3282  THROW_ASSERT(n < local_data.size(), "index out of range");
3283  return local_data[n];
3284 }
3285 
3286 unsigned int module::get_local_data_size() const
3287 {
3288  return static_cast<unsigned int>(local_data.size());
3289 }
3290 
3292 {
3293  NP_descriptions = f;
3294  if(get_black_box() and
3303  {
3304  set_black_box(false);
3305  }
3306 }
3307 
3309 {
3310  return NP_descriptions;
3311 }
3312 
3314  structural_objectRef _owner, std::vector<std::pair<std::string, structural_objectRef>>& computed_parameters) const
3315 {
3316  std::vector<std::string> param;
3318  auto it_end = param.end();
3319  for(auto it = param.begin(); it != it_end; ++it)
3320  {
3321  structural_objectRef obj = find_member(*it, port_vector_o_K, _owner);
3322  computed_parameters.push_back(std::make_pair(*it, obj));
3323  }
3324 }
3325 
3326 structural_objectRef module::find_member(const std::string& _id, so_kind _type,
3327  const structural_objectRef ASSERT_PARAMETER(_owner)) const
3328 {
3329  THROW_ASSERT(_owner && _owner.get() == this, "owner mismatch");
3330  switch(_type)
3331  {
3332  case port_o_K:
3333  case port_vector_o_K:
3334  {
3335  for(const auto& in_port : in_ports)
3336  {
3337  if(in_port->get_id() == _id)
3338  {
3339  return in_port;
3340  }
3341  }
3342  for(const auto& out_port : out_ports)
3343  {
3344  if(out_port->get_id() == _id)
3345  {
3346  return out_port;
3347  }
3348  }
3349  for(const auto& in_out_port : in_out_ports)
3350  {
3351  if(in_out_port->get_id() == _id)
3352  {
3353  return in_out_port;
3354  }
3355  }
3356  for(const auto& gen_port : gen_ports)
3357  {
3358  if(gen_port->get_id() == _id)
3359  {
3360  return gen_port;
3361  }
3362  }
3363  break;
3364  }
3365  case component_o_K:
3366  {
3367  auto it = index_components.find(_id);
3368  if(it != index_components.end())
3369  {
3370  return it->second;
3371  }
3372  break;
3373  }
3374  case channel_o_K:
3375  {
3376  auto it = index_channels.find(_id);
3377  if(it != index_channels.end())
3378  {
3379  return it->second;
3380  }
3381  break;
3382  }
3383  case constant_o_K:
3384  {
3385  auto it = index_constants.find(_id);
3386  if(it != index_constants.end())
3387  {
3388  return it->second;
3389  }
3390  break;
3391  }
3392  case signal_vector_o_K:
3393  case signal_o_K:
3394  {
3395  auto it = index_signals.find(_id);
3396  if(it != index_signals.end())
3397  {
3398  return it->second;
3399  }
3400  break;
3401  }
3402  case bus_connection_o_K:
3403  {
3404  auto it = index_bus_connections.find(_id);
3405  if(it != index_bus_connections.end())
3406  {
3407  return it->second;
3408  }
3409  break;
3410  }
3411  case data_o_K:
3412  {
3413  for(const auto& i : local_data)
3414  {
3415  if(i->get_id() == _id)
3416  {
3417  return i;
3418  }
3419  }
3420  break;
3421  }
3422  case event_o_K:
3423  {
3424  for(const auto& i : list_of_event)
3425  {
3426  if(i->get_id() == _id)
3427  {
3428  return i;
3429  }
3430  }
3431  break;
3432  }
3433  case action_o_K:
3434  {
3435  for(const auto& list_of_proces : list_of_process)
3436  {
3437  if(list_of_proces->get_id() == _id)
3438  {
3439  return list_of_proces;
3440  }
3441  }
3442  for(const auto& i : list_of_service)
3443  {
3444  if(i->get_id() == _id)
3445  {
3446  return i;
3447  }
3448  }
3449  break;
3450  }
3451  default:
3452  THROW_ERROR("Structural object not foreseen");
3453  }
3454  return structural_objectRef();
3455 }
3456 
3458 {
3459  unsigned int currPort = 0;
3460  unsigned int inPortSize = get_in_port_size();
3461  for(currPort = 0; currPort < inPortSize; currPort++)
3462  {
3463  if(GetPointer<port_o>(get_in_port(currPort))->get_is_var_args())
3464  {
3465  return true;
3466  }
3467  }
3468 
3469  return false;
3470 }
3471 
3473 {
3475  "Copying module: " + get_path() + " (" + get_typeRef()->id_type + ")");
3477 
3478  if(is_critical)
3479  {
3480  GetPointer<module>(dest)->set_critical();
3481  }
3482  if(is_generated)
3483  {
3484  GetPointer<module>(dest)->set_generated();
3485  }
3487  {
3488  GetPointer<module>(dest)->set_multi_unit_multiplicity(multi_unit_multiplicity);
3489  }
3490  if(keep_hierarchy)
3491  {
3492  GetPointer<module>(dest)->set_keep_hierarchy(keep_hierarchy);
3493  }
3495 
3497 #ifndef NDEBUG
3498  if(last_position_port)
3499  {
3501  }
3502 #endif
3503  for(unsigned int i = 0; i < last_position_port; i++)
3504  {
3505  THROW_ASSERT(positional_map.find(i) != positional_map.end(), "port " + std::to_string(i) + " does not exist");
3506  const structural_objectRef port = positional_map.find(i)->second;
3507  port_o::port_direction dir = port_o::GEN;
3508  if(port->get_kind() == port_o_K)
3509  {
3510  dir = GetPointer<port_o>(port)->get_port_direction();
3511  obj = structural_objectRef(new port_o(debug_level, dest, dir, port_o_K));
3512  }
3513  else if(port->get_kind() == port_vector_o_K)
3514  {
3515  dir = GetPointer<port_o>(port)->get_port_direction();
3516  obj = structural_objectRef(new port_o(debug_level, dest, dir, port_vector_o_K));
3517  }
3518  else
3519  {
3520  THROW_ERROR("Not expected object type: " + std::string(port->get_kind_text()));
3521  }
3522  port->copy(obj);
3523 
3524  switch(dir)
3525  {
3526  case port_o::IN:
3527  {
3528  GetPointer<module>(dest)->add_in_port(obj);
3529  break;
3530  }
3531  case port_o::OUT:
3532  {
3533  GetPointer<module>(dest)->add_out_port(obj);
3534  break;
3535  }
3536  case port_o::IO:
3537  {
3538  GetPointer<module>(dest)->add_in_out_port(obj);
3539  break;
3540  }
3541  case port_o::GEN:
3542  case port_o::TLM_IN:
3543  case port_o::TLM_INOUT:
3544  case port_o::TLM_OUT:
3545  case port_o::UNKNOWN:
3546  default:
3547  {
3548  THROW_ERROR("Not supported port direction");
3549  }
3550  }
3551  }
3552 
3554 #ifndef NDEBUG
3555  if(internal_objects.size())
3556  {
3557  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - copying internal objects: " << internal_objects.size());
3558  }
3559 #endif
3560  for(const auto& int_obj : internal_objects)
3561  {
3562  switch(int_obj->get_kind())
3563  {
3564  case signal_o_K:
3565  {
3567  break;
3568  }
3569  case signal_vector_o_K:
3570  {
3572  break;
3573  }
3574  case constant_o_K:
3575  {
3576  obj = structural_objectRef(new constant_o(debug_level, dest));
3577  break;
3578  }
3579  case component_o_K:
3580  {
3581  obj = structural_objectRef(new component_o(debug_level, dest));
3582  break;
3583  }
3584  case action_o_K:
3585  case bus_connection_o_K:
3586  case channel_o_K:
3587  case data_o_K:
3588  case event_o_K:
3589  case port_o_K:
3590  case port_vector_o_K:
3591  default:
3592  {
3593  THROW_ERROR("Not expected type: " + std::string(int_obj->get_kind_text()));
3594  }
3595  }
3596  int_obj->copy(obj);
3597  GetPointer<module>(dest)->add_internal_object(obj);
3598  }
3599 
3600  std::string scope = get_path();
3601  for(unsigned int i = 0; i < last_position_port; i++)
3602  {
3603  const structural_objectRef int_obj = positional_map.find(i)->second;
3604  std::vector<structural_objectRef> ports;
3605  if(int_obj->get_kind() == port_vector_o_K)
3606  {
3607  ports.push_back(int_obj);
3608  for(unsigned int p = 0; p < GetPointer<port_o>(int_obj)->get_ports_size(); p++)
3609  {
3610  ports.push_back(GetPointer<port_o>(int_obj)->get_port(p));
3611  }
3612  }
3613  else
3614  {
3615  ports.push_back(int_obj);
3616  }
3617  for(const auto& port_obj : ports)
3618  {
3619  const structural_objectRef dest_port = dest->find_isomorphic(port_obj);
3621  " - copying the connections of port: " << port_obj->get_path());
3622  const port_o* port = GetPointer<port_o>(port_obj);
3623  for(unsigned int c = 0; c < port->get_connections_size(); c++)
3624  {
3625  const structural_objectRef conn_obj = port->get_connection(c);
3626  std::string connected_path = conn_obj->get_path();
3627  if(connected_path.find(scope + "/") == std::string::npos)
3628  {
3629  continue;
3630  }
3631  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - internal connection with: " << connected_path);
3632  structural_objectRef dest_obj;
3633  if(conn_obj->get_kind() == signal_o_K || conn_obj->get_kind() == signal_vector_o_K)
3634  {
3635  // port-to-signal connection.
3636  dest_obj = dest->find_isomorphic(conn_obj);
3637  GetPointer<signal_o>(dest_obj)->add_port(dest_port);
3638  }
3639  else if(conn_obj->get_kind() == port_o_K || conn_obj->get_kind() == port_vector_o_K)
3640  {
3641  // port-to-port connection. It is a port of a submodule
3642  structural_objectRef conn_owner = conn_obj->get_owner();
3643  if(conn_owner->get_kind() == port_vector_o_K and conn_owner->get_owner()->get_path() != get_path())
3644  {
3645  conn_owner = conn_owner->get_owner();
3646  }
3647  THROW_ASSERT(conn_owner, "Not valid submodule");
3648  dest_obj = dest->find_isomorphic(conn_owner);
3649  dest_obj = dest_obj->find_isomorphic(conn_obj);
3650  GetPointer<port_o>(dest_obj)->add_connection(dest_port);
3651  }
3652  else if(conn_obj->get_kind() == constant_o_K)
3653  {
3654  // port-to-constant connection.
3655  dest_obj = dest->find_isomorphic(conn_obj);
3656  GetPointer<constant_o>(dest_obj)->add_connection(dest_port);
3657  }
3658  else
3659  {
3660  THROW_ERROR("Connected object not yet supported " + std::string(conn_obj->get_kind_text()));
3661  }
3663  " - adding connection between " << dest_port->get_path() << " and "
3664  << dest_obj->get_path());
3665  GetPointer<port_o>(dest_port)->add_connection(dest_obj);
3666  }
3667  }
3668  }
3669 
3670  for(const auto& index_constant : index_constants)
3671  {
3672  const structural_objectRef int_obj = index_constant.second;
3673  const structural_objectRef dest_el = dest->find_isomorphic(int_obj);
3675  " - copying the connections of constant: " << int_obj->get_path());
3676  const constant_o* constant = GetPointer<constant_o>(int_obj);
3677  for(unsigned int i = 0; i < constant->get_connected_objects_size(); i++)
3678  {
3679  const structural_objectRef conn_obj = constant->get_connection(i);
3680  std::string connected_path = conn_obj->get_path();
3681  if(connected_path.find(scope + "/") == std::string::npos)
3682  {
3683  continue;
3684  }
3686  structural_objectRef dest_obj;
3687  structural_objectRef conn_owner = conn_obj->get_owner();
3688  if(conn_owner->get_kind() != component_o_K || conn_owner->get_path() != get_path())
3689  {
3690  if(conn_owner->get_kind() == port_vector_o_K and conn_owner->get_owner()->get_path() != get_path())
3691  {
3692  conn_owner = conn_owner->get_owner();
3693  }
3694  dest_obj = dest->find_isomorphic(conn_owner);
3695  dest_obj = dest_obj->find_isomorphic(conn_obj);
3696  }
3697  else
3698  {
3699  dest_obj = dest->find_isomorphic(conn_obj);
3700  }
3701  if(GetPointer<port_o>(dest_obj))
3702  {
3703  GetPointer<port_o>(dest_obj)->add_connection(dest_el);
3704  }
3705  else
3706  {
3707  THROW_ERROR("Not expected object");
3708  }
3709 
3711  " - adding connection between " << dest_el->get_path() << " and " << dest_obj->get_path());
3712  GetPointer<constant_o>(dest_el)->add_connection(dest_obj);
3713  }
3714  }
3715 
3716  for(const auto& index_signal : index_signals)
3717  {
3718  const structural_objectRef int_obj = index_signal.second;
3719  std::vector<structural_objectRef> signal_objs;
3720  if(int_obj->get_kind() == signal_vector_o_K)
3721  {
3722  for(unsigned int p = 0; p < GetPointer<signal_o>(int_obj)->get_signals_size(); p++)
3723  {
3724  signal_objs.push_back(GetPointer<signal_o>(int_obj)->get_signal(p));
3725  }
3726  }
3727  signal_objs.push_back(int_obj);
3728  for(const auto& signal_obj : signal_objs)
3729  {
3730  const structural_objectRef signal_el = dest->find_isomorphic(signal_obj);
3732  " - copying the connections of signal: " << signal_obj->get_path());
3733  const signal_o* sig = GetPointer<signal_o>(signal_obj);
3734  for(unsigned int c = 0; c < sig->get_connected_objects_size(); c++)
3735  {
3736  const structural_objectRef conn_obj = sig->get_port(c);
3737  std::string connected_path = conn_obj->get_path();
3738  if(connected_path.find(scope + "/") == std::string::npos)
3739  {
3740  continue;
3741  }
3742  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - internal connection with: " << connected_path);
3743  structural_objectRef dest_obj;
3744  if(conn_obj->get_kind() == port_o_K || conn_obj->get_kind() == port_vector_o_K)
3745  {
3746  structural_objectRef conn_owner = conn_obj->get_owner();
3747  if(conn_owner->get_kind() != component_o_K || conn_owner->get_path() != get_path())
3748  {
3749  if(conn_owner->get_kind() == port_vector_o_K and conn_owner->get_owner()->get_path() != get_path())
3750  {
3751  conn_owner = conn_owner->get_owner();
3752  }
3753  dest_obj = dest->find_isomorphic(conn_owner);
3754  dest_obj = dest_obj->find_isomorphic(conn_obj);
3755  }
3756  else
3757  {
3758  dest_obj = dest->find_isomorphic(conn_obj);
3759  }
3760  GetPointer<port_o>(dest_obj)->add_connection(signal_el);
3761  }
3762  else
3763  {
3764  THROW_ERROR("Connected object not yet supported " + std::string(conn_obj->get_kind_text()));
3765  }
3767  " - adding connection between " << signal_el->get_path() << " and "
3768  << dest_obj->get_path());
3769  GetPointer<signal_o>(signal_el)->add_port(dest_obj);
3770  }
3771  }
3772  }
3773 
3774  for(auto l = index_bus_connections.begin(); l != index_bus_connections.end(); ++l)
3775  {
3776  THROW_ERROR("Copy of bus connections is not yet supported");
3777  }
3778 
3779  for(auto l = index_channels.begin(); l != index_channels.end(); ++l)
3780  {
3781  THROW_ERROR("Copy of bus connections is not yet supported");
3782  }
3783 
3784  if(NP_descriptions)
3785  {
3787  GetPointer<module>(dest)->set_NP_functionality(NP);
3788  }
3789  GetPointer<module>(dest)->set_description(description);
3790  GetPointer<module>(dest)->set_copyright(copyright);
3791  GetPointer<module>(dest)->set_authors(authors);
3792  GetPointer<module>(dest)->set_license(license);
3793 }
3794 
3796 {
3797  switch(key->get_kind())
3798  {
3799  case port_vector_o_K:
3800  case port_o_K:
3801  {
3802  port_o::port_direction port_dir = GetPointer<port_o>(key)->get_port_direction();
3803  switch(port_dir)
3804  {
3805  case port_o::IN:
3806  {
3807  for(const auto& in_port : in_ports)
3808  {
3809  if(in_port->get_id() == key->get_id())
3810  {
3811  return in_port;
3812  }
3813  }
3814  for(const auto& in_port : in_ports)
3815  {
3816  if(key->get_owner()->get_kind() != port_vector_o_K || in_port->get_kind() != port_vector_o_K)
3817  {
3818  continue;
3819  }
3820  if(key->get_owner()->get_id() != in_port->get_id())
3821  {
3822  continue;
3823  }
3825  if(iso)
3826  {
3827  return iso;
3828  }
3829  }
3830  THROW_ERROR("Something went wrong with module " + key->get_path() + " in " + get_path());
3831  break;
3832  }
3833  case port_o::OUT:
3834  {
3835  for(const auto& out_port : out_ports)
3836  {
3837  if(out_port->get_id() == key->get_id())
3838  {
3839  return out_port;
3840  }
3841  }
3842  for(const auto& out_port : out_ports)
3843  {
3844  if(key->get_owner()->get_kind() != port_vector_o_K || out_port->get_kind() != port_vector_o_K)
3845  {
3846  continue;
3847  }
3848  if(key->get_owner()->get_id() != out_port->get_id())
3849  {
3850  continue;
3851  }
3853  if(iso)
3854  {
3855  return iso;
3856  }
3857  }
3858  THROW_ERROR("Something went wrong with module " + key->get_path() + " in " + get_path());
3859  break;
3860  }
3861  case port_o::IO:
3862  {
3863  for(const auto& in_out_port : in_out_ports)
3864  {
3865  if(in_out_port->get_id() == key->get_id())
3866  {
3867  return in_out_port;
3868  }
3869  }
3870  for(const auto& in_out_port : in_out_ports)
3871  {
3872  if(key->get_owner()->get_kind() != port_vector_o_K || in_out_port->get_kind() != port_vector_o_K)
3873  {
3874  continue;
3875  }
3876  if(key->get_owner()->get_id() != in_out_port->get_id())
3877  {
3878  continue;
3879  }
3880  structural_objectRef iso = in_out_port->find_isomorphic(key);
3881  if(iso)
3882  {
3883  return iso;
3884  }
3885  }
3886  THROW_ERROR("Something went wrong with module " + key->get_path() + " in " + get_path());
3887  break;
3888  }
3889  case port_o::GEN:
3890  {
3891  for(const auto& gen_port : gen_ports)
3892  {
3893  if(gen_port->get_id() == key->get_id())
3894  {
3895  return gen_port;
3896  }
3897  }
3898  THROW_ERROR("Something went wrong with module " + key->get_path());
3899  break;
3900  }
3901  case port_o::TLM_IN:
3902  case port_o::TLM_INOUT:
3903  case port_o::TLM_OUT:
3904  case port_o::UNKNOWN:
3905  default:
3906  THROW_ERROR("Something went wrong with module " + key->get_path());
3907  }
3908  break;
3909  }
3910  case component_o_K:
3911  {
3912  auto it = index_components.find(key->get_id());
3913  if(it != index_components.end())
3914  {
3915  return it->second;
3916  }
3917  THROW_ERROR("Something went wrong with module " + key->get_path());
3918  break;
3919  }
3920  case channel_o_K:
3921  {
3922  auto it = index_channels.find(key->get_id());
3923  if(it != index_channels.end())
3924  {
3925  return it->second;
3926  }
3927  THROW_ERROR("Something went wrong with module " + key->get_path());
3928  break;
3929  }
3930  case constant_o_K:
3931  {
3932  auto it = index_constants.find(key->get_id());
3933  if(it != index_constants.end())
3934  {
3935  return it->second;
3936  }
3937  THROW_ERROR("Something went wrong with module " + key->get_path());
3938  break;
3939  }
3940  case signal_vector_o_K:
3941  case signal_o_K:
3942  {
3943  auto it = index_signals.find(key->get_id());
3944  if(it != index_signals.end())
3945  {
3946  return it->second;
3947  }
3948  if(key->get_owner()->get_kind() == signal_vector_o_K)
3949  {
3950  it = index_signals.find(key->get_owner()->get_id());
3951  if(it != index_signals.end())
3952  {
3953  return it->second->find_isomorphic(key);
3954  }
3955  }
3956  THROW_ERROR("Something went wrong! " + key->get_path() + " in " + get_path());
3957  break;
3958  }
3959  case bus_connection_o_K:
3960  {
3961  auto it = index_bus_connections.find(key->get_id());
3962  if(it != index_bus_connections.end())
3963  {
3964  return it->second;
3965  }
3966  break;
3967  }
3968  case action_o_K:
3969  case data_o_K:
3970  case event_o_K:
3971  default:
3972  THROW_ERROR("Something went wrong: " + key->get_path());
3973  }
3974  return structural_objectRef();
3975 }
3976 
3977 std::vector<std::string> get_connections(const xml_element* node)
3978 {
3979  std::vector<std::string> connections;
3980  const xml_node::node_list listC = node->get_children();
3981  for(const auto& itC : listC)
3982  {
3983  const auto* EnodeCC = GetPointer<const xml_element>(itC);
3984  if(!EnodeCC)
3985  {
3986  continue;
3987  }
3988  if(EnodeCC->get_name() == "connected_objects")
3989  {
3990  const xml_element::attribute_list Alist = EnodeCC->get_attributes();
3991  auto it_end = Alist.end();
3992  for(auto it = Alist.begin(); it != it_end; ++it)
3993  {
3994  connections.push_back((*it)->get_value());
3995  }
3996  }
3997  }
3998  return connections;
3999 }
4000 
4002 {
4003  structural_object::xload(Enode, _owner, CM);
4004  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - Loading module: " << this->get_id());
4005 
4006  std::map<structural_objectRef, std::vector<std::string>> connections;
4007 
4009  // Recourse through child nodes:
4010  const xml_node::node_list list = Enode->get_children();
4011  for(const auto& iter : list)
4012  {
4013  const auto* EnodeC = GetPointer<const xml_element>(iter);
4014  if(!EnodeC or EnodeC->get_name() == GET_CLASS_NAME(structural_type_descriptor))
4015  {
4016  continue;
4017  }
4018  if(!EnodeC or EnodeC->get_name() == "parameter")
4019  {
4020  continue;
4021  }
4022 
4023  if(EnodeC->get_name() == GET_CLASS_NAME(port_o) || EnodeC->get_name() == GET_CLASS_NAME(port_vector_o))
4024  {
4026  THROW_ASSERT(CE_XVM(dir, EnodeC), "Port has to have a direction." + std::to_string(EnodeC->get_line()));
4027  std::string dir_string;
4028  LOAD_XVFM(dir_string, EnodeC, dir);
4029  dir = port_o::to_port_direction(dir_string);
4030  if(EnodeC->get_name() == GET_CLASS_NAME(port_o))
4031  {
4033  obj = structural_objectRef(new port_o(debug_level, _owner, dir, port_o_K));
4034  obj->xload(EnodeC, obj, CM);
4035  connections[obj] = get_connections(EnodeC);
4036  }
4037  else if(EnodeC->get_name() == GET_CLASS_NAME(port_vector_o))
4038  {
4040  obj = structural_objectRef(new port_o(debug_level, _owner, dir, port_vector_o_K));
4041  obj->xload(EnodeC, obj, CM);
4042  const xml_node::node_list listC = EnodeC->get_children();
4043  for(const auto& iterC : listC)
4044  {
4045  const auto* EnodeCC = GetPointer<const xml_element>(iterC);
4046  if(!EnodeCC || EnodeCC->get_name() != GET_CLASS_NAME(port_o))
4047  {
4048  continue;
4049  }
4050  std::string id_string;
4051  LOAD_XVFM(id_string, EnodeCC, id);
4052  structural_objectRef port_obj = obj->find_member(id_string, port_o_K, obj);
4053  THROW_ASSERT(port_obj, "Port " + id_string + " not found in " + obj->get_path());
4054  connections[port_obj] = get_connections(EnodeCC);
4055  }
4056  }
4057  switch(dir)
4058  {
4059  case port_o::IN:
4060  {
4061  GetPointer<module>(_owner)->add_in_port(obj);
4062  break;
4063  }
4064  case port_o::OUT:
4065  {
4066  GetPointer<module>(_owner)->add_out_port(obj);
4067  break;
4068  }
4069  case port_o::IO:
4070  {
4071  GetPointer<module>(_owner)->add_in_out_port(obj);
4072  break;
4073  }
4074  case port_o::GEN:
4075  {
4076  GetPointer<module>(_owner)->add_gen_port(obj);
4077  break;
4078  }
4079  case port_o::TLM_IN:
4080  case port_o::TLM_INOUT:
4081  case port_o::TLM_OUT:
4082  case port_o::UNKNOWN:
4083  default:
4084  {
4085  THROW_ERROR("Port direction not foreseen");
4086  }
4087  }
4088  }
4089  else if(EnodeC->get_name() == GET_CLASS_NAME(component_o))
4090  {
4092  obj = structural_objectRef(new component_o(debug_level, _owner));
4093  obj->xload(EnodeC, obj, CM);
4094  GetPointer<module>(_owner)->add_internal_object(obj);
4095  }
4096  else if(EnodeC->get_name() == GET_CLASS_NAME(signal_o))
4097  {
4099  obj = structural_objectRef(new signal_o(debug_level, _owner, signal_o_K));
4100  obj->xload(EnodeC, obj, CM);
4101  GetPointer<module>(_owner)->add_internal_object(obj);
4102  connections[obj] = get_connections(EnodeC);
4103  }
4104  else if(EnodeC->get_name() == GET_CLASS_NAME(signal_vector_o))
4105  {
4106  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - Signal vector");
4108  obj->xload(EnodeC, obj, CM);
4109  GetPointer<module>(_owner)->add_internal_object(obj);
4110  const xml_node::node_list listC = EnodeC->get_children();
4111  for(const auto& iterC : listC)
4112  {
4113  const auto* EnodeCC = GetPointer<const xml_element>(iterC);
4114  if(!EnodeCC || EnodeCC->get_name() != GET_CLASS_NAME(signal_o))
4115  {
4116  continue;
4117  }
4118  std::string id_string;
4119  LOAD_XVFM(id_string, EnodeCC, id);
4120  structural_objectRef sig_obj = obj->find_member(id_string, signal_o_K, obj);
4121  connections[sig_obj] = get_connections(EnodeCC);
4122  }
4123  }
4124  else if(EnodeC->get_name() == GET_CLASS_NAME(constant_o))
4125  {
4127  obj = structural_objectRef(new constant_o(debug_level, _owner));
4128  obj->xload(EnodeC, obj, CM);
4129  GetPointer<module>(_owner)->add_internal_object(obj);
4130  connections[obj] = get_connections(EnodeC);
4131  }
4132  else if(EnodeC->get_name() == GET_CLASS_NAME(channel_o))
4133  {
4135  obj = structural_objectRef(new channel_o(debug_level, _owner));
4136  obj->xload(EnodeC, obj, CM);
4137  GetPointer<module>(_owner)->add_internal_object(obj);
4138  }
4139  else if(EnodeC->get_name() == GET_CLASS_NAME(bus_connection_o))
4140  {
4141  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - Bus connection");
4143  obj->xload(EnodeC, obj, CM);
4144  GetPointer<module>(_owner)->add_internal_object(obj);
4145  }
4146  else if(EnodeC->get_name() == GET_CLASS_NAME(data_o))
4147  {
4149  obj = structural_objectRef(new data_o(debug_level, _owner));
4150  obj->xload(EnodeC, obj, CM);
4151  GetPointer<module>(_owner)->add_local_data(obj);
4152  }
4153  else if(EnodeC->get_name() == GET_CLASS_NAME(event_o))
4154  {
4156  obj = structural_objectRef(new event_o(debug_level, _owner));
4157  obj->xload(EnodeC, obj, CM);
4158  GetPointer<module>(_owner)->add_event(obj);
4159  }
4160  else if(EnodeC->get_name() == GET_CLASS_NAME(action_o))
4161  {
4163  obj = structural_objectRef(new action_o(debug_level, _owner));
4164  obj->xload(EnodeC, obj, CM);
4165  if(GetPointer<action_o>(obj)->get_process_nservice())
4166  {
4167  GetPointer<module>(_owner)->add_process(obj);
4168  }
4169  else
4170  {
4171  GetPointer<module>(_owner)->add_service(obj);
4172  }
4173  }
4174  else if(EnodeC->get_name() == GET_CLASS_NAME(NP_functionality))
4175  {
4176  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - NP functionality");
4178  NP_descriptions->xload(EnodeC);
4179  }
4180  else if(EnodeC->get_name() == GET_CLASS_NAME(description))
4181  {
4182  const xml_text_node* text = EnodeC->get_child_text();
4183  if(!text)
4184  {
4185  THROW_WARNING("description is missing for " + EnodeC->get_name());
4186  }
4187  else
4188  {
4189  description = text->get_content();
4191  }
4192  }
4193  else if(EnodeC->get_name() == GET_CLASS_NAME(copyright))
4194  {
4195  const xml_text_node* text = EnodeC->get_child_text();
4196  if(!text)
4197  {
4198  THROW_WARNING("copyright is missing for " + EnodeC->get_name());
4199  }
4200  else
4201  {
4202  copyright = text->get_content();
4204  }
4205  }
4206  else if(EnodeC->get_name() == GET_CLASS_NAME(authors))
4207  {
4208  const xml_text_node* text = EnodeC->get_child_text();
4209  if(!text)
4210  {
4211  THROW_WARNING("authors are missing for " + EnodeC->get_name());
4212  }
4213  else
4214  {
4215  authors = text->get_content();
4217  }
4218  }
4219  else if(EnodeC->get_name() == GET_CLASS_NAME(license))
4220  {
4221  const xml_text_node* text = EnodeC->get_child_text();
4222  if(!text)
4223  {
4224  THROW_WARNING("license is missing for " + EnodeC->get_name());
4225  }
4226  else
4227  {
4228  license = text->get_content();
4230  }
4231  }
4232  else if(EnodeC->get_name() == GET_CLASS_NAME(specialized))
4233  {
4234  const xml_text_node* text = EnodeC->get_child_text();
4235  if(!text)
4236  {
4237  THROW_WARNING("specialization identifier is missing for " + EnodeC->get_name());
4238  }
4239  else
4240  {
4241  specialized = text->get_content();
4243  }
4244  }
4245  else if(EnodeC->get_name() == GET_CLASS_NAME(multi_unit_multiplicity))
4246  {
4247  const xml_text_node* text = EnodeC->get_child_text();
4248  if(!text)
4249  {
4250  THROW_WARNING("multi_unit_multiplicity identifier is missing for " + EnodeC->get_name());
4251  }
4252  else
4253  {
4254  std::string multi_unit_multiplicitySTR = text->get_content();
4255  xml_node::convert_escaped(multi_unit_multiplicitySTR);
4256  multi_unit_multiplicity = static_cast<unsigned>(std::stoul(multi_unit_multiplicitySTR));
4257  }
4258  }
4259  else if(EnodeC->get_name() == GET_CLASS_NAME(keep_hierarchy))
4260  {
4261  const xml_text_node* text = EnodeC->get_child_text();
4262  if(!text)
4263  {
4264  THROW_WARNING("keep_hierarchy identifier is missing for " + EnodeC->get_name());
4265  }
4266  else
4267  {
4268  std::string keep_hierarchySTR = text->get_content();
4269  xml_node::convert_escaped(keep_hierarchySTR);
4270  keep_hierarchy = static_cast<bool>(std::stoi(keep_hierarchySTR));
4271  }
4272  }
4273  else
4274  {
4275  THROW_ERROR("Internal object not yet supported: " + EnodeC->get_name());
4276  }
4277  }
4278 
4279  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - Loading the interconnetions");
4280  const std::string& scope = get_path();
4281  // Second turn to connect ports, signals and constants
4282  for(auto& connection : connections)
4283  {
4284  obj = connection.first;
4285  THROW_ASSERT(obj, "Object not valid");
4286  const std::vector<std::string>& conns = connection.second;
4288  " - Analyzing the connections of " << obj->get_path() << " (" << obj->get_kind_text()
4289  << "): " << conns.size());
4290  for(const auto& conn : conns)
4291  {
4293  if(conn.find(scope + "/") == std::string::npos)
4294  {
4295  continue;
4296  }
4297  std::string connected_path = conn;
4298  connected_path = connected_path.substr(scope.size() + 1, connected_path.size());
4299  std::vector<std::string> elements = SplitString(connected_path, HIERARCHY_SEPARATOR);
4301  " * Connected to " + connected_path << ": " << elements.size());
4302  structural_objectRef connnected_object;
4303  if(elements.size() == 1)
4304  {
4306  if((connnected_object = find_member(elements[0], constant_o_K, _owner)))
4307  {
4308  GetPointer<constant_o>(connnected_object)->add_connection(obj);
4309  }
4310  else if((connnected_object = find_member(elements[0], signal_o_K, _owner)) and
4311  !(obj->get_kind() == signal_o_K and obj->get_path() == connnected_object->get_path()))
4312  {
4313  GetPointer<signal_o>(connnected_object)->add_port(obj);
4314  }
4315  else if((connnected_object = find_member(elements[0], port_o_K, _owner)) and
4316  !(obj->get_kind() == port_o_K and obj->get_path() == connnected_object->get_path()))
4317  {
4318  GetPointer<port_o>(connnected_object)->add_connection(obj);
4319  }
4320  else
4321  {
4322  THROW_ERROR("Connected object " + connected_path + " cannot be found");
4323  }
4324  }
4325  else if(elements.size() == 2)
4326  {
4329  if((connnected_object = find_member(elements[0], component_o_K, _owner)))
4330  {
4331  if((connnected_object = connnected_object->find_member(elements[1], port_o_K, connnected_object)))
4332  {
4333  GetPointer<port_o>(connnected_object)->add_connection(obj);
4334  }
4335  else
4336  {
4337  THROW_ERROR("Connected object " + connected_path + " cannot be found");
4338  }
4339  }
4340  else if((connnected_object = find_member(elements[0], port_vector_o_K, _owner)))
4341  {
4342  if((connnected_object = connnected_object->find_member(elements[1], port_o_K, connnected_object)))
4343  {
4344  GetPointer<port_o>(connnected_object)->add_connection(obj);
4345  }
4346  else
4347  {
4348  THROW_ERROR("Connected object " + connected_path + " cannot be found");
4349  }
4350  }
4351  else if((connnected_object = find_member(elements[0], signal_vector_o_K, _owner)))
4352  {
4353  if((connnected_object = connnected_object->find_member(elements[1], signal_o_K, connnected_object)))
4354  {
4355  GetPointer<signal_o>(connnected_object)->add_port(obj);
4356  }
4357  else
4358  {
4359  THROW_ERROR("Connected object " + connected_path + " cannot be found");
4360  }
4361  }
4362  else
4363  {
4364  THROW_ERROR("Connected object " + connected_path + " cannot be found");
4365  }
4366  }
4367  else if(elements.size() == 3)
4368  {
4370  if((connnected_object = find_member(elements[0], component_o_K, _owner)))
4371  {
4372  if((connnected_object = connnected_object->find_member(elements[1], port_vector_o_K, connnected_object)))
4373  {
4374  if((connnected_object = connnected_object->find_member(elements[2], port_o_K, connnected_object)))
4375  {
4376  GetPointer<port_o>(connnected_object)->add_connection(obj);
4377  }
4378  else
4379  {
4380  THROW_ERROR("Connected object " + connected_path + " cannot be found");
4381  }
4382  }
4383  else
4384  {
4385  THROW_ERROR("Connected object " + connected_path + " cannot be found");
4386  }
4387  }
4388  else
4389  {
4390  THROW_ERROR("Connected object " + connected_path + " cannot be found");
4391  }
4392  }
4393  else
4394  {
4395  THROW_ERROR("Not supported connected size: " + std::to_string(elements.size()));
4396  }
4397  THROW_ASSERT(connnected_object, "Connected object not correctly identified: " + conn);
4399  " - Identified connection with " + connnected_object->get_path());
4400  if(GetPointer<constant_o>(obj))
4401  {
4402  GetPointer<constant_o>(obj)->add_connection(connnected_object);
4403  }
4404  else if(GetPointer<port_o>(obj))
4405  {
4406  GetPointer<port_o>(obj)->add_connection(connnected_object);
4407  }
4408  else if(GetPointer<signal_o>(obj))
4409  {
4410  GetPointer<signal_o>(obj)->add_port(connnected_object);
4411  }
4412  else
4413  {
4414  THROW_ERROR("Not expected type: " + std::string(obj->get_kind_text()));
4415  }
4416  }
4417  }
4418 
4419 #ifndef NDEBUG
4420  if(get_black_box())
4421  {
4423  " Component " + get_id() + " (" + get_typeRef()->id_type + ") is a black box");
4424  }
4425 #endif
4426 }
4427 
4429 {
4430  structural_object::xwrite(rootnode);
4431 
4432  xml_element* xml_description = rootnode->add_child_element("description");
4433  xml_description->add_child_text(description);
4434  xml_element* xml_copyright = rootnode->add_child_element("copyright");
4435  xml_copyright->add_child_text(copyright);
4436  xml_element* xml_authors = rootnode->add_child_element("authors");
4437  xml_authors->add_child_text(authors);
4438  xml_element* xml_license = rootnode->add_child_element("license");
4439  xml_license->add_child_text(license);
4440  if(specialized != "")
4441  {
4442  xml_element* xml_specialized = rootnode->add_child_element("specialized");
4443  xml_specialized->add_child_text(specialized);
4444  }
4445  if(keep_hierarchy)
4446  {
4447  xml_element* xml_keep_hierarchy = rootnode->add_child_element("keep_hierarchy");
4448  xml_keep_hierarchy->add_child_text("true");
4449  }
4450 
4451  if(in_ports.size())
4452  {
4453  for(auto& in_port : in_ports)
4454  {
4455  in_port->xwrite(rootnode);
4456  }
4457  }
4458  if(out_ports.size())
4459  {
4460  for(auto& out_port : out_ports)
4461  {
4462  out_port->xwrite(rootnode);
4463  }
4464  }
4465  if(in_out_ports.size())
4466  {
4467  for(auto& in_out_port : in_out_ports)
4468  {
4469  in_out_port->xwrite(rootnode);
4470  }
4471  }
4472 
4473  if(gen_ports.size())
4474  {
4475  for(auto& gen_port : gen_ports)
4476  {
4477  gen_port->xwrite(rootnode);
4478  }
4479  }
4480  if(internal_objects.size())
4481  {
4482  for(auto& internal_object : internal_objects)
4483  {
4484  internal_object->xwrite(rootnode);
4485  }
4486  }
4487 
4488  if(local_data.size())
4489  {
4490  for(auto& i : local_data)
4491  {
4492  i->xwrite(rootnode);
4493  }
4494  }
4495 
4496  if(list_of_event.size())
4497  {
4498  for(auto& i : list_of_event)
4499  {
4500  i->xwrite(rootnode);
4501  }
4502  }
4503 
4504  if(list_of_process.size())
4505  {
4506  for(auto& list_of_proces : list_of_process)
4507  {
4508  list_of_proces->xwrite(rootnode);
4509  }
4510  }
4511 
4512  if(list_of_service.size())
4513  {
4514  for(auto& i : list_of_service)
4515  {
4516  i->xwrite(rootnode);
4517  }
4518  }
4519 
4520  if(NP_descriptions)
4521  {
4522  NP_descriptions->xwrite(rootnode);
4523  }
4524 }
4525 
4526 #if HAVE_TECHNOLOGY_BUILT
4527 void module::xwrite_attributes(xml_element* rootnode, const technology_nodeRef& tn)
4528 {
4529  structural_object::xwrite_attributes(rootnode, tn);
4530 
4531  if(in_ports.size())
4532  {
4533  for(auto& in_port : in_ports)
4534  {
4535  in_port->xwrite_attributes(rootnode, tn);
4536  }
4537  }
4538  if(out_ports.size())
4539  {
4540  for(auto& out_port : out_ports)
4541  {
4542  out_port->xwrite_attributes(rootnode, tn);
4543  }
4544  }
4545  if(in_out_ports.size())
4546  {
4547  for(auto& in_out_port : in_out_ports)
4548  {
4549  in_out_port->xwrite_attributes(rootnode, tn);
4550  }
4551  }
4552 }
4553 #endif
4554 
4555 void module::print(std::ostream& os) const
4556 {
4557  PP(os, "MODULE:\n");
4559  PP(os, "[\n");
4560  if(in_ports.size())
4561  {
4562  for(unsigned int i = 0; i < in_ports.size(); i++)
4563  {
4564  os << "In " << i + 1 << ") " << in_ports[i];
4565  }
4566  }
4567  if(out_ports.size())
4568  {
4569  for(unsigned int i = 0; i < out_ports.size(); i++)
4570  {
4571  os << "Out " << i + 1 << ") " << out_ports[i];
4572  }
4573  }
4574  if(in_out_ports.size())
4575  {
4576  for(unsigned int i = 0; i < in_out_ports.size(); i++)
4577  {
4578  os << "IO " << i + 1 << ") " << in_out_ports[i];
4579  }
4580  }
4581 
4582  if(gen_ports.size())
4583  {
4584  for(unsigned int i = 0; i < gen_ports.size(); i++)
4585  {
4586  os << "GenP " << i + 1 << ") " << gen_ports[i];
4587  }
4588  }
4589 
4590  if(internal_objects.size())
4591  {
4592  for(unsigned int i = 0; i < internal_objects.size(); i++)
4593  {
4594  os << "Int " << i + 1 << ") " << internal_objects[i];
4595  }
4596  }
4597 
4598  if(local_data.size())
4599  {
4600  for(unsigned int i = 0; i < local_data.size(); i++)
4601  {
4602  os << "D " << i + 1 << ") " << local_data[i];
4603  }
4604  }
4605 
4606  if(list_of_event.size())
4607  {
4608  for(unsigned int i = 0; i < list_of_event.size(); i++)
4609  {
4610  os << "E " << i + 1 << ") " << list_of_event[i];
4611  }
4612  }
4613 
4614  if(list_of_process.size())
4615  {
4616  for(unsigned int i = 0; i < list_of_process.size(); i++)
4617  {
4618  os << "Proc " << i + 1 << ") " << list_of_process[i];
4619  }
4620  }
4621 
4622  if(list_of_service.size())
4623  {
4624  for(unsigned int i = 0; i < list_of_service.size(); i++)
4625  {
4626  os << "Serv " << i + 1 << ") " << list_of_service[i];
4627  }
4628  }
4629 
4630  if(NP_descriptions)
4631  {
4632  NP_descriptions->print(os);
4633  }
4634 
4635  os << description << std::endl;
4636  os << copyright << std::endl;
4637  os << authors << std::endl;
4638  os << license << std::endl;
4639  PP(os, "]\n");
4640 }
4641 
4643 {
4644  THROW_ASSERT(GetPointer<port_o>(port), "Expected a port_o object");
4645  THROW_ASSERT(GetPointer<port_o>(port)->get_port_direction() != pdir, "No need to change the direction");
4646  std::string _id = port->get_id();
4647  if(GetPointer<port_o>(port)->get_port_direction() == port_o::IN)
4648  {
4649  bool found = false;
4650  for(unsigned int i = 0; i < in_ports.size(); i++)
4651  {
4652  if(in_ports[i]->get_id() == _id || found)
4653  {
4654  found = true;
4655  if(i == in_ports.size() - 1)
4656  {
4657  in_ports.pop_back();
4658  }
4659  else
4660  {
4661  in_ports[i] = in_ports[i + 1];
4662  }
4663  }
4664  }
4665  }
4666  else if(pdir == port_o::IN)
4667  {
4668  in_ports.push_back(port);
4669  }
4670 
4671  if(GetPointer<port_o>(port)->get_port_direction() == port_o::OUT)
4672  {
4673  bool found = false;
4674  for(unsigned int i = 0; i < out_ports.size(); i++)
4675  {
4676  if(out_ports[i]->get_id() == _id || found)
4677  {
4678  found = true;
4679  if(i == out_ports.size() - 1)
4680  {
4681  out_ports.pop_back();
4682  }
4683  else
4684  {
4685  out_ports[i] = out_ports[i + 1];
4686  }
4687  }
4688  }
4689  }
4690  else if(pdir == port_o::OUT)
4691  {
4692  out_ports.push_back(port);
4693  }
4694 
4695  if(GetPointer<port_o>(port)->get_port_direction() == port_o::IO)
4696  {
4697  bool found = false;
4698 
4699  for(unsigned int i = 0; i < in_out_ports.size(); i++)
4700  {
4701  if(in_out_ports[i]->get_id() == _id || found)
4702  {
4703  found = true;
4704  if(i == in_out_ports.size() - 1)
4705  {
4706  in_out_ports.pop_back();
4707  }
4708  else
4709  {
4710  in_out_ports[i] = in_out_ports[i + 1];
4711  }
4712  }
4713  }
4714  }
4715  else if(pdir == port_o::IO)
4716  {
4717  in_out_ports.push_back(port);
4718  }
4719 
4720  if(GetPointer<port_o>(port)->get_port_direction() == port_o::GEN)
4721  {
4722  bool found = false;
4723  for(unsigned int i = 0; i < gen_ports.size(); i++)
4724  {
4725  if(gen_ports[i]->get_id() == _id || found)
4726  {
4727  found = true;
4728  if(i == gen_ports.size() - 1)
4729  {
4730  gen_ports.pop_back();
4731  }
4732  else
4733  {
4734  gen_ports[i] = gen_ports[i + 1];
4735  }
4736  }
4737  }
4738  }
4739  else if(pdir == port_o::GEN)
4740  {
4741  gen_ports.push_back(port);
4742  }
4743 
4744  GetPointer<port_o>(port)->set_port_direction(pdir);
4745 }
4746 
4747 void module::AddParameter(const std::string& name, const std::string& default_value)
4748 {
4749  if(name != MEMORY_PARAMETER)
4750  {
4751  if(not NP_descriptions)
4752  {
4753  NP_descriptions = NP_functionalityRef(new NP_functionality);
4754  NP_descriptions->add_NP_functionality(NP_functionality::LIBRARY, get_id());
4755  }
4756  NP_descriptions->add_NP_functionality(
4757  NP_functionality::LIBRARY, NP_descriptions->get_NP_functionality(NP_functionality::LIBRARY) + " " + name);
4758  }
4759  structural_object::AddParameter(name, default_value);
4760 }
4761 
4762 component_o::component_o(int _debug_level, const structural_objectRef o) : module(_debug_level, o)
4763 {
4764 }
4765 
4767  const structural_objectRef _owner) const
4768 {
4769  return module::find_member(_id, _type, _owner);
4770 }
4771 
4773 {
4774  module::copy(dest);
4775 }
4776 
4778 {
4779  return module::find_isomorphic(key);
4780 }
4781 
4783 {
4784  module::xload(Enode, _owner, CM);
4785 }
4786 
4788 {
4789  xml_element* Enode = rootnode->add_child_element(get_kind_text());
4790  module::xwrite(Enode);
4791 }
4792 
4793 #if HAVE_TECHNOLOGY_BUILT
4794 void component_o::xwrite_attributes(xml_element* rootnode, const technology_nodeRef& tn)
4795 {
4796  module::xwrite_attributes(rootnode, tn);
4797 }
4798 #endif
4799 
4800 void component_o::print(std::ostream& os) const
4801 {
4802  os << "COMPONENT-";
4803  module::print(os);
4804 }
4805 
4806 channel_o::channel_o(int _debug_level, const structural_objectRef o) : module(_debug_level, o)
4807 {
4808 }
4809 
4810 void channel_o::add_interface(unsigned int t, const std::string& _interface)
4811 {
4812  impl_interfaces[t] = _interface;
4813 }
4814 
4815 const std::string& channel_o::get_interface(unsigned int t) const
4816 {
4817  return impl_interfaces.find(t)->second;
4818 }
4819 
4821 {
4822  THROW_ASSERT(p, "NULL object received");
4823  THROW_ASSERT(GetPointer<port_o>(p), "A port is expected");
4824  connected_objects.push_back(p);
4825 }
4826 
4827 const structural_objectRef channel_o::get_port(unsigned int n) const
4828 {
4829  THROW_ASSERT(n < connected_objects.size(), "index out of range");
4830  return connected_objects[n].lock();
4831 }
4832 
4834 {
4835  return static_cast<unsigned int>(connected_objects.size());
4836 }
4837 
4839  const structural_objectRef _owner) const
4840 {
4841  structural_objectRef mod = module::find_member(_id, _type, _owner);
4842  if(mod)
4843  {
4844  return mod;
4845  }
4846  switch(_type)
4847  {
4848  case port_o_K:
4849  {
4850  for(const auto& connected_object : connected_objects)
4851  {
4852  if(connected_object.lock()->get_id() == _id && connected_object.lock()->get_owner() == _owner)
4853  {
4854  return connected_object.lock();
4855  }
4856  }
4857  break;
4858  }
4859  case action_o_K:
4860  case bus_connection_o_K:
4861  case channel_o_K:
4862  case component_o_K:
4863  case constant_o_K:
4864  case data_o_K:
4865  case event_o_K:
4866  case port_vector_o_K:
4867  case signal_o_K:
4868  case signal_vector_o_K:
4869  default:
4870  break;
4871  }
4872  return mod;
4873 }
4874 
4876 {
4877  module::copy(dest);
4878  auto it_end = impl_interfaces.end();
4879  for(auto it = impl_interfaces.begin(); it != it_end; ++it)
4880  {
4881  GetPointer<channel_o>(dest)->add_interface(it->first, it->second);
4882  }
4884 }
4885 
4887 {
4890  if(mod_find)
4891  {
4892  return mod_find;
4893  }
4894  else
4895  {
4896  switch(key->get_kind())
4897  {
4898  case port_o_K:
4899  {
4901 
4902  if(key->get_owner()->get_id() == get_owner()->get_id())
4903  {
4904  return get_owner()->find_isomorphic(key);
4906  }
4907  else
4908  {
4910  return get_owner()->find_isomorphic(key->get_owner())->find_isomorphic(key);
4911  }
4912  break;
4913  }
4914  case action_o_K:
4915  case component_o_K:
4916  case bus_connection_o_K:
4917  case channel_o_K:
4918  case constant_o_K:
4919  case data_o_K:
4920  case event_o_K:
4921  case port_vector_o_K:
4922  case signal_o_K:
4923  case signal_vector_o_K:
4924  default:
4925  THROW_ERROR("Something went wrong!");
4926  }
4927  }
4928  return structural_objectRef();
4929 }
4930 
4932 {
4933  module::xload(Enode, _owner, CM);
4934  // Recourse through child nodes:
4935  const xml_node::node_list list = Enode->get_children();
4936  for(const auto& iter : list)
4937  {
4938  const auto* EnodeC = GetPointer<const xml_element>(iter);
4939  if(!EnodeC)
4940  {
4941  continue;
4942  }
4943  if(EnodeC->get_name() == "impl_interfaces")
4944  {
4945  const xml_element::attribute_list Alist = EnodeC->get_attributes();
4946  auto it_end = Alist.end();
4947  for(auto it = Alist.begin(); it != it_end; ++it)
4948  {
4949  impl_interfaces[static_cast<unsigned>(std::stoul((*it)->get_name().substr(2)))] = (*it)->get_value();
4950  }
4951  }
4952  }
4953 }
4954 
4956 {
4957  xml_element* Enode = rootnode->add_child_element(get_kind_text());
4958  module::xwrite(Enode);
4959  xml_element* Enode_II = Enode->add_child_element("impl_interfaces");
4960  auto it_end = impl_interfaces.end();
4961  for(auto it = impl_interfaces.begin(); it != it_end; ++it)
4962  {
4963  WRITE_XNVM2("II" + std::to_string(it->first), it->second, Enode_II);
4964  }
4965  xml_element* Enode_CO = Enode->add_child_element("connected_objects");
4966  for(unsigned int i = 0; i < connected_objects.size(); i++)
4967  {
4968  WRITE_XNVM2("CON" + std::to_string(i), connected_objects[i].lock()->get_path(), Enode_CO);
4969  }
4970 }
4971 
4972 #if HAVE_TECHNOLOGY_BUILT
4973 void channel_o::xwrite_attributes(xml_element* rootnode, const technology_nodeRef& tn)
4974 {
4975  module::xwrite_attributes(rootnode, tn);
4976 }
4977 #endif
4978 
4979 void channel_o::print(std::ostream& os) const
4980 {
4981  os << "CHANNEL-";
4982  module::print(os);
4983  PP(os, "[");
4984  if(impl_interfaces.size())
4985  {
4986  PP(os, "List of the interfaces:\n");
4987  }
4988  for(const auto& impl_interface : impl_interfaces)
4989  {
4990  os << " @(" << impl_interface.first << ") " << impl_interface.second;
4991  PP(os, "\n");
4992  }
4993  for(const auto& connected_object : connected_objects)
4994  {
4995  os << connected_object.lock()->get_path() + "-" + convert_so_short(connected_object.lock()->get_kind()) << " ";
4996  }
4997  PP(os, "\n]\n");
4998 }
4999 
5001 {
5002 }
5003 
5005 {
5006  THROW_ASSERT(c, "NULL object received");
5007  connections.push_back(c);
5008 }
5009 
5011 {
5012  THROW_ASSERT(n < connections.size(), "index out of range");
5013  return connections[n].lock();
5014 }
5015 
5017 {
5018  return static_cast<unsigned int>(connections.size());
5019 }
5020 
5022 {
5023  THROW_ERROR("Something went wrong!");
5024  return structural_objectRef();
5025 }
5026 
5028  const structural_objectRef _owner) const
5029 {
5030  switch(_type)
5031  {
5032  case signal_o_K:
5033  case port_o_K:
5034  {
5035  for(const auto& connection : connections)
5036  {
5037  if(connection.lock()->get_id() == _id && connection.lock()->get_owner() == _owner)
5038  {
5039  return connection.lock();
5040  }
5041  }
5042  break;
5043  }
5044  case action_o_K:
5045  case component_o_K:
5046  case bus_connection_o_K:
5047  case channel_o_K:
5048  case constant_o_K:
5049  case data_o_K:
5050  case event_o_K:
5051  case port_vector_o_K:
5052  case signal_vector_o_K:
5053  default:
5054  THROW_ERROR("Structural object not foreseen");
5055  }
5056  return structural_objectRef();
5057 }
5058 
5060 {
5063 }
5064 
5066 {
5067  structural_object::xload(Enode, _owner, CM);
5068 }
5069 
5071 {
5072  xml_element* Enode = rootnode->add_child_element(get_kind_text());
5074 }
5075 
5076 void bus_connection_o::print(std::ostream& os) const
5077 {
5078  PP(os, "BUS CONNECTION:\n");
5080  PP(os, "[\n");
5081  if(connections.size())
5082  {
5083  PP(os, "List of connections:\n");
5084  }
5085  for(const auto& connection : connections)
5086  {
5087  os << connection.lock()->get_path() + "-" + convert_so_short(connection.lock()->get_kind()) << " ";
5088  }
5089  PP(os, "\n]\n");
5090 }
5091 
5092 void port_o::add_n_ports(unsigned int n_ports, structural_objectRef _owner)
5093 {
5094  THROW_ASSERT(port_type == port_vector_o_K, "the port " + get_path() + " has to be of type port_vector_o_K");
5095  THROW_ASSERT(_owner.get() == this, "owner and this has to be the same object");
5096  THROW_ASSERT(n_ports != PARAMETRIC_PORT, "a number of port different from PARAMETRIC_PORT is expected");
5097  THROW_ASSERT(get_typeRef(), "the port vector has to have a type descriptor");
5098 
5099  unsigned int currentPortNumber = this->get_ports_size();
5100  for(unsigned int i = 0; i < n_ports; i++)
5101  {
5103  p->set_type(get_typeRef());
5104  p->set_id(std::to_string(currentPortNumber + i));
5105  ports.push_back(p);
5106  }
5107  THROW_ASSERT(port_type == port_vector_o_K, "inconsistent data structure");
5108 }
5109 
5110 const structural_objectRef port_o::get_port(unsigned int n) const
5111 {
5112  THROW_ASSERT(port_type == port_vector_o_K, "the port " + get_path() + " has to be of type port_vector_o_K");
5113  THROW_ASSERT(n < ports.size(), "index out of range: " + get_path() + " " + STR(n) + "/" + STR(ports.size()));
5114  return ports[n];
5115 }
5116 
5117 unsigned int port_o::get_ports_size() const
5118 {
5119  THROW_ASSERT(port_type == port_vector_o_K, "the port " + get_path() + " has to be of type port_vector_o_K");
5120  return static_cast<unsigned int>(ports.size());
5121 }
5122 
5123 void port_o::set_port_size(unsigned int dim)
5124 {
5125  get_typeRef()->size = dim;
5126 }
5127 
5128 unsigned long long port_o::get_port_size() const
5129 {
5130  return get_typeRef()->size;
5131 }
5132 
5133 bool port_o::resize_if_busport(unsigned long long bus_size_bitsize, unsigned long long bus_addr_bitsize,
5134  unsigned long long bus_data_bitsize, unsigned long long bus_tag_bitsize,
5135  structural_objectRef port)
5136 {
5137  const auto bus_bitsize = GetPointer<port_o>(port)->get_is_data_bus() ? bus_data_bitsize :
5138  GetPointer<port_o>(port)->get_is_addr_bus() ? bus_addr_bitsize :
5139  GetPointer<port_o>(port)->get_is_size_bus() ? bus_size_bitsize :
5140  GetPointer<port_o>(port)->get_is_tag_bus() ? bus_tag_bitsize :
5141  0U;
5142  if(bus_bitsize)
5143  {
5144  port->type_resize(bus_bitsize);
5145  if(port->get_kind() == port_vector_o_K)
5146  {
5147  for(auto pi = 0U; pi < GetPointer<port_o>(port)->get_ports_size(); ++pi)
5148  {
5149  const auto port_d = GetPointer<port_o>(port)->get_port(pi);
5150  port_d->type_resize(bus_bitsize);
5151  }
5152  }
5153  }
5154  return bus_bitsize;
5155 }
5156 
5157 void port_o::resize_std_port(unsigned long long bitsize_variable, unsigned long long n_elements,
5159 {
5160  if(n_elements == 0)
5161  {
5163  "---Specializing port " + port->get_path() + " " + STR(bitsize_variable));
5164  if(port->get_kind() == port_vector_o_K)
5165  {
5166  THROW_ASSERT(GetPointer<port_o>(port)->get_ports_size(),
5167  "Number of ports not specialized for " + port->get_path());
5168  for(unsigned int pi = 0; pi < GetPointer<port_o>(port)->get_ports_size(); ++pi)
5169  {
5170  structural_objectRef port_d = GetPointer<port_o>(port)->get_port(pi);
5171  port_d->type_resize(bitsize_variable);
5172  }
5173  }
5174  port->type_resize(bitsize_variable);
5175  }
5176  else
5177  {
5179  "---Specializing port " + port->get_path() + " " + STR(bitsize_variable) + ":" + STR(n_elements));
5180  if(port->get_kind() == port_vector_o_K)
5181  {
5182  THROW_ASSERT(GetPointer<port_o>(port)->get_ports_size(), "Number of ports not specialized");
5183  for(unsigned int pi = 0; pi < GetPointer<port_o>(port)->get_ports_size(); ++pi)
5184  {
5185  structural_objectRef port_d = GetPointer<port_o>(port)->get_port(pi);
5186  port_d->type_resize(bitsize_variable, n_elements);
5187  }
5188  }
5189  port->type_resize(bitsize_variable, n_elements);
5190  }
5191 }
5192 
5194 {
5195  if(GetPointer<port_o>(port_i)->get_port_interface() != port_o::port_interface::PI_DEFAULT)
5196  {
5197  GetPointer<port_o>(cir_port)->set_port_interface(GetPointer<port_o>(port_i)->get_port_interface());
5198  }
5199  if(GetPointer<port_o>(port_i)->get_port_alignment() != port_interface_alignment_DEFAULT)
5200  {
5201  GetPointer<port_o>(cir_port)->set_port_alignment(GetPointer<port_o>(port_i)->get_port_alignment());
5202  }
5203  if(GetPointer<port_o>(port_i)->get_is_extern())
5204  {
5205  GetPointer<port_o>(cir_port)->set_is_extern(true);
5206  }
5207  if(GetPointer<port_o>(port_i)->get_is_global())
5208  {
5209  GetPointer<port_o>(cir_port)->set_is_global(true);
5210  }
5211  if(GetPointer<port_o>(port_i)->get_is_memory())
5212  {
5213  GetPointer<port_o>(cir_port)->set_is_memory(true);
5214  }
5215  if(GetPointer<port_o>(port_i)->get_is_slave())
5216  {
5217  GetPointer<port_o>(cir_port)->set_is_slave(true);
5218  }
5219  if(GetPointer<port_o>(port_i)->get_is_master())
5220  {
5221  GetPointer<port_o>(cir_port)->set_is_master(true);
5222  }
5223  if(GetPointer<port_o>(port_i)->get_is_data_bus())
5224  {
5225  GetPointer<port_o>(cir_port)->set_is_data_bus(true);
5226  }
5227  if(GetPointer<port_o>(port_i)->get_is_addr_bus())
5228  {
5229  GetPointer<port_o>(cir_port)->set_is_addr_bus(true);
5230  }
5231  if(GetPointer<port_o>(port_i)->get_is_size_bus())
5232  {
5233  GetPointer<port_o>(cir_port)->set_is_size_bus(true);
5234  }
5235  if(GetPointer<port_o>(port_i)->get_is_tag_bus())
5236  {
5237  GetPointer<port_o>(cir_port)->set_is_tag_bus(true);
5238  }
5239  if(GetPointer<port_o>(port_i)->get_is_doubled())
5240  {
5241  GetPointer<port_o>(cir_port)->set_is_doubled(true);
5242  }
5243  if(GetPointer<port_o>(port_i)->get_is_halved())
5244  {
5245  GetPointer<port_o>(cir_port)->set_is_halved(true);
5246  }
5247 }
5248 
5249 #define __TO_STRING_HELPER(r, data, elem) {data::elem, BOOST_PP_STRINGIZE(elem)},
5250 #define TO_STRING(enum_type, elem_list) \
5251  static const std::unordered_map<enum enum_type, std::string> to_string = { \
5252  BOOST_PP_SEQ_FOR_EACH(__TO_STRING_HELPER, enum_type, elem_list)}
5253 
5254 std::string port_o::GetString(enum port_o::port_interface v)
5255 {
5256  TO_STRING(port_interface, PORT_INTERFACE_ENUM);
5257  return to_string.at(v);
5258 }
5259 
5260 std::string port_o::GetString(enum port_o::port_direction v)
5261 {
5262  TO_STRING(port_direction, PORT_DIRECTION_ENUM);
5263  return to_string.at(v);
5264 }
void xwrite(xml_element *rootnode) override
Add a structural_object to an xml tree.
void set_is_doubled(bool c)
set the is_doubled attribute.
void remove_connection(structural_objectRef s)
remove a connection (signal/port) from this
void print(std::ostream &os) const override
Print the bus_connection_o (for debug purpose)
void substitute_connection(structural_objectRef old_conn, structural_objectRef new_conn)
bool is_reverse
when true the port is dumped as [0:msb-1] instead of [msb-1:0]
virtual unsigned long long get_size(unsigned int var) const
Return the size in bit of a C object.
std::vector< structural_objectRef > list_of_event
List of event associated with the module.
virtual bool is_a_complex(unsigned int index) const
Return true if index is a variable or a type of type complex.
void set_action_type(process_type at)
Set the type of the action.
void pi(UINT64 *A)
Definition: Keccak.c:102
static const bool is_addr_bus_DEFAULT
void remove_internal_object(structural_objectRef s)
void copy(structural_objectRef dest) const override
Perform a copy of the module.
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
void remove_port(const std::string &id)
remove a port from the module
std::vector< structural_objectRef > local_data
List of local data associated with the module.
void set_description(const std::string &d)
Set the description associated with the module.
unsigned int get_ports_size() const
Return the number of ports.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
std::string get_bus_bundle() const
Returns the bus bundle identifier, if any.
TVMValue param[3]
static const char * s_typeNames[]
store the names of the enumerative s_type.
void copy(structural_objectRef dest) const override
Perform a copy of the component.
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.
void xwrite(xml_element *rootnode) override=0
Add a structural_object to an xml tree.
This class describes a generic data declaration object.
refcount< NP_functionality > NP_functionalityRef
RefCount type definition of the connection class structure.
void set_is_global(bool c)
set the is_global attribute.
const structural_objectRef get_internal_object(unsigned int n) const
Return the ith internal objects.
#define PRINT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
const std::string & get_interface(unsigned int t) const
Return the interface with a given treenode.
void set_is_var_args(bool c)
set the is var_args attribute.
void set_port_size(unsigned int dim)
Set port size.
unsigned int get_connected_objects_size() const
Return the number of ports associated with the connection.
#define DEBUG_LEVEL_PEDANTIC
very verbose debugging print is performed.
structural_objectRef find_isomorphic(const structural_objectRef key) const override
Find key in this object.
bool get_is_memory() const
return true if the port is a memory port
Structure representing the most relevant information about the type of a structural object...
const structural_objectRef get_signal(unsigned int n) const
Return the ith port of the vector.
void set_multi_unit_multiplicity(unsigned int value)
set_multi_unit_multiplicity
const std::string & get_id() const
Return the identifier associated with the structural_object.
bool get_is_addr_bus() const
return true if the port works as an address bus
structural_objectRef find_bounded_object(const structural_objectConstRef f_owner=structural_objectConstRef()) const
Find the object bounded to the port.
std::vector< structural_objectRef > signals_
The list of signals associated with the vector of signals.
bool get_critical() const
return if the component is critical or not
std::map< std::string, structural_objectRef > index_channels
index for channels this table is used to quickly search internal channels used by find_member and fin...
Simple pretty print functor.
so_kind
Enumerative type for structural object classes, it is used with get_kind() function to know the actua...
char base
This version is stamped on May 10, 2016.
Definition: nussinov.c:24
std::list< xml_attribute * > attribute_list
const structural_objectRef get_port(unsigned int n) const
Return the ith port of the vector.
void set_generated()
set the component as generated
structural_objectRef find_member(const std::string &id, so_kind type, const structural_objectRef owner) const override
Return the object named id of a given type which belongs to or it is associated with the object...
void set_scope(const std::string &sc)
Set the scope of the action.
bus_connection_o(int debug_level, const structural_objectRef o)
Constructor.
static std::string GetString(enum port_direction)
std::string description
Store the module description.
This class describes a port associated with a component or a channel.
const std::vector< std::string > SplitString(const std::string &input, const std::string &separators)
Function which splits a string into tokens.
std::string get_kind_text() const override
return the name of the class as a string.
void xload(const xml_element *Enode, structural_objectRef owner, structural_managerRef const &CM) override
Load a structural_object starting from an xml file.
unsigned int get_service_size() const
Return the number of services.
static const bool black_box_DEFAULT
structural_objectRef find_isomorphic(const structural_objectRef key) const override
Find key in this object.
bool is_a_vector(unsigned int variable) const
Return true if index is a variable or a type of type vector.
This class describes a generic channel.
structural_objectRef find_member(const std::string &id, so_kind type, const structural_objectRef owner) const override
Return the object named id of a given type which belongs to or it is associated with the object...
bool is_critical
when true the signal is involved into the critical path of the netlist
static const bool is_memory_DEFAULT
unsigned int get_out_port_size() const
Return the number of output ports.
void set_owner(const structural_objectRef new_owner)
set the owner of the structural object
bool get_critical() const
return if the component is critical or not
bool is_data_bus
when true the port is a data bus
void set_is_extern(bool c)
set the is_extern attribute.
void set_license(const std::string &l)
Set the license associated with the module.
std::string specialized
when non empty it defines with respect what module has been specialized
void set_is_tag_bus(bool c)
set the is_tag_bus attribute.
void add_event_to_sensitivity(structural_objectRef e)
Add an event to the sensitivity list of the action.
#define MEMORY_PARAMETER
#define NP
Definition: doitgen.h:41
std::vector< structural_objectRef > list_of_service
List of services associated with the module.
std::map< std::string, structural_objectRef > index_bus_connections
index for bus_connections this table is used to quickly search internal bus_connections used by find_...
CustomOrderedMap< T, U > CustomMap
Definition: custom_map.hpp:167
void print(std::ostream &os) const override
Print the component (for debug purpose)
exceptions managed by PandA
port_direction dir
direction of a port
bool get_is_halved() const
return true if the port has a halved size w.r.t the precision
structural_objectRef find_member(const std::string &id, so_kind type, const structural_objectRef owner) const override
Return the object named id of a given type which belongs to or it is associated with the object...
const structural_objectRef get_in_port(unsigned int n) const
Return the ith input port.
unsigned int lsb
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...
virtual std::string print_type(unsigned int type, bool global=false, bool print_qualifiers=false, bool print_storage=false, unsigned int var=0, const var_pp_functorConstRef vppf=var_pp_functorConstRef(), const std::string &prefix="", const std::string &tail="") const
Print a type and its variable in case var is not zero.
void add_port(structural_objectRef p)
Bind the connection object with a port.
structural_objectRef find_isomorphic(const structural_objectRef key) const override
Find key in this object.
bool is_connected(structural_objectRef s) const
structural_objectRef find_isomorphic(const structural_objectRef key) const override
Find key in this object.
void copy(structural_objectRef dest) const override
Perform a copy of the data.
#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
void remove_port(structural_objectRef s)
remove the connection of this signal with a port
bool is_critical
when true the port is involved into the critical path of the netlist
void copy(structural_objectRef dest) const override
Perform a copy of the action.
void set_bus_bundle(const std::string &name)
Sets the bus bundle identifier.
std::vector< structural_objectRef > in_out_ports
Input-output ports of this module.
void print(std::ostream &os) const override
Print the constant value (for debug purpose)
void set_treenode(unsigned int n)
Set the treenode id associated with the structural_object.
#define min(x, y)
unsigned int get_internal_objects_size() const
Return the number of internal objects.
xml_text_node * add_child_text(const std::string &content)
Append a new text node.
Definition: xml_node.cpp:68
unsigned int get_connected_objects_size() const
Return the number of ports associated with the connection.
bool get_is_var_args() const
return true if the port is a var_args
This class describes a generic systemC action.
Class specification of the manager of the technology library data structures.
structural_type_descriptorRef type
The description of the type.
virtual bool is_an_array(unsigned int variable) const
Return true if index is a variable or a type of type array.
void add_connection(structural_objectRef p)
Bind the element object with a port/signal.
std::vector< structural_objectRef > gen_ports
generic ports of this module
unsigned int get_event_size() const
Return the number of events.
bool is_size_bus
when true the port is a size bus
std::map< std::string, structural_objectRef > index_constants
index for constants this table is used to quickly search internal constants used by find_member and f...
#define PORT_DIRECTION_ENUM
void set_fun_id(unsigned int id)
Function that set the function with the action.
std::string legalize(const std::string &id)
void copy(structural_objectRef dest) const override
Perform a copy of the channel.
void xload(const xml_element *Enode, structural_objectRef owner, structural_managerRef const &CM) override=0
Load a structural_object starting from an xml file.
std::string convert_so_short(so_kind in) const
Convert a so_kind in a short string.
const structural_objectRef get_parameter(unsigned int n) const
Return the ith input parameter.
virtual bool is_unsigned(unsigned int index) const
Return true if index is a variable or a type of type unsigned int.
bool is_halved
when true the port has a halfed size
unsigned int get_multi_unit_multiplicity() const
get_multi_unit_multiplicity
void xload(const xml_element *Enode, structural_objectRef owner, structural_managerRef const &CM) override
Load a structural_object starting from an xml file.
void set_critical()
set the port as critical with respect to the timing path
data_o(int debug_level, const structural_objectRef o)
Constructor.
unsigned int get_gen_port_size() const
Return the number of generic ports.
const structural_objectRef get_process(unsigned int n) const
Return the ith process.
std::string GetParameter(std::string name) const
Get the value associated to parameter if it has been associated; if it has not specified returns the ...
so_kind port_type
port type
void copy(structural_objectRef dest) const override
Perform a copy of the event.
unsigned int get_signals_size() const
Return the number of ports.
void set_is_data_bus(bool c)
set the is_data attribute.
virtual void xwrite(xml_element *Enode)
Add a structural_object to an xml tree.
#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
static const bool is_master_DEFAULT
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
static const bool is_extern_DEFAULT
int key[32]
Definition: aes.h:67
#define max
Definition: backprop.h:17
static const char * process_typeNames[]
Redefinition of get_kind_text()
s_type type
The type of the port or the signal.
structural_objectRef find_member(const std::string &id, so_kind type, const structural_objectRef owner) const override
Return the object named id of a given type which belongs to or it is associated with the object...
port_direction
Enumerative type describing the direction of a port.
bool get_is_size_bus() const
return true if the port works as a size bus
bool is_extern
when true the port is an extern port
static const bool is_reverse_DEFAULT
unsigned long long size
The size of the object (in bit). The objects having a size are: ports, signals, channels, data, and actions.
std::map< unsigned int, std::string > impl_interfaces
List of the interfaces associated with the channel.
unsigned int function_id
The index of the function which represents the behavior.
structural_objectRef find_isomorphic(const structural_objectRef key) const override
Find key in this object.
virtual bool is_a_pointer(unsigned int variable) const
Return true if index is a variable or a type of type pointer.
std::string copyright
Store the copyright description.
static bool check_type(structural_type_descriptorRef src_type, structural_type_descriptorRef dest_type)
Check if two type descriptors are consistent.
virtual void AddParameter(const std::string &name, const std::string &default_value)
Add a parameter.
bool is_connected(structural_objectRef s) const
std::string id
Identifier for this component.
std::vector< structural_objectRef > parameters
The method procedure parameter.
bool is_addr_bus
when true the port is an address bus
const structural_objectRef get_event(unsigned int n) const
Return the ith event.
unsigned int get_local_data_size() const
Return the number of local data.
void xload(const xml_element *Enode, structural_objectRef owner, structural_managerRef const &CM) override
Load a structural_object starting from an xml file.
enum so_kind get_kind() const override
return the type of the class
#define PORT_INTERFACE_ENUM
#define ASSERT_PARAMETER(parameter)
Definition: utility.hpp:96
virtual std::string get_kind_text() const =0
Virtual function used to get the string name of a structural_object instance.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
Definition: exceptions.hpp:292
void set_is_slave(bool c)
set the is_slave attribute.
static const bool is_size_bus_DEFAULT
const structural_objectRef get_port(unsigned int n) const
Return the ith port bounded to the connection.
void xwrite(xml_element *rootnode) override
Add a structural_object to an xml tree.
bool is_generated
when true the component has been internally generated
void set_port_alignment(unsigned int algn)
Set the port interface alignment.
bool get_is_extern() const
return true if the port is extern
s_type
Define the possible type of a structural object.
void set_is_clock(bool c)
set the is clock attribute.
bool is_var_args() const
True if one of the ports of the module has the attribute is_var_args=true.
structural_objectRef find_isomorphic(const structural_objectRef key) const override
Find key in this object.
void xload(const xml_element *Enode)
Load a NP_functionality starting from an xml file.
const structural_objectRef get_connection(unsigned int n) const
Return a connection.
structural_objectRef get_connection(unsigned int idx) const
Return the ith element bounded to the connection.
static const unsigned int vector_size_DEFAULT
unsigned int get_parameters_size() const
Return the number of the parameters.
void set_is_memory(bool c)
set the is_memory attribute.
static const uint32_t k[]
Definition: sha-256.c:22
std::string GetDefaultParameter(std::string name) const
Get the value associated to parameter if it has been associate; It throws an exception if it has not ...
void add_out_port(structural_objectRef p)
Add an output port.
std::vector< Wrefcount< structural_object > > connected_objects
List of ports bound to the signal object.
#define TO_STRING(enum_type, elem_list)
void xload(const xml_element *Enode, structural_objectRef owner, structural_managerRef const &CM) override
Load a structural_object starting from an xml file.
port_endianess
Enumerative type describing the endianess of a port; NONE means that it has not been specified yet...
Class specification of the data structures used to manage technology information. ...
const std::string get_path() const
Return a unique identifier of the structural object.
void xload(const xml_element *Enode, structural_objectRef owner, structural_managerRef const &CM) override
Load a structural_object starting from an xml file.
unsigned int get_treenode() const
Return the treenode id associated with the structural_object.
void get_NP_library_parameters(structural_objectRef owner, std::vector< std::pair< std::string, structural_objectRef >> &parameters) const
Return the list of object that can be parametrized.
bool get_keep_hierarchy() const
get_keep_hierarchy
const NP_functionalityRef & get_NP_functionality() const
Return the alternative functionalities.
static port_direction to_port_direction(const std::string &val)
Convert a string into the corresponding port_direction enumerative type.
port_interface
Enum type describing if the port is associated with a specific interface type.
std::vector< Wrefcount< structural_object > > connected_objects
List of ports bounded by the channel object.
void print(std::ostream &os) const override
Print the signal (for debug purpose)
unsigned int get_sensitivity_size() const
Return tha size of the sensitivity list.
structural_objectRef find_isomorphic(const structural_objectRef key) const override
Find key in this object.
static bool resize_if_busport(unsigned long long bus_size_bitsize, unsigned long long bus_addr_bitsize, unsigned long long bus_data_bitsize, unsigned long long bus_tag_bitsize, structural_objectRef port)
auxiliary function used to resize the bus ports with respect to their associated bus size ...
#define LOAD_XVFM(variable, node, field)
LOAD XML Value for field Macro. Set a variable starting from an XML value. Conversion is performed if...
Definition: xml_helper.hpp:69
unsigned int treenode
Treenode id of the type.
const structural_objectRef get_out_port(unsigned int n) const
Return the ith output port.
std::vector< structural_objectRef > action_sensitivity
Sensitivity list.
bool get_reverse() const
Returns if the port as to be printed in a reverse mode.
structural_objectRef get_positional_port(unsigned int index) const
return a port of the module given its position
void xwrite(xml_element *rootnode) override
Add a structural_object to an xml tree.
bool get_is_global() const
return true if the port is global
process_type
Define the possible types of a process.
static const unsigned int PARAMETRIC_SIGNAL
bool is_memory
when true the port is a memory port
unsigned int aligment
virtual void print(std::ostream &os) const
Print the structural_object (for debug purpose)
structural_objectRef find_member(const std::string &id, so_kind type, const structural_objectRef owner) const override
Return the object named id of a given type which belongs to or it is associated with the object...
void add_interface(unsigned int t, const std::string &_interface)
Add an interface to the object.
port_o(int debug_level, const structural_objectRef o, port_direction dir, so_kind _port_type)
Constructor.
#define index(x, y)
Definition: Keccak.c:74
bool is_master
when true the port is a master port
static const bool is_var_args_DEFAULT
std::vector< structural_objectRef > in_ports
input port of this module
std::string get_kind_text() const
Definition of get_kind_text()
redefinition of set to manage ordered/unordered structures
static const unsigned int treenode_DEFAULT
virtual enum tec_kind get_kind() const =0
Virtual function used to find the real type of a technology_nodeinstance.
std::map< std::string, structural_objectRef > index_signals
index for signals this table is used to quickly search internal signals used by find_member and find_...
structural_objectRef find_isomorphic(const structural_objectRef key) const override
Find key in this object.
void print(std::ostream &os) const
Print the Non-SystemC based functionality description (for debug purpose).
unsigned int get_num_ports() const
Return the total number of the ports.
structural_objectRef find_member(const std::string &id, so_kind type, const structural_objectRef owner) const override
Return the object named id of a given type which belongs to or it is associated with the object...
unsigned int treenode
index of the treenode in the tree_manager associated with the structural object.
void add_parameter(structural_objectRef d)
Add a procedure paramenter.
bool get_is_master() const
return true if the port works as master memory port
void print(std::ostream &os) const override
Print the module (for debug purpose)
virtual bool is_int(unsigned int index) const
Return true if index is a variable or a type of type int.
channel_o(int debug_level, const structural_objectRef o)
Constructor.
bool get_is_clock() const
return true if the port is a clock
static const bool is_doubled_DEFAULT
void set_black_box(bool bb)
Set the black box property associated with the structural_object.
void add_service(structural_objectRef p)
Add a service to the module.
const structural_objectRef get_gen_port(unsigned int n) const
Return the ith generic port.
void substitute_port(structural_objectRef old_conn, structural_objectRef new_conn)
static const bool is_slave_DEFAULT
structural_objectRef find_isomorphic(const structural_objectRef key) const override
Find key in this object.
void xwrite(xml_element *rootnode) override
Add a structural_object to an xml tree.
static void fix_port_properties(structural_objectRef port_i, structural_objectRef cir_port)
copy the port properties from port_i to cir_port
int get_line() const
Discover at what line number this node occurs in the XML file.
Definition: xml_node.cpp:101
void SetParameter(const std::string &name, const std::string &value)
Set a parameter value.
static simple_indent PP
pretty print functor object used by all print members to indent the output of the print function...
void set_NP_functionality(NP_functionalityRef f)
Set the alternative module behavior descriptions (Non SystemC based).
virtual enum so_kind get_kind() const =0
Virtual function used to find the real type of a structural_object instance.
virtual bool is_bool(unsigned int index) const
Return true if index is a variable or a type of type bool.
void print(std::ostream &os) const override
Print the port (for debug purpose)
void xload(const xml_element *Enode, structural_objectRef owner, structural_managerRef const &CM) override
Load a structural_object starting from an xml file.
void print(std::ostream &os) const override
Print the data declaration object (for debug purpose).
This class describes a generic bus connection.
const structural_objectRef get_port(unsigned int n) const
Return the ith port bounded to the connection.
const structural_objectRef get_positional_signal(unsigned int n) const
Return the ith port of the vector with respect to lsb.
void add_port(structural_objectRef p)
Bind the connection object with a port.
unsigned int GetUnqualified(const unsigned int index) const
Return the unqualified version of a type.
unsigned int get_fun_id() const
Return the function id.
struct definition of the field attr on function_decl, field_decl, var_decl tree node.
Definition: tree_node.hpp:774
This file collects some utility functions and macros.
#define GET_CLASS_NAME(meth)
Macro returning the name of a class.
Definition: utility.hpp:102
void add_in_port(structural_objectRef p)
Add an input port.
std::list< xml_nodeRef > node_list
type for list of xml nodes
Definition: xml_node.hpp:90
void xwrite(xml_element *rootnode)
Add a NP_functionality to an xml tree.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
Definition: exceptions.hpp:263
void add_process(structural_objectRef p)
Add a process to the module.
void print(std::ostream &os) const override
Print the event (for debug purpose)
void add_connection(structural_objectRef s)
Bind this port with a signal/port.
bool get_is_doubled() const
return true if the port has a doubled size w.r.t the precision
unsigned long long get_port_size() const
Get port size.
std::string get_kind_text() const override
return the name of the class as a string.
port_interface pi
port interface type of a port
process_type action_type
The type of the action.
static const bool is_halved_DEFAULT
void xload(const xml_element *Enode, structural_type_descriptorRef owner)
Load a structural_type_descriptor starting from an xml file.
void type_resize(unsigned long long new_bit_size)
Just resize the size of the bits of the object.
void set_port_endianess(port_endianess end)
Set the endianess of the port.
bool get_generated() const
return if the component has been generated or not
void xwrite(xml_element *rootnode)
Add a structural_type_descriptor to an xml tree.
void add_internal_object(structural_objectRef c)
Add an internal component/channel/signal/bus_connection_o.
#define HIERARCHY_SEPARATOR
static const unsigned int size_DEFAULT
void set_port_interface(port_interface pi)
Set the port interface type of the port.
structural_objectRef find_member(const std::string &id, so_kind type, const structural_objectRef owner) const override
Return the object named id of a given type which belongs to or it is associated with the object...
module(int debug_level, const structural_objectRef o)
Constructor.
void add_connection(structural_objectRef c)
Add a connection (e.g.
unsigned int last_position_port
store the last index of the positional binding
virtual bool is_a_struct(unsigned int variable) const
Return true if index is a variable or a type of type struct.
const structural_objectRef get_service(unsigned int n) const
Return the ith service.
void add_n_ports(unsigned int n_ports, structural_objectRef owner)
Specify the number of ports of a generic port_vector object and add its corresponding ports...
void print(std::ostream &os) const override
Print the action (for debug purpose)
port_endianess get_port_endianess() const
Return the endianess of the port.
component_o(int debug_level, const structural_objectRef o)
Constructor.
structural_objectRef find_member(const std::string &id, so_kind type, const structural_objectRef owner) const override
Return the object named id of a given type which belongs to or it is associated with the object...
static const bool is_global_DEFAULT
#define WRITE_XNVM2(name, value, node)
WRITE XML Name Value Macro second version. Insert a value in an XML tree given the name of the attrib...
Definition: xml_helper.hpp:58
signal_o(int debug_level, const structural_objectRef o, so_kind _signal_type)
Constructor.
unsigned int get_in_port_size() const
Return the number of input ports.
unsigned int get_process_size() const
Return the number of internal processes.
void xwrite(xml_element *rootnode) override
Add a structural_object to an xml tree.
std::string value
Value of this element.
This class describes a simple logic/RTL signal.
const structural_objectRef get_local_data(unsigned int n) const
Return the ith local data.
#define GET_TYPE_SIZE(structural_obj)
Macro returning the size of the type of a structural object.
refcount< T > lock() const
Definition: refcount.hpp:212
Very simple pretty printer functor.
NP_functionalityRef NP_descriptions
Alternative descriptions of the behavior of the module.
unsigned int lsb
least significant bit
virtual bool is_real(unsigned int index) const
Return true if index is a variable or a type of type real.
bool is_critical
when true the component is involved into the critical path of the netlist
std::string id_type
Original type id of the structural object.
void copy(structural_objectRef dest) const override
Perform a copy of the value.
const structural_objectRef get_connection(unsigned int n) const
Return connection bounded to this port.
This class describes all classes used to represent a structural object.
std::string scope
Used to identify the scope of the action (public, private or protected)
const structural_type_descriptorRef & get_typeRef() const
Return the type descriptor of the structural_object.
process_type get_action_type() const
Return the type of the action.
std::map< unsigned int, structural_objectRef > positional_map
positional map, given the index return the port in that position
static port_interface to_port_interface(const std::string &val)
Convert a string into the corresponding port_interface enumerative type.
std::string get_value() const
Return the (integer) value associated with this element.
void add_gen_port(structural_objectRef p)
Add a generic port.
bool black_box
True if the structural object is a black box (e.g., a library component).
unsigned int GetElements(const unsigned int type) const
Given an array or a vector return the element type.
#define WRITE_XNVM(variable, value, node)
WRITE XML Name Value Macro.
Definition: xml_helper.hpp:55
static const bool is_data_bus_DEFAULT
bool is_clock
when true the port is a clock port and has to be attached to a clock object
void set_id(const std::string &s)
Set the identifier associated with the structural_object.
bool is_tag_bus
when true the port is a tag bus
bool get_process_nservice() const
Return the type of the action: process (true) or services (false).
const structural_objectRef get_owner() const
Return the owner.
std::vector< structural_objectRef > ports
The list of ports associated with the port.
#define WRITE_XVM(variable, node)
WRITE XML Value Macro. Insert a value in an XML tree.
Definition: xml_helper.hpp:51
void xload(const xml_element *Enode, structural_objectRef owner, structural_managerRef const &CM) override
Load a structural_object starting from an xml file.
virtual void copy(structural_objectRef dest) const
Perform a copy of the structural object.
void set_port_direction(port_direction dir)
Set the direction of the port.
std::string license
Store some tags concerning the license type associated with the functional unit.
void set_keep_hierarchy(bool ky)
set_keep_hierarchy
int debug_level
debug level for the object
void add_n_signals(unsigned int n_signals, structural_objectRef owner)
Specify the number of ports of a generic port_vector object and add its corresponding ports...
void set_is_size_bus(bool c)
set the is_size_bus attribute.
bool ExistsParameter(std::string name) const
Check if a parameter has been specified.
bool get_critical() const
return if the component is critical or not
std::vector< Wrefcount< structural_object > > connected_objects
The list of connections associated with the port.
Wrefcount< structural_object > owner
The owner of the object.
bool get_is_tag_bus() const
return true if the port works as an tag bus
std::string get_content() const
Get the text of this content node.
void change_port_direction(structural_objectRef port, port_o::port_direction pdir)
change the direction of a port
refcount< structural_object > structural_objectRef
RefCount type definition of the structural_object class structure.
port_interface get_port_interface() const
Return the port interface type of the port.
T * get() const
Definition: refcount.hpp:169
virtual bool is_an_union(unsigned int variable) const
Return true if index is a variable of a type of type union.
static const bool is_tag_bus_DEFAULT
unsigned int get_connections_size() const
Return the number of connections associated with the bus connection object.
structural_objectRef find_member(const std::string &id, so_kind type, const structural_objectRef owner) const override
Return the object named id of a given type which belongs to or it is associated with the object...
std::string size_parameter
custom size parameter
void set_is_master(bool c)
set the is_master attribute.
event_o(int debug_level, const structural_objectRef o)
Constructor.
void add_local_data(structural_objectRef d)
Add a local data.
std::vector< Wrefcount< structural_object > > connected_objects
List of ports bounded by the constant object.
void AddParameter(const std::string &name, const std::string &default_value) override
Add a parameter.
This class describes a generic event.
#define DEBUG_PARAMETER(parameter)
macro used to solve problem of parameters used only in not-release
Definition: utility.hpp:91
static const s_type type_DEFAULT
bool get_black_box() const
Return the black box property.
void set_copyright(const std::string &c)
Set the copyright associated with the module.
virtual unsigned int get_type(const unsigned int var) const
Return the type of the variable.
void set_is_addr_bus(bool c)
set the is_addr_bus attribute.
structural_objectRef find_isomorphic(const structural_objectRef key) const override
Find key in this object.
#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
bool get_is_slave() const
return true if the port works as slave memory port
const structural_objectRef get_in_out_port(unsigned int n) const
Return the ith input-output port.
constant_o(int debug_level, const structural_objectRef o)
Constructor.
const structural_objectRef get_sensitivity(unsigned int n) const
Return a specific event of the sensitivity list.
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
std::vector< structural_objectRef > out_ports
output ports of this module
Not parsed functionality manager.
so_kind signal_type
port type
const std::string & get_scope() const
Return the scope of the action.
std::string bus_bundle
bus bundle
std::vector< structural_objectRef > internal_objects
internal components/channels/signals/bus_connection_os (for structural modules)
unsigned long long get_size() const
Return the size associated with this element (in bits)
Class implementation of the structural_manager.
This class describes a generic component.
bool is_slave
when true the port is a slave port
Class specification of the manager for each library.
static void resize_std_port(unsigned long long bitsize_variable, unsigned long long n_elements, int debug_level, structural_objectRef port)
auxiliary function used to resize the standard ports
static const unsigned int treenode_DEFAULT
CustomMap< std::string, std::string > parameters
Map between parameter string and related values of an instance.
This class writes different HDL based descriptions (VHDL, Verilog, SystemC) starting from a structura...
void copy(structural_objectRef dest) const override
Perform a copy of the bus_connection_o.
void xwrite(xml_element *rootnode) override
Add a structural_object to an xml tree.
void xload(const xml_element *Enode, structural_objectRef owner, structural_managerRef const &CM) override
Load a structural_object starting from an xml file.
bool is_var_args
when true the port must be specialized at runtime depending on the number of input ...
unsigned int get_connections_size() const
Return the number of connections bounded to this port.
void print(std::ostream &os) const
function that prints the class.
This class describes a constant value.
bool exist_NP_functionality(NP_functionaly_type type) const
Return true in case there exist a functionaly of the given type.
static void convert_escaped(std::string &ioString)
Convert escaped characters.
Definition: xml_node.hpp:197
structural_objectRef find_member(const std::string &id, so_kind type, const structural_objectRef owner) const override
Return the object named id of a given type which belongs to or it is associated with the object...
CustomMap< std::string, std::string > default_parameters
Map between parameter string and its default value.
structural_object(int debug_level, const structural_objectRef o)
Constructor for the structural_object.
void xwrite(xml_element *rootnode) override
Add a structural_object to an xml tree.
std::map< std::string, structural_objectRef > index_components
index for components this table is used to quickly search internal components used by find_member and...
bool get_is_data_bus() const
return true if the port works as a data bus
unsigned int get_port_alignment() const
Return the port interface alignment.
static const bool is_clock_DEFAULT
void set_authors(const std::string &a)
Set the authors associated with the module.
Not parsed functionality descriptor of a module.
void xwrite(xml_element *rootnode) override
Add a structural_object to an xml tree.
virtual void xload(const xml_element *Enode, structural_objectRef owner, structural_managerRef const &CM)
Load a structural_object starting from an xml file.
This class describes a generic module.
void add_in_out_port(structural_objectRef p)
Add an input-output port.
const std::string get_name() const
Returns the name of the type descriptor.
void xload(const xml_element *Enode, structural_objectRef owner, structural_managerRef const &CM) override
Load a structural_object starting from an xml file.
bool is_full_connected() const
Return if signal has both input and output.
void set_is_halved(bool c)
set the is_halved attribute.
bool keep_hierarchy
when true the module has the keep_hierarchy attribute active
std::string authors
Store the list of authors.
unsigned int get_in_out_port_size() const
Return the number of output ports.
xml_element * add_child_element(const std::string &name)
Add a child element to this node.
Definition: xml_node.cpp:54
void set_reverse()
Sets the port as reverse.
bool is_doubled
when true the port has a doubled size
Base object for all the structural objects.
void set_critical()
set the component as critical with respect to the timing path
port_endianess end
endianess of a port
structural_objectRef get_connected_signal() const
Return the connected signal, if any.
bool is_global
when true the port is a global port
void print(std::ostream &os) const override
Print the channel (for debug purpose)
std::vector< std::string > get_connections(const xml_element *node)
port_direction get_port_direction() const
Return the direction of the port.
virtual structural_objectRef find_isomorphic(const structural_objectRef key) const =0
Find key in this object.
void xwrite(xml_element *rootnode) override
Add a structural_object to an xml tree.
CustomMap< std::string, std::string > GetParameters() const
return the whole set of parameters
std::vector< Wrefcount< structural_object > > connections
List of connections associated with the bus.
void copy(structural_objectRef dest) const override
Perform a copy of the signal.
void add_event(structural_objectRef e)
Add an event to the module.
action_o(int debug_level, const structural_objectRef o)
Constructor.
void set_critical()
set the signal as critical with respect to the timing path
static const bool is_critical_DEFAULT
unsigned long long vector_size
The number of the elements of a vector.
void copy(structural_type_descriptorRef dest)
Method that copies the contents of the current structural_type_descriptorRef into another structural_...
void set_type(const structural_type_descriptorRef &s)
Set the type of the structural_object.
std::vector< structural_objectRef > list_of_process
List of processes associated with the module.
static const unsigned port_interface_alignment_DEFAULT
unsigned int multi_unit_multiplicity
multi-unit multiplicity is the number of units implemented by this module all doing the same thing ...
void get_library_parameters(std::vector< std::string > &parameters) const
fill a vector with the library parameters in case it there exists a LIBRARY based description...
void copy(structural_objectRef dest) const override
Perform a copy of the port.
unsigned int get_connected_objects_size() const
Return the number of ports associated with the connection.
#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:50 for PandA-2024.02 by doxygen 1.8.13