PandA-2024.02
structural_manager.cpp
Go to the documentation of this file.
1 /*
2  *
3  * _/_/_/ _/_/ _/ _/ _/_/_/ _/_/
4  * _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/
5  * _/_/_/ _/_/_/_/ _/ _/_/ _/ _/ _/_/_/_/
6  * _/ _/ _/ _/ _/ _/ _/ _/ _/
7  * _/ _/ _/ _/ _/ _/_/_/ _/ _/
8  *
9  * ***********************************************
10  * PandA Project
11  * URL: http://panda.dei.polimi.it
12  * Politecnico di Milano - DEIB
13  * System Architectures Group
14  * ***********************************************
15  * Copyright (C) 2004-2024 Politecnico di Milano
16  *
17  * This file is part of the PandA framework.
18  *
19  * The PandA framework is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program. If not, see <http://www.gnu.org/licenses/>.
31  *
32  */
47 #include "structural_manager.hpp"
48 
49 #include "Parameter.hpp"
50 #include "cg_node.hpp"
51 #include "custom_map.hpp"
52 #include "custom_set.hpp"
53 #include "dbgPrintHelper.hpp"
54 #include "exceptions.hpp"
55 #include "graph.hpp"
56 #include "graph_info.hpp"
57 #include "library_manager.hpp"
58 #include "refcount.hpp"
59 #include "string_manipulation.hpp"
60 #include "technology_manager.hpp"
61 #include "technology_node.hpp"
62 #include "typed_node_info.hpp"
63 #include "xml_element.hpp"
64 #include "xml_node.hpp"
65 
66 #include <iosfwd>
67 #include <list>
68 #include <memory>
69 #include <ostream>
70 #include <utility>
71 #include <vector>
72 
73 #include <boost/algorithm/string/predicate.hpp>
74 #include <boost/graph/adjacency_list.hpp>
75 #include <boost/graph/filtered_graph.hpp>
76 #include <boost/graph/graph_traits.hpp>
77 #include <boost/graph/graphviz.hpp>
78 #include <boost/iterator/iterator_facade.hpp>
79 #include <boost/smart_ptr/shared_ptr.hpp>
80 
81 #include "config_HAVE_TECHNOLOGY_BUILT.hpp"
82 
84  : Param(_Param), debug_level(_Param->get_class_debug_level(GET_CLASS(*this)))
85 {
86  og = new graphs_collection(GraphInfoRef(new cg_graph_info), _Param);
89 }
90 
92 {
93  delete og;
94  delete data_graph;
95  delete circuit_graph;
96 }
97 
99 {
100  return structural_type_descriptor::check_type(src_type->get_typeRef(), dest_type->get_typeRef());
101 }
102 
104 {
105  THROW_ASSERT(id.find(HIERARCHY_SEPARATOR, 0) == std::string::npos,
106  std::string("Object id cannot contain the \"/\" character"));
107  return owner->find_member(id, type, owner) != nullptr;
108 }
109 
111 {
112  auto* p = GetPointer<port_o>(src);
113  for(unsigned int i = 0; i < p->get_connections_size(); i++)
114  {
115  if(p->get_connection(i) == sign)
116  {
117  return true;
118  }
119  }
120  return false;
121 }
122 
123 void structural_manager::set_top_info(std::string id, structural_type_descriptorRef module_type, unsigned int treenode)
124 {
125  structural_objectRef nullobj;
127  auto* circ = GetPointer<component_o>(circuit);
128  circ->set_id(id);
129  circ->set_treenode(treenode);
130  circ->set_type(module_type);
131 }
132 
133 void structural_manager::set_top_info(const std::string& id, const technology_managerRef& LM,
134  const std::string& Library)
135 {
136  structural_objectRef nullobj;
137  circuit = this->add_module_from_technology_library(id, id, Library, nullobj, LM);
138 }
139 
141  structural_type_descriptorRef obj_type, unsigned int treenode)
142 {
143  THROW_ASSERT(owner, "missing the owner");
144  THROW_ASSERT(!check_object(id, owner, ctype), "the object " + id + " is already present in " + owner->get_path());
146  switch(ctype)
147  {
148  case component_o_K:
149  {
150  {
151  cc = structural_objectRef(new component_o(debug_level, owner));
152  }
153  break;
154  }
155  case constant_o_K:
156  {
157  {
158  cc = structural_objectRef(new constant_o(debug_level, owner));
159  }
160  break;
161  }
162  case channel_o_K:
163  {
164  {
165  cc = structural_objectRef(new channel_o(debug_level, owner));
166  }
167  break;
168  }
169  case action_o_K:
170  case bus_connection_o_K:
171  case data_o_K:
172  case event_o_K:
173  case port_o_K:
174  case port_vector_o_K:
175  case signal_o_K:
176  case signal_vector_o_K:
177  default:
178  THROW_ERROR(std::string("ctype not supported"));
179  }
180  cc->set_id(id);
181  cc->set_treenode(treenode);
182  cc->set_type(obj_type);
183  auto* own = GetPointer<module>(owner);
184  THROW_ASSERT(own, "Signal, port or interface couldn't own internal object");
185  own->add_internal_object(cc);
186  return cc;
187 }
188 
191  unsigned int treenode)
192 {
193  THROW_ASSERT(owner, "missing the owner");
194  THROW_ASSERT(!check_object(id, owner, port_o_K), "the object " + id + " is already present in " + owner->get_path());
195  structural_objectRef cp = structural_objectRef(new port_o(owner->debug_level, owner, pdir, port_o_K));
196  cp->set_id(id);
197  cp->set_treenode(treenode);
198  cp->set_type(type_descr);
199  switch(owner->get_kind())
200  {
201  case channel_o_K:
202  case component_o_K:
203  {
204  auto* own = GetPointer<module>(owner);
205  switch(pdir)
206  {
207  case port_o::IN:
208  {
209  own->add_in_port(cp);
210 #if HAVE_TECHNOLOGY_BUILT
211  attributeRef direction(new attribute(attribute::STRING, "input"));
212  cp->add_attribute("direction", direction);
213 #endif
214  break;
215  }
216  case port_o::OUT:
217  {
218  own->add_out_port(cp);
219 #if HAVE_TECHNOLOGY_BUILT
220  attributeRef direction(new attribute(attribute::STRING, "output"));
221  cp->add_attribute("direction", direction);
222 #endif
223  if(GetPointer<module>(owner))
224  {
225  NP_functionalityRef NPF = GetPointer<module>(owner)->get_NP_functionality();
226  if(NPF)
227  {
228 #if HAVE_TECHNOLOGY_BUILT
229  std::string equation = NPF->get_NP_functionality(NP_functionality::EQUATION);
230  std::vector<std::string> tokens = SplitString(equation, ";");
231  for(auto& token : tokens)
232  {
233  if(starts_with(token, id))
234  {
235  equation = token.substr(token.find('=') + 1, token.size());
236  }
237  }
238  attributeRef function(new attribute(attribute::STRING, equation));
239  cp->add_attribute("function", function);
240 #endif
241  }
242  }
243  break;
244  }
245  case port_o::IO:
246  {
247  own->add_in_out_port(cp);
248  break;
249  }
250  case port_o::GEN:
251  {
252  own->add_gen_port(cp);
253  break;
254  }
255  case port_o::TLM_IN:
256  case port_o::TLM_INOUT:
257  case port_o::TLM_OUT:
258  case port_o::UNKNOWN:
259  default:
260  THROW_ERROR(std::string("port type not supported"));
261  }
262  break;
263  }
264  case action_o_K:
265  case bus_connection_o_K:
266  case constant_o_K:
267  case data_o_K:
268  case event_o_K:
269  case port_o_K:
270  case port_vector_o_K:
271  case signal_o_K:
272  case signal_vector_o_K:
273  default:
274  THROW_ERROR(std::string("Signal, port or interface couldn't own a port"));
275  }
276 
277  return cp;
278 }
279 
281  structural_objectRef owner)
282 {
283  switch(owner->get_kind())
284  {
285  case channel_o_K:
286  case component_o_K:
287  {
288  auto* own = GetPointer<module>(owner);
289  own->change_port_direction(port_object, pdir);
290  break;
291  }
292  case action_o_K:
293  case bus_connection_o_K:
294  case constant_o_K:
295  case data_o_K:
296  case event_o_K:
297  case port_o_K:
298  case port_vector_o_K:
299  case signal_o_K:
300  case signal_vector_o_K:
301  default:
302  THROW_ERROR(std::string("object not yet managed"));
303  }
304 }
305 
307  unsigned int n_ports, structural_objectRef owner,
309  unsigned int treenode)
310 {
311  THROW_ASSERT(owner, "missing the owner");
313  "the object " + id + " is already present in " + owner->get_path());
315  cp->set_id(id);
316  cp->set_treenode(treenode);
317  cp->set_type(type_descr);
318  if(n_ports != port_o::PARAMETRIC_PORT)
319  {
320  GetPointer<port_o>(cp)->add_n_ports(n_ports, cp);
321  }
322  switch(owner->get_kind())
323  {
324  case channel_o_K:
325  case component_o_K:
326  {
327  auto* own = GetPointer<module>(owner);
328  switch(pdir)
329  {
330  case port_o::IN:
331  {
332  own->add_in_port(cp);
333  break;
334  }
335  case port_o::OUT:
336  {
337  own->add_out_port(cp);
338  break;
339  }
340  case port_o::IO:
341  {
342  own->add_in_out_port(cp);
343  break;
344  }
345  case port_o::GEN:
346  {
347  own->add_gen_port(cp);
348  break;
349  }
350  case port_o::TLM_IN:
351  case port_o::TLM_INOUT:
352  case port_o::TLM_OUT:
353  case port_o::UNKNOWN:
354  default:
355  THROW_ERROR(std::string("port type not supported"));
356  }
357  break;
358  }
359  case action_o_K:
360  case bus_connection_o_K:
361  case constant_o_K:
362  case data_o_K:
363  case event_o_K:
364  case port_o_K:
365  case port_vector_o_K:
366  case signal_o_K:
367  case signal_vector_o_K:
368  default:
369  THROW_ERROR(std::string("Signal, port or interface couldn't own a port"));
370  }
371  return cp;
372 }
373 
374 structural_objectRef structural_manager::add_sign_vector(std::string id, unsigned int n_signs,
375  structural_objectRef owner,
376  structural_type_descriptorRef sign_type, unsigned int treenode)
377 {
378  THROW_ASSERT(owner, "missing the owner");
379  THROW_ASSERT(!check_object(id, owner, signal_o_K),
380  "the object " + id + " is already present in " + owner->get_path());
382  cs->set_id(id);
383  cs->set_treenode(treenode);
384  cs->set_type(sign_type);
385  if(n_signs != signal_o::PARAMETRIC_SIGNAL)
386  {
387  GetPointer<signal_o>(cs)->add_n_signals(n_signs, cs);
388  }
389  switch(owner->get_kind())
390  {
391  case component_o_K:
392  {
393  auto* own = GetPointer<module>(owner);
394  own->add_internal_object(cs);
395  break;
396  }
397  case action_o_K:
398  case bus_connection_o_K:
399  case channel_o_K:
400  case constant_o_K:
401  case data_o_K:
402  case event_o_K:
403  case port_o_K:
404  case port_vector_o_K:
405  case signal_o_K:
406  case signal_vector_o_K:
407  default:
408  THROW_ERROR(std::string("Only a module can own a signal vector"));
409  }
410  return cs;
411 }
412 
414  structural_type_descriptorRef sign_type, unsigned int treenode)
415 {
416  THROW_ASSERT(owner, "missing the owner");
417  THROW_ASSERT(!check_object(id, owner, signal_o_K),
418  "the object " + id + " is already present in " + owner->get_path());
420  cs->set_id(id);
421  cs->set_treenode(treenode);
422  cs->set_type(sign_type);
423  switch(owner->get_kind())
424  {
425  case channel_o_K:
426  case component_o_K:
427  {
428  auto* own = GetPointer<module>(owner);
429  own->add_internal_object(cs);
430  break;
431  }
432  case bus_connection_o_K:
433  {
434  auto* own = GetPointer<bus_connection_o>(owner);
435  own->add_connection(cs);
436  break;
437  }
438  case action_o_K:
439  case constant_o_K:
440  case data_o_K:
441  case event_o_K:
442  case port_o_K:
443  case port_vector_o_K:
444  case signal_o_K:
445  case signal_vector_o_K:
446  default:
447  THROW_ERROR(std::string("Signal, port or interface couldn't own signal"));
448  }
449  return cs;
450 }
451 
453 {
454  auto* sign(GetPointer<signal_o>(signal));
455  THROW_ASSERT(sign, "Null argument or not a signal");
456 
457  if(sign->get_connected_objects_size() > 0)
458  {
459  THROW_ERROR("Signal has connected objects");
460  }
461 
462  structural_objectRef owner(sign->get_owner());
463 
464  switch(owner->get_kind())
465  {
466  case channel_o_K:
467  case component_o_K:
468  GetPointer<module>(owner)->remove_internal_object(signal);
469  break;
470  case action_o_K:
471  case bus_connection_o_K:
472  case constant_o_K:
473  case data_o_K:
474  case event_o_K:
475  case port_o_K:
476  case port_vector_o_K:
477  case signal_o_K:
478  case signal_vector_o_K:
479  default:
480  THROW_ERROR("Signal removal not implemented for this owner type");
481  }
482 }
483 
485  structural_objectRef& to_signal)
486 {
487  // sanity checks
488 
489  auto* from(GetPointer<signal_o>(from_signal));
490  auto* to(GetPointer<signal_o>(to_signal));
491  THROW_ASSERT(from && to && from->get_owner() == to->get_owner(), "Need two valid signals with the same owner");
492  THROW_ASSERT(from->is_connected(member), "Not a member of from_signal");
493  THROW_ASSERT(check_type(member, to_signal), "Member is incompatible with to_signal");
494  THROW_ASSERT(!to->is_connected(member), "Already a member of to_signal");
495 
496  // ok, let's rock
497 
499  "moving member " + member->get_path() + " from " + from_signal->get_path() + " to " +
500  to_signal->get_path());
501 
502  switch(member->get_kind())
503  {
504  case port_o_K:
505  {
506  auto* p(GetPointer<port_o>(member));
507  from->remove_port(member);
508  p->remove_connection(from_signal);
509 
510  p->add_connection(to_signal);
511  to->add_port(member);
512  break;
513  }
514  case action_o_K:
515  case bus_connection_o_K:
516  case channel_o_K:
517  case component_o_K:
518  case constant_o_K:
519  case data_o_K:
520  case event_o_K:
521  case port_vector_o_K:
522  case signal_o_K:
523  case signal_vector_o_K:
524  default:
525  THROW_ERROR("Unsupported signal member type -- " + std::string(member->get_kind_text()));
526  }
527 }
528 
531  unsigned int treenode)
532 {
533  THROW_ASSERT(owner, "missing the owner");
535  "the object " + id + " is already present in " + owner->get_path());
536  structural_objectRef c_obj(new constant_o(debug_level, owner, value));
537  c_obj->set_id(id);
538  c_obj->set_treenode(treenode);
539  c_obj->set_type(type);
540  auto* own = GetPointer<module>(owner);
541  THROW_ASSERT(own, "Signal, port or interface couldn't own internal object");
542  own->add_internal_object(c_obj);
543  return c_obj;
544 }
545 
547  std::string functionality_description)
548 {
549  THROW_ASSERT((cir->get_kind() == component_o_K), "Only components can have a Non SystemC functionality");
550  const auto com = GetPointer<module>(cir);
552  (com->get_NP_functionality() ? com->get_NP_functionality() : NP_functionalityRef(new NP_functionality));
553  f->add_NP_functionality(dt, functionality_description);
554  com->set_NP_functionality(f);
555 }
556 
557 void structural_manager::SetParameter(const std::string& name, const std::string& value)
558 {
559  THROW_ASSERT((get_circ()->get_kind() == component_o_K), "Only components can have a Non SystemC functionality");
560  auto* com = GetPointer<module>(get_circ());
561  com->SetParameter(name, value);
562 }
563 
565 {
566  auto* ad = GetPointer<action_o>(pr);
567  ad->add_event_to_sensitivity(obj);
568 }
569 
571 {
572  THROW_ASSERT(src && dest,
573  "Missing src or dest: " + (src ? src->get_path() : "!src") + " " + (dest ? dest->get_path() : "!dest"));
574  // std::cerr <<"Adding connection from " + src->get_path() + ":" + src->get_kind_text() + " to "+ dest->get_path() +
575  // ":" + dest->get_kind_text() << std::endl;
576  switch(src->get_kind())
577  {
578  case port_o_K:
579  {
580  auto* p_s = GetPointerS<port_o>(src);
581  switch(dest->get_kind())
582  {
583  case port_o_K:
584  {
585  THROW_ASSERT(
586  src->get_owner() != dest->get_owner(),
587  "A direct connection between ports of the same object is not allowed. Put a signal in between...: " +
588  src->get_path() + " " + dest->get_path());
589  THROW_ASSERT(check_type(src, dest),
590  "Ports have to be compatible: " + src->get_path() + " -> " + dest->get_path());
591  THROW_ASSERT(!src->find_member(dest->get_id(), port_o_K, dest->get_owner()),
592  "Port " + src->get_id() + " already bound to " + dest->get_id());
593  THROW_ASSERT(!dest->find_member(src->get_id(), port_o_K, src->get_owner()),
594  "Port " + dest->get_id() + " already bound to " + src->get_id());
595  auto* p_d = GetPointerS<port_o>(dest);
596  p_s->add_connection(dest);
597  p_d->add_connection(src);
598  break;
599  }
600  case signal_o_K:
601  {
602  THROW_ASSERT(check_type(src, dest),
603  "Ports and signals have to be compatible: " + src->get_path() + " -> " + dest->get_path());
604  p_s->add_connection(dest);
605  auto* c_d = GetPointerS<signal_o>(dest);
606  c_d->add_port(src);
607  break;
608  }
609  case channel_o_K:
610  {
611  THROW_ASSERT(src->get_owner() != dest->get_owner(),
612  "A direct connection between port and channel of the same object is not allowed.");
613  THROW_ASSERT(!src->find_member(dest->get_id(), channel_o_K, dest->get_owner()),
614  "Port " + src->get_id() + " already bound to " + dest->get_id());
616  p_s->add_connection(dest);
617  auto* c_d = GetPointerS<channel_o>(dest);
618  c_d->add_port(src);
619  break;
620  }
621  case constant_o_K:
622  {
623  // THROW_ASSERT(src->get_owner() != dest->get_owner(), "A direct connection between port and constant of
624  // the same object is not allowed.");
625  THROW_ASSERT(!src->find_member(dest->get_id(), constant_o_K, dest->get_owner()),
626  "Port " + src->get_id() + " already bound to " + dest->get_id());
628  p_s->add_connection(dest);
629  auto* c_d = GetPointerS<constant_o>(dest);
630  c_d->add_connection(src);
631  break;
632  }
633  case action_o_K:
634  case bus_connection_o_K:
635  case component_o_K:
636  case data_o_K:
637  case event_o_K:
638  case port_vector_o_K:
639  case signal_vector_o_K:
640  default:
641  {
642  THROW_ERROR("Cannot connect a port_o to a " + dest->get_kind_text() + " " +
643  (src ? src->get_path() : "") + " " + (dest ? dest->get_path() : ""));
644  }
645  }
646  break; // case src = port_o_K
647  }
648  case port_vector_o_K:
649  {
650  auto* p_s = GetPointerS<port_o>(src);
651  switch(dest->get_kind())
652  {
653  case port_vector_o_K:
654  {
655  THROW_ASSERT(
656  src->get_owner() != dest->get_owner(),
657  "A direct connection between ports of the same object is not allowed. Put a signal in between...: " +
658  src->get_path() + " " + dest->get_path());
659  THROW_ASSERT(check_type(src, dest),
660  "Ports have to be compatible: " + src->get_path() + " -> " + dest->get_path());
661  THROW_ASSERT(!src->find_member(dest->get_id(), port_o_K, dest->get_owner()),
662  "Port " + src->get_id() + " already bound to " + dest->get_id());
663  THROW_ASSERT(!dest->find_member(src->get_id(), port_o_K, src->get_owner()),
664  "Port " + dest->get_id() + " already bound to " + src->get_id());
665  auto* p_d = GetPointerS<port_o>(dest);
666  p_s->add_connection(dest);
667  p_d->add_connection(src);
668  break;
669  }
670  case signal_vector_o_K:
671  {
672  THROW_ASSERT(check_type(src, dest),
673  "Ports and signals have to be compatible: " + src->get_path() + " -> " + dest->get_path());
674  p_s->add_connection(dest);
675  auto* c_d = GetPointerS<signal_o>(dest);
676  c_d->add_port(src);
677  break;
678  }
679  case action_o_K:
680  case bus_connection_o_K:
681  case channel_o_K:
682  case component_o_K:
683  case constant_o_K:
684  case port_o_K:
685  case signal_o_K:
686  case data_o_K:
687  case event_o_K:
688  default:
689  {
690  THROW_ERROR("Cannot connect a port_vector_o (" + src->get_path() + ") to a " + dest->get_kind_text() +
691  " (" + dest->get_path() + ")");
692  }
693  }
694  break;
695  }
696  case signal_o_K:
697  {
698  auto* s_s = GetPointerS<signal_o>(src);
699  switch(dest->get_kind())
700  {
701  case port_o_K:
702  {
703  THROW_ASSERT(check_type(src, dest), "Ports and signals have to be compatible: " + src->get_path() +
704  " (" + src->get_typeRef()->get_name() + ") -> " +
705  dest->get_path() + " (" + dest->get_typeRef()->get_name() + ")");
706  s_s->add_port(dest);
707  auto* p_d = GetPointerS<port_o>(dest);
708  p_d->add_connection(src);
709  break;
710  }
711  case action_o_K:
712  case bus_connection_o_K:
713  case channel_o_K:
714  case component_o_K:
715  case constant_o_K:
716  case data_o_K:
717  case event_o_K:
718  case port_vector_o_K:
719  case signal_o_K:
720  case signal_vector_o_K:
721  default:
722  {
723  THROW_ERROR("Cannot connect a signal_o - " + src->get_path() + " to a " + dest->get_kind_text() + " - " +
724  dest->get_path());
725  }
726  }
727  break; // case src = signal_o_K
728  }
729  case signal_vector_o_K:
730  {
731  auto* s_s = GetPointerS<signal_o>(src);
732  switch(dest->get_kind())
733  {
734  case port_vector_o_K:
735  {
736  THROW_ASSERT(check_type(src, dest),
737  "Ports and signals have to be compatible: " + src->get_path() + " -> " + dest->get_path());
738  s_s->add_port(dest);
739  auto* p_d = GetPointerS<port_o>(dest);
740  p_d->add_connection(src);
741  break;
742  }
743  case action_o_K:
744  case bus_connection_o_K:
745  case channel_o_K:
746  case component_o_K:
747  case constant_o_K:
748  case data_o_K:
749  case event_o_K:
750  case port_o_K:
751  case signal_o_K:
752  case signal_vector_o_K:
753  default:
754  {
755  THROW_ERROR("Cannot connect a signal_vector_o - " + src->get_path() + " to a " + dest->get_kind_text() +
756  " - " + dest->get_path());
757  }
758  }
759  break;
760  }
761  case constant_o_K:
762  {
763  auto* c_s = GetPointerS<constant_o>(src);
764  switch(dest->get_kind())
765  {
766  case port_o_K:
767  {
768  THROW_ASSERT(check_type(src, dest),
769  "Incompatible object types: " + src->get_id() + " -> " + dest->get_id());
770  // THROW_ASSERT(src->get_owner() != dest->get_owner(), "A direct connection between a constant and a port
771  // of the same object is not allowed.");
772  c_s->add_connection(dest);
773  auto* p_d = GetPointerS<port_o>(dest);
774  p_d->add_connection(src);
775  break;
776  }
777  case action_o_K:
778  case bus_connection_o_K:
779  case channel_o_K:
780  case component_o_K:
781  case constant_o_K:
782  case data_o_K:
783  case event_o_K:
784  case port_vector_o_K:
785  case signal_o_K:
786  case signal_vector_o_K:
787  default:
788  {
789  THROW_ERROR("Cannot connect a constant_o to a " + dest->get_kind_text());
790  }
791  }
792  break; // case src = constant_o_K
793  }
794  case action_o_K:
795  case bus_connection_o_K:
796  case channel_o_K:
797  case component_o_K:
798  case data_o_K:
799  case event_o_K:
800  default:
801  {
802  THROW_ERROR("Cannot connect a " + src->get_kind_text() + " to a " + dest->get_kind_text());
803  }
804  } // switch src kind
805 }
806 
807 void structural_manager::WriteDot(const std::string& file_name, circuit_graph_type gt, graph* g) const
808 {
809  const auto output_directory = Param->getOption<std::string>(OPT_dot_directory);
810  std::ofstream f((output_directory + file_name).c_str());
811 
812  if(g == nullptr)
813  {
814  switch(gt)
815  {
816  case DATA_G:
817  g = data_graph;
818  break;
819  case COMPLETE_G:
820  g = circuit_graph;
821  break;
822  default:
823  THROW_ERROR(std::string("Not supported graph type"));
824  }
825  }
826  boost::write_graphviz(f, *g, cg_label_writer(g), cg_edge_writer(g));
827 }
828 
829 void structural_manager::print(std::ostream& os) const
830 {
831  if(circuit && circuit->get_id() != "")
832  {
833  auto* circ = GetPointer<component_o>(circuit);
834  circ->print(os);
835  }
836  else
837  {
838  os << "Error : empty circuit.\n";
839  }
840 }
841 
843 {
844  auto* gi = GetPointer<cg_graph_info>(circuit_graph->GetGraphInfo());
845  THROW_ASSERT(gi, "graph property not associated with the circuit graph");
846  return gi->Entry;
847 }
848 
850 {
851  auto* top_c = GetPointer<module>(obj);
852  if(top_c->get_internal_objects_size() == 0 && obj->get_owner()) // check has mean for all component but the top
853  {
854  for(unsigned int i = 0; i < top_c->get_in_port_size(); i++)
855  {
856  auto* temp = GetPointer<port_o>(top_c->get_in_port(i));
857  if(!temp)
858  {
859  THROW_ERROR("not expected type of port");
860  }
861  if(temp->get_kind() == port_o_K && temp->get_connections_size() == 0 && !permissive)
862  {
863  THROW_ERROR(std::string("Error : component " + obj->get_id() + " input port " + temp->get_id() +
864  " is not bound\n"));
865  }
866  else if(temp->get_kind() == port_o_K && temp->get_connections_size() == 0 && permissive)
867  {
869  {
870  THROW_WARNING("component " + obj->get_id() + " input port " + temp->get_id() + " is not bound");
871  }
872  }
873  else if(temp->get_kind() == port_vector_o_K)
874  {
875  for(unsigned int w = 0; w < temp->get_ports_size(); w++)
876  {
877  auto* tempi = GetPointer<port_o>(temp->get_port(w));
878  THROW_ASSERT(tempi, "Expected a port got something of different");
879  if(tempi->get_connections_size() == 0 && !permissive)
880  {
881  THROW_ERROR(
882  std::string("Component " + obj->get_id() + " input port " + tempi->get_id() + " is not bound\n"));
883  }
884  else if(tempi && tempi->get_connections_size() == 0 && permissive)
885  {
887  {
888  THROW_WARNING("component " + obj->get_id() + " input port " + tempi->get_id() + " is not bound");
889  }
890  }
891  }
892  }
893  }
894  for(unsigned int i = 0; i < top_c->get_out_port_size(); i++)
895  {
896  auto* temp = GetPointer<port_o>(top_c->get_out_port(i));
897  if(!temp)
898  {
899  THROW_ERROR("not expected type of port");
900  }
901  if(temp->get_kind() == port_o_K && temp->get_connections_size() == 0 && !permissive)
902  {
903  THROW_ERROR(std::string("Error : component " + obj->get_id() + " output port " + temp->get_id() +
904  " is not bound\n"));
905  }
906  else if(temp->get_kind() == port_o_K && temp->get_connections_size() == 0 && permissive)
907  {
909  {
910  THROW_WARNING("component " + obj->get_id() + " output port " + temp->get_id() + " is not bound");
911  }
912  }
913  else if(temp->get_kind() == port_vector_o_K)
914  {
915  for(unsigned int w = 0; w < temp->get_ports_size(); w++)
916  {
917  auto* tempi = GetPointer<port_o>(temp->get_port(w));
918  THROW_ASSERT(tempi, "Expected a port got something of different");
919  if(tempi->get_connections_size() == 0 && !permissive)
920  {
921  THROW_ERROR(std::string("Error : component " + obj->get_id() + " output port " + tempi->get_id() +
922  " is not bound\n"));
923  }
924  else if(tempi->get_connections_size() == 0 && permissive)
925  {
927  {
928  THROW_WARNING("component " + obj->get_id() + " output port " + tempi->get_id() + " is not bound");
929  }
930  }
931  }
932  }
933  }
934  for(unsigned int i = 0; i < top_c->get_in_out_port_size(); i++)
935  {
936  auto* temp = GetPointer<port_o>(top_c->get_in_out_port(i));
937  if(!temp)
938  {
939  THROW_ERROR("not expected type of port");
940  }
941  if(temp->get_kind() == port_o_K && temp->get_connections_size() == 0 && !permissive)
942  {
943  THROW_ERROR(std::string("Error : component " + obj->get_id() + " in/output port " + temp->get_id() +
944  " is not bound\n"));
945  }
946  else if(temp->get_kind() == port_o_K && temp->get_connections_size() == 0 && permissive)
947  {
949  {
950  THROW_WARNING("component " + obj->get_id() + " in/output port " + temp->get_id() + " is not bound");
951  }
952  }
953  else if(temp->get_kind() == port_vector_o_K)
954  {
955  for(unsigned int w = 0; w < temp->get_ports_size(); w++)
956  {
957  auto* tempi = GetPointer<port_o>(temp->get_port(w));
958  THROW_ASSERT(tempi, "Expected a port got something of different");
959  if(tempi->get_connections_size() == 0 && !permissive)
960  {
961  THROW_ERROR(std::string("Error : component " + obj->get_id() + " in/output port " + tempi->get_id() +
962  " is not bound\n"));
963  }
964  else if(tempi->get_connections_size() == 0 && permissive)
965  {
967  {
968  THROW_WARNING("component " + obj->get_id() + " in/output port " + tempi->get_id() +
969  " is not bound");
970  }
971  }
972  }
973  }
974  }
975  for(unsigned int i = 0; i < top_c->get_gen_port_size(); i++)
976  {
977  auto* temp = GetPointer<port_o>(top_c->get_gen_port(i));
978  if(!temp)
979  {
980  THROW_ERROR("not expected type of port");
981  }
982  if(temp->get_kind() == port_o_K && temp->get_connections_size() == 0 && !permissive)
983  {
984  THROW_ERROR(std::string("Error : component " + obj->get_id() + " generic port " + temp->get_id() +
985  " is not bound\n"));
986  }
987  else if(temp->get_kind() == port_o_K && temp->get_connections_size() == 0 && permissive)
988  {
990  {
991  THROW_WARNING("component " + obj->get_id() + " generic port " + temp->get_id() + " is not bound");
992  }
993  }
994  else if(temp->get_kind() == port_vector_o_K)
995  {
996  for(unsigned int w = 0; w < temp->get_ports_size(); w++)
997  {
998  auto* tempi = GetPointer<port_o>(temp->get_port(w));
999  THROW_ASSERT(tempi, "Expected a port got something of different");
1000  if(tempi->get_connections_size() == 0 && !permissive)
1001  {
1002  THROW_ERROR(std::string("Error : component " + obj->get_id() + " generic port " + tempi->get_id() +
1003  " is not bound\n"));
1004  }
1005  else if(tempi->get_connections_size() == 0 && permissive)
1006  {
1008  {
1009  THROW_WARNING("component " + obj->get_id() + " generic port " + tempi->get_id() + " is not bound");
1010  }
1011  }
1012  }
1013  }
1014  }
1015  }
1016  for(unsigned int i = 0; i < top_c->get_internal_objects_size(); i++)
1017  {
1018  switch(top_c->get_internal_object(i)->get_kind())
1019  {
1020  case channel_o_K:
1021  case component_o_K:
1022  {
1023  if(!top_c->get_internal_object(i)->get_black_box())
1024  {
1025  check_structure(top_c->get_internal_object(i), permissive);
1026  }
1027  break;
1028  }
1029  case constant_o_K:
1030  case signal_o_K:
1031  case signal_vector_o_K:
1032  case bus_connection_o_K:
1033  break;
1034  case action_o_K:
1035  case data_o_K:
1036  case event_o_K:
1037  case port_o_K:
1038  case port_vector_o_K:
1039  default:
1040  THROW_ERROR("Internal object not foreseen: " + std::string(top_c->get_internal_object(i)->get_kind_text()));
1041  }
1042  }
1043 }
1044 
1045 void structural_manager::INIT(bool permissive)
1046 {
1047  check_structure(circuit, permissive);
1048  if(og)
1049  {
1050  delete og;
1051  }
1052  if(data_graph)
1053  {
1054  delete data_graph;
1055  }
1056  if(circuit_graph)
1057  {
1058  delete circuit_graph;
1059  }
1064 }
1065 
1067  const std::string& fu_name,
1068  const std::string& library_name,
1069  const structural_objectRef owner,
1070  const technology_managerConstRef TM)
1071 {
1072  THROW_ASSERT(!owner || owner->get_kind() == component_o_K || owner->get_kind() == channel_o_K,
1073  "Expected a component or a channel got something of different");
1074  technology_nodeRef port_tec_node = TM->get_fu(fu_name, library_name);
1075  THROW_ASSERT(port_tec_node,
1076  std::string("gate not found: ") + fu_name + " " + std::string(" in library: ") + library_name);
1077  if(GetPointer<functional_unit_template>(port_tec_node))
1078  {
1079  port_tec_node = GetPointer<functional_unit_template>(port_tec_node)->FU;
1080  }
1081  THROW_ASSERT(port_tec_node, "port_tec_node is null");
1082  THROW_ASSERT(GetPointer<functional_unit>(port_tec_node), "GetPointer<functional_unit>(port_tec_node) is null");
1083  THROW_ASSERT(GetPointer<functional_unit>(port_tec_node)->CM,
1084  "GetPointer<functional_unit>(port_tec_node)->CM is null for " + fu_name);
1085  structural_objectRef curr_lib_instance = GetPointer<functional_unit>(port_tec_node)->CM->get_circ();
1086  THROW_ASSERT(curr_lib_instance->get_kind() == component_o_K, "Expected a component got something of different");
1088  if(!owner)
1089  {
1090  circuit = curr_gate; // set the top component of the circuit manager.
1091  }
1092  curr_lib_instance->copy(curr_gate);
1093  curr_gate->set_id(id);
1094  if(owner)
1095  {
1096  GetPointer<module>(owner)->add_internal_object(curr_gate);
1097  }
1098  return curr_gate;
1099 }
1100 
1104 template <class Graph>
1105 void circuit_add_edge(typename boost::graph_traits<Graph>::vertex_descriptor A,
1106  typename boost::graph_traits<Graph>::vertex_descriptor B, int selector, Graph& g,
1107  const structural_objectRef from1, structural_objectRef to1, bool is_critical = false)
1108 {
1109  typename boost::graph_traits<Graph>::out_edge_iterator oi, oi_end;
1110  typename boost::graph_traits<Graph>::edge_descriptor e;
1111  bool inserted;
1112  for(boost::tie(oi, oi_end) = boost::out_edges(A, g); oi != oi_end; oi++)
1113  {
1114  if(boost::target(*oi, g) != B)
1115  {
1116  continue;
1117  }
1118  if(GET_FROM_PORT(&g, *oi) == from1 && GET_TO_PORT(&g, *oi) == to1)
1119  {
1120  return;
1121  }
1122  }
1123  boost::tie(e, inserted) = boost::add_edge(A, B, EdgeProperty(selector), g);
1124  EDGE_ADD_FROM_PORT(&g, e, from1);
1125  EDGE_ADD_TO_PORT(&g, e, to1);
1126  EDGE_SET_CRITICAL(&g, e, is_critical);
1127 }
1128 
1138  graphs_collection* bg,
1139  const std::map<structural_objectRef, boost::graph_traits<graphs_collection>::vertex_descriptor>& module_vertex_rel,
1140  const structural_objectRef& p1, const structural_objectRef& p2,
1141  boost::graph_traits<graphs_collection>::vertex_descriptor en,
1142  boost::graph_traits<graphs_collection>::vertex_descriptor ex, bool is_critical = false)
1143 {
1144  THROW_ASSERT(p1->get_kind() == port_o_K || p1->get_kind() == port_vector_o_K,
1145  "Expected a port got something of different");
1146  THROW_ASSERT(p2->get_kind() == port_o_K || p2->get_kind() == port_vector_o_K,
1147  "Expected a port got something of different");
1148 
1149  structural_objectRef p_obj1 = p1;
1150  structural_objectRef p_obj2 = p2;
1151 
1152  // now detect the vertex associated with the ports
1153  boost::graph_traits<graphs_collection>::vertex_descriptor src,
1154  tgt = boost::graph_traits<graphs_collection>::null_vertex();
1155 
1156  structural_objectRef owner1 = p_obj1->get_owner();
1157  structural_objectRef owner2 = p_obj2->get_owner();
1158 
1159  // first detect the actual owner
1160  if(owner1 && owner1->get_kind() == port_vector_o_K)
1161  {
1162  owner1 = owner1->get_owner();
1163  }
1164  if(owner2 && owner2->get_kind() == port_vector_o_K)
1165  {
1166  owner2 = owner2->get_owner();
1167  }
1168 
1169  int edge_type = DATA_SELECTOR;
1170  if(GetPointerS<port_o>(p_obj2)->get_is_clock() || GetPointerS<port_o>(p_obj2)->get_is_clock())
1171  {
1172  edge_type = CLOCK_SELECTOR;
1173  }
1174 
1175  if(owner1 == owner2) // pass through signal
1176  {
1177  if(GetPointerS<port_o>(p_obj1)->get_port_direction() == port_o::OUT &&
1178  GetPointerS<port_o>(p_obj2)->get_port_direction() == port_o::IN)
1179  {
1180  std::swap(p_obj1, p_obj2);
1181  }
1182 
1183  src = en;
1184  tgt = ex;
1185  }
1186  else
1187  {
1189  if(owner1 && owner1->get_owner() == owner2)
1190  {
1191  src = module_vertex_rel.at(owner1);
1192  if(GetPointerS<port_o>(p_obj2)->get_port_direction() == port_o::OUT)
1193  {
1194  tgt = ex;
1195  }
1196  else if(GetPointerS<port_o>(p_obj2)->get_port_direction() == port_o::IN)
1197  {
1198  tgt = en;
1199  }
1200  else if(GetPointerS<port_o>(p_obj2)->get_port_direction() == port_o::IO)
1201  {
1202  if(GetPointerS<port_o>(p_obj1)->get_port_direction() == port_o::IN)
1203  {
1204  tgt = en;
1205  }
1206  else
1207  {
1208  tgt = ex;
1209  }
1210  }
1211  else
1212  {
1213  THROW_ERROR("Something wrong");
1214  }
1215  if(GetPointerS<port_o>(p_obj1)->get_port_direction() == port_o::IN)
1216  {
1217  std::swap(src, tgt);
1218  std::swap(p_obj1, p_obj2);
1219  }
1220  }
1222  else if(owner2 && owner2->get_owner() == owner1)
1223  {
1224  src = en;
1225  tgt = module_vertex_rel.find(owner2)->second;
1226  }
1227  else // module port
1228  {
1229  src = module_vertex_rel.find(owner1)->second;
1230  tgt = module_vertex_rel.find(owner2)->second;
1231 
1232  if(GetPointerS<port_o>(p_obj1)->get_port_direction() == port_o::IN &&
1233  GetPointerS<port_o>(p_obj2)->get_port_direction() == port_o::OUT)
1234  {
1235  std::swap(src, tgt);
1236  std::swap(p_obj1, p_obj2);
1237  }
1238 
1240  if(GetPointerS<port_o>(p_obj1)->get_port_direction() == port_o::IN &&
1241  GetPointerS<port_o>(p_obj2)->get_port_direction() == port_o::IN)
1242  {
1243  // std::cerr << "hyper-edge and not significant connectivity" << std::endl;
1244  return;
1245  }
1246 
1247  THROW_ASSERT(GetPointerS<port_o>(p_obj1)->get_port_direction() == port_o::OUT &&
1248  GetPointerS<port_o>(p_obj2)->get_port_direction() == port_o::IN,
1249  "Not supported situation: " + p_obj1->get_path() + " <-> " + p_obj2->get_path());
1250  }
1251  }
1252 
1253  circuit_add_edge(src, tgt, edge_type, *bg, p_obj1, p_obj2, is_critical);
1254 
1255 #if 0
1256  //try to detect a direction
1257  if ((pp1->get_port_direction() == port_o::IN && pp2->get_port_direction() != port_o::IN) ||
1258  (pp1->get_port_direction() != port_o::OUT && pp2->get_port_direction() == port_o::OUT)
1259  )
1260  std::swap(pp1, pp2);
1261 
1262  else
1263  {
1264  if (owner2 && owner1 == owner2->get_owner())// pp1 is a top port
1265  {
1266  THROW_ASSERT(module_vertex_rel.find(owner2) != module_vertex_rel.end(), "module not found");
1267  v2 = module_vertex_rel.find(owner2)->second;
1268  if (pp1->get_port_direction() != port_o::OUT or pp2->get_port_direction() == port_o::IN)
1269  v1 = en;
1270  else
1271  {
1272  v1 = ex;
1273  std::swap(v1, v2);
1274  std::swap(pp1, pp2);
1275  }
1276  }
1277  else if (owner1 && owner2 == owner1->get_owner())// pp2 is a top port
1278  {
1279  THROW_ASSERT(module_vertex_rel.find(owner1) != module_vertex_rel.end(), "module not found");
1280  v1 = module_vertex_rel.find(owner1)->second;
1281  if (pp2->get_port_direction() != port_o::OUT or pp1->get_port_direction() == port_o::IN)
1282  {
1283  v2 = en;
1284  std::swap(v1, v2);
1285  std::swap(pp1, pp2);
1286  }
1287  else
1288  v2 = ex;
1289  }
1290  else
1291  {
1292  THROW_ASSERT(module_vertex_rel.find(owner1) != module_vertex_rel.end(), "module not found");
1293  v1 = module_vertex_rel.find(owner1)->second;
1294  THROW_ASSERT(module_vertex_rel.find(owner2) != module_vertex_rel.end(), "module not found");
1295  v2 = module_vertex_rel.find(owner2)->second;
1296  }
1297  }
1298  //std::cerr << " connection " << pp1->get_path() << " -> " << pp2->get_path() << std::endl;
1299  //in case both ports are IO or GEN two opposite edges are added
1300  if ((pp1->get_port_direction() == port_o::IO || pp1->get_port_direction() == port_o::GEN) && (pp2->get_port_direction() == port_o::IO || pp2->get_port_direction() == port_o::GEN))
1301  {
1302  circuit_add_edge(v1, v2, DATA_SELECTOR, *bg, p1, p2, is_critical);
1303  circuit_add_edge(v2, v1, DATA_SELECTOR, *bg, p2, p1, is_critical);
1304  }
1305  else if ((pp1->get_port_direction() == port_o::IN && pp2->get_port_direction() == port_o::IN && ((v1 == en && v2 != en) || (v1 != en && v2 == en))) ||
1306  (pp1->get_port_direction() == port_o::OUT && pp2->get_port_direction() == port_o::OUT && ((v1 == ex && v2 != ex) || (v1 != ex && v2 == ex))) ||
1307  pp1->get_port_direction() != pp2->get_port_direction()
1308  )
1309  {
1310  structural_objectRef port;
1311  if (pp1 != GetPointer<port_o>(p1)) //check possible swap
1312  {
1313  if (pp1->get_is_clock() || pp2->get_is_clock())
1314  circuit_add_edge(v1, v2, CLOCK_SELECTOR, *bg, p2, p1, is_critical);
1315  else
1316  circuit_add_edge(v1, v2, DATA_SELECTOR, *bg, p2, p1, is_critical);
1317  }
1318  else
1319  {
1320  if (pp1->get_is_clock() || pp2->get_is_clock())
1321  circuit_add_edge(v1, v2, CLOCK_SELECTOR, *bg, p1, p2, is_critical);
1322  else
1323  circuit_add_edge(v1, v2, DATA_SELECTOR, *bg, p1, p2, is_critical);
1324  }
1325  }
1326 #endif
1327 }
1328 
1337 static void add_directed_edge(
1338  graphs_collection* bg,
1339  const std::map<structural_objectRef, boost::graph_traits<graphs_collection>::vertex_descriptor>& module_vertex_rel,
1340  const structural_objectRef& p1, const structural_objectRef& p2,
1341  boost::graph_traits<graphs_collection>::vertex_descriptor en,
1342  boost::graph_traits<graphs_collection>::vertex_descriptor ex, bool is_critical = false)
1343 {
1344  // the port is not connected to any object
1345  if(!p2)
1346  {
1347  return;
1348  }
1349  THROW_ASSERT(p1, "not valid object");
1350 
1351  // std::cerr << "p1 is " << p1->get_kind_text() << std::endl;
1352  // std::cerr << "p2 is " << p2->get_kind_text() << std::endl;
1353 
1354  switch(p2->get_kind())
1355  {
1356  case port_o_K:
1357  case port_vector_o_K:
1358  {
1359  // std::cerr << "p1: " << p1->get_path() << "(" << p1->get_kind_text() << ") -> p2: " << p2->get_path() << "("
1360  // << p2->get_kind_text() << ")" << std::endl;
1361  add_directed_edge_single(bg, module_vertex_rel, p1, p2, en, ex, is_critical);
1362  break;
1363  }
1364  case signal_o_K:
1365  case signal_vector_o_K:
1366  {
1367  auto* conn = GetPointer<signal_o>(p2);
1368  for(unsigned int k = 0; k < conn->get_connected_objects_size(); k++)
1369  {
1370  if(conn->get_port(k) != p1)
1371  {
1372  // std::cerr << "p1: " << p1->get_path() << "(" << p1->get_kind_text() << ") -> p2: " <<
1373  // conn->get_port(k)->get_path() << "(" << conn->get_port(k)->get_kind_text() << ")" << std::endl;
1374  add_directed_edge_single(bg, module_vertex_rel, p1, conn->get_port(k), en, ex, is_critical);
1375  }
1376  }
1377  break;
1378  }
1379  case constant_o_K:
1380  {
1381  structural_objectRef owner1 = p1->get_owner();
1382  boost::graph_traits<graphs_collection>::vertex_descriptor v1;
1383  if(owner1 && owner1->get_kind() == port_vector_o_K)
1384  {
1385  owner1 = owner1->get_owner();
1386  }
1387  THROW_ASSERT(module_vertex_rel.find(owner1) != module_vertex_rel.end(), "module not found");
1388  v1 = module_vertex_rel.find(owner1)->second;
1389  circuit_add_edge(en, v1, DATA_SELECTOR, *bg, p2, p1, is_critical);
1390  break;
1391  }
1392  case component_o_K:
1393  {
1394  THROW_WARNING("Still to be checked!");
1396  structural_objectRef owner1 = p1->get_owner();
1397  structural_objectRef owner2 = p2->get_owner();
1398  boost::graph_traits<graphs_collection>::vertex_descriptor v1, v2;
1399  if(owner1 && owner1->get_kind() == port_vector_o_K)
1400  {
1401  owner1 = owner1->get_owner();
1402  }
1403  if(owner1 == owner2)
1404  { // top ports
1405  v1 = en;
1406  }
1407  else
1408  {
1409  THROW_ASSERT(module_vertex_rel.find(owner1) != module_vertex_rel.end(), "module not found");
1410  v1 = module_vertex_rel.find(owner1)->second;
1411  }
1412  THROW_ASSERT(module_vertex_rel.find(p2) != module_vertex_rel.end(), "module not found");
1413  v2 = module_vertex_rel.find(p2)->second;
1414  circuit_add_edge(v1, v2, CHANNEL_SELECTOR, *bg, p1, p2, is_critical);
1415  break;
1416  }
1417  case action_o_K:
1418  case bus_connection_o_K:
1419  case channel_o_K:
1420  case data_o_K:
1421  case event_o_K:
1422  default:
1423  {
1424  THROW_ERROR("unexpected object type: " + std::string(p2->get_kind_text()));
1425  }
1426  }
1427 }
1428 
1430 {
1431  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Building graph of " + top->get_typeRef()->id_type);
1432 
1433  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - Creating the PI node");
1434  // create the entry node
1435  vertex v_en = bg->AddVertex(NodeInfoRef(new cg_node_info()));
1436  std::string v_en_name = "PI";
1437  GET_NODE_INFO(bg, cg_node_info, v_en)->vertex_name = v_en_name;
1438  GET_NODE_INFO(bg, cg_node_info, v_en)->node_type = TYPE_ENTRY;
1439  GET_NODE_INFO(bg, cg_node_info, v_en)->node_operation = ENTRY;
1440  const module* mod = GetPointer<module>(top);
1441  for(unsigned int p = 0; p < mod->get_in_port_size(); p++)
1442  {
1443  structural_objectRef port = mod->get_in_port(p);
1444  if(GetPointer<port_o>(port)->get_critical())
1445  {
1446  GET_NODE_INFO(bg, cg_node_info, v_en)->is_critical = true;
1447  }
1448  }
1449 
1450  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - Creating the PO node");
1451  // create the exit node
1452  vertex v_ex = bg->AddVertex(NodeInfoRef(new cg_node_info()));
1453  std::string v_ex_name = "PO";
1454  GET_NODE_INFO(bg, cg_node_info, v_ex)->vertex_name = v_ex_name;
1455  GET_NODE_INFO(bg, cg_node_info, v_ex)->node_type = TYPE_EXIT;
1456  GET_NODE_INFO(bg, cg_node_info, v_ex)->node_operation = EXIT;
1457  for(unsigned int p = 0; p < mod->get_out_port_size(); p++)
1458  {
1459  structural_objectRef port = mod->get_out_port(p);
1460  if(GetPointer<port_o>(port)->get_critical())
1461  {
1462  GET_NODE_INFO(bg, cg_node_info, v_ex)->is_critical = true;
1463  }
1464  }
1465 
1466  // attach the graph property to the graph
1467  auto* graph_info = GetPointer<cg_graph_info>(circuit_graph->GetGraphInfo());
1468  graph_info->Entry = v_en;
1469  graph_info->Entry_name = v_en_name;
1470  graph_info->Exit = v_ex;
1471  graph_info->Exit_name = v_ex_name;
1472 
1474  std::map<structural_objectRef, boost::graph_traits<graphs_collection>::vertex_descriptor> module_vertex_rel;
1475  for(unsigned int i = 0; i < mod->get_internal_objects_size(); i++)
1476  {
1477  switch(mod->get_internal_object(i)->get_kind())
1478  {
1479  case channel_o_K:
1480  case component_o_K:
1481  {
1482  vertex curr_v = bg->AddVertex(NodeInfoRef(new cg_node_info));
1483  module_vertex_rel[mod->get_internal_object(i)] = curr_v;
1484  auto* mod_int = GetPointer<module>(mod->get_internal_object(i));
1485  GET_NODE_INFO(bg, cg_node_info, curr_v)->vertex_name = mod_int->get_id();
1486  GET_NODE_INFO(bg, cg_node_info, curr_v)->node_operation = GET_TYPE_NAME(mod_int);
1487  GET_NODE_INFO(bg, cg_node_info, curr_v)->reference = mod->get_internal_object(i);
1488  if(mod->get_internal_object(i)->get_kind() == component_o_K)
1489  {
1490  GET_NODE_INFO(bg, cg_node_info, curr_v)->is_critical =
1491  GetPointer<module>(mod->get_internal_object(i))->get_critical();
1492  }
1494  " - Creating the node for the instance " + mod_int->get_path());
1495  break;
1496  }
1497  case signal_o_K:
1498  case constant_o_K:
1499  case signal_vector_o_K:
1500  case bus_connection_o_K:
1501  break;
1502  case action_o_K:
1503  case data_o_K:
1504  case event_o_K:
1505  case port_o_K:
1506  case port_vector_o_K:
1507  default:
1508  THROW_ERROR("Structural object not foreseen: " + std::string(mod->get_internal_object(i)->get_kind_text()));
1509  }
1510  }
1511  for(unsigned int i = 0; i < mod->get_internal_objects_size(); i++)
1512  {
1513  switch(mod->get_internal_object(i)->get_kind())
1514  {
1515  case channel_o_K:
1516  case component_o_K:
1517  {
1518  auto* mod_inst = GetPointer<module>(mod->get_internal_object(i));
1519  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Analyzing instance " + mod_inst->get_path());
1520  if(mod_inst->get_in_port_size())
1521  {
1522  // analyzing input ports
1523  for(unsigned int j = 0; j < mod_inst->get_in_port_size(); j++)
1524  {
1525  const structural_objectRef& in_port = mod_inst->get_in_port(j);
1526  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " * Input port: " + in_port->get_path());
1527  // the input port is a single port
1528  if(in_port->get_kind() == port_o_K)
1529  {
1530  const port_o* p = GetPointer<port_o>(in_port);
1532  const structural_objectRef& bounded = p->find_bounded_object();
1533  if(!bounded)
1534  {
1535  continue;
1536  }
1538  " - Bounded object: " + bounded->get_path() + " - " + bounded->get_kind_text());
1539  if(!(GetPointer<signal_o>(bounded) && !(GetPointer<signal_o>(bounded)->is_full_connected())))
1540  {
1542  " - Adding direct edge from " + bounded->get_path() + " to " +
1543  p->get_path());
1544  bool is_critical = false;
1545  if(p->get_critical())
1546  {
1547  if((GetPointer<port_o>(bounded)->get_critical()) or
1548  (GetPointer<signal_o>(bounded) && GetPointer<signal_o>(bounded)->get_critical()))
1549  {
1550  is_critical = true;
1551  }
1552  }
1553  add_directed_edge(bg, module_vertex_rel, in_port, bounded, v_en, v_ex, is_critical);
1554  }
1555  }
1556  else
1557  {
1558  auto* pv = GetPointer<port_o>(mod_inst->get_in_port(j));
1560  for(unsigned int k = 0; k < pv->get_ports_size(); k++)
1561  {
1562  const structural_objectRef& in_port_i = pv->get_port(k);
1564  " - Port: " + in_port_i->get_path());
1565  const structural_objectRef& bounded =
1566  GetPointer<port_o>(pv->get_port(k))->find_bounded_object();
1567  if(!bounded)
1568  {
1569  continue;
1570  }
1572  " - Bounded object: " + bounded->get_path() + " - " +
1573  bounded->get_kind_text());
1574  if(!(GetPointer<signal_o>(bounded) && !(GetPointer<signal_o>(bounded)->is_full_connected())))
1575  {
1577  " - Adding direct edge from " + bounded->get_path() + " to " +
1578  in_port_i->get_path());
1580  {
1581  THROW_WARNING(
1582  "Critical paths are not correctly identified when port vectors are involved");
1583  }
1584  add_directed_edge(bg, module_vertex_rel, in_port_i, bounded, v_en, v_ex);
1585  }
1586  }
1587  }
1588  }
1589  }
1590  // analyzing output ports
1591  if(mod_inst->get_out_port_size())
1592  {
1593  for(unsigned int j = 0; j < mod_inst->get_out_port_size(); j++)
1594  {
1595  const structural_objectRef& out_port = mod_inst->get_out_port(j);
1596  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Output port: " + out_port->get_path());
1597  if(out_port->get_kind() == port_o_K)
1598  {
1599  const port_o* p = GetPointer<port_o>(out_port);
1602  if(!target)
1603  {
1605  continue;
1606  }
1608  " - Bounded object: " + target->get_path() + " - " + target->get_kind_text());
1610  " - Adding direct edge from " + out_port->get_path() + " to " +
1611  target->get_path());
1612  bool is_critical = false;
1613  if(GetPointer<port_o>(out_port)->get_critical())
1614  {
1615  if(GetPointer<port_o>(target)->get_critical())
1616  {
1617  is_critical = true;
1618  }
1619  }
1620  add_directed_edge(bg, module_vertex_rel, out_port, target, v_en, v_ex, is_critical);
1621  }
1622  else
1623  {
1624  auto* pv = GetPointer<port_o>(out_port);
1626  const structural_objectRef target_vector = pv->find_bounded_object();
1627  if(target_vector)
1628  {
1630  "---Adding direct edge from " + pv->get_path() + " to " +
1631  target_vector->get_path());
1632  add_directed_edge(bg, module_vertex_rel, out_port, target_vector, v_en, v_ex);
1633  }
1634  else
1635  {
1636  for(unsigned int k = 0; k < pv->get_ports_size(); k++)
1637  {
1638  const port_o* p = GetPointer<port_o>(pv->get_port(k));
1640  if(!target)
1641  {
1642  continue;
1643  }
1645  "---Adding direct edge from " + p->get_path() + " to " + target->get_path());
1647  {
1648  THROW_WARNING(
1649  "Critical paths are not correctly identified when port vectors are involved");
1650  }
1651  add_directed_edge(bg, module_vertex_rel, pv->get_port(k), target, v_en, v_ex);
1652  }
1653  }
1655  }
1657  }
1658  }
1659  // analyzing in/out ports
1660  if(mod_inst->get_in_out_port_size())
1661  {
1662  for(unsigned int j = 0; j < mod_inst->get_in_out_port_size(); j++)
1663  {
1665  " * In/Out port: " + mod_inst->get_in_out_port(j)->get_path());
1666  const structural_objectRef& bounded =
1667  GetPointer<port_o>(mod_inst->get_in_out_port(j))->find_bounded_object();
1668  if(!bounded)
1669  {
1670  continue;
1671  }
1672  if(mod_inst->get_in_out_port(j)->get_kind() == port_o_K)
1673  {
1674  add_directed_edge(bg, module_vertex_rel, mod_inst->get_in_out_port(j), bounded, v_en, v_ex);
1675  }
1676  else
1677  {
1678  auto* pv = GetPointer<port_o>(mod_inst->get_in_out_port(j));
1679  for(unsigned int k = 0; k < pv->get_ports_size(); k++)
1680  {
1681  const structural_objectRef& bounded_k =
1682  GetPointer<port_o>(pv->get_port(k))->find_bounded_object();
1683  if(!bounded_k)
1684  {
1685  continue;
1686  }
1687  add_directed_edge(bg, module_vertex_rel, pv->get_port(k), bounded_k, v_en, v_ex);
1688  }
1689  }
1690  }
1691  }
1692  // analyzing generic ports
1693  if(mod_inst->get_gen_port_size())
1694  {
1695  for(unsigned int j = 0; j < mod_inst->get_gen_port_size(); j++)
1696  {
1698  " * Generic port: " + mod_inst->get_gen_port(j)->get_path());
1699  const structural_objectRef& bounded =
1700  GetPointer<port_o>(mod_inst->get_gen_port(j))->find_bounded_object();
1701  if(!bounded)
1702  {
1703  continue;
1704  }
1705  if(mod_inst->get_gen_port(j)->get_kind() == port_o_K)
1706  {
1707  add_directed_edge(bg, module_vertex_rel, mod_inst->get_gen_port(j), bounded, v_en, v_ex);
1708  }
1709  else
1710  {
1711  auto* pv = GetPointer<port_o>(mod_inst->get_gen_port(j));
1712  for(unsigned int k = 0; k < pv->get_ports_size(); k++)
1713  {
1714  const structural_objectRef& bounded_k =
1715  GetPointer<port_o>(pv->get_port(k))->find_bounded_object();
1716  if(!bounded_k)
1717  {
1718  continue;
1719  }
1720  add_directed_edge(bg, module_vertex_rel, pv->get_port(k), bounded_k, v_en, v_ex);
1721  }
1722  }
1723  }
1724  }
1725  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Analyzed instance " + mod_inst->get_path());
1726  break;
1727  }
1728  case constant_o_K:
1729  case signal_o_K:
1730  case signal_vector_o_K:
1731  case bus_connection_o_K:
1732  break;
1733  case action_o_K:
1734  case data_o_K:
1735  case event_o_K:
1736  case port_o_K:
1737  case port_vector_o_K:
1738  default:
1739  THROW_ERROR("Structural object not foreseen: " + std::string(mod->get_internal_object(i)->get_kind_text()));
1740  }
1741  }
1742  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Built graph of " + top->get_typeRef()->id_type);
1743 }
1744 
1746 {
1747  // Recurse through child nodes:
1748  const xml_node::node_list list = node->get_children();
1749  for(const auto& iter : list)
1750  {
1751  const auto* Enode = GetPointer<const xml_element>(iter);
1752  if(!Enode || Enode->get_name() != GET_CLASS_NAME(component_o))
1753  {
1754  continue;
1755  }
1756  CM->get_circ()->xload(Enode, CM->get_circ(), CM);
1757  }
1758 }
1759 
1761 {
1762  xml_element* CMnode = rootnode->add_child_element("circuit");
1763  get_circ()->xwrite(CMnode);
1764 }
1765 
1767 {
1768  auto* pin = GetPointer<port_o>(obj);
1769  for(unsigned int j = 0; j < pin->get_connections_size(); j++)
1770  {
1771  structural_objectRef comp = pin->get_connection(j);
1772  if(GetPointer<port_o>(comp))
1773  {
1774  GetPointer<port_o>(comp)->remove_connection(obj);
1775  }
1776  if(GetPointer<signal_o>(comp))
1777  {
1778  GetPointer<signal_o>(comp)->remove_port(obj);
1779  }
1780  }
1781 }
1782 
1784 {
1785  structural_objectRef top_obj = this->get_circ();
1787 
1788  auto* obj_mod = GetPointer<module>(obj);
1789  // std::cerr << "obj: " << obj->get_path() << std::endl;
1790  // std::cerr << "removing inport" << std::endl;
1791  for(unsigned int i = 0; i < obj_mod->get_in_port_size(); i++)
1792  {
1793  structural_objectRef comp_port = obj_mod->get_in_port(i);
1794  if(comp_port->get_kind() == port_o_K)
1795  {
1796  remove_port_connection(comp_port);
1797  }
1798  else if(comp_port->get_kind() == port_vector_o_K)
1799  {
1800  for(unsigned int p = 0; p < GetPointer<port_o>(comp_port)->get_ports_size(); p++)
1801  {
1802  remove_port_connection(GetPointer<port_o>(comp_port)->get_port(p));
1803  }
1804  }
1805  }
1806  // std::cerr << "removing outport" << std::endl;
1807  for(unsigned int i = 0; i < obj_mod->get_out_port_size(); i++)
1808  {
1809  structural_objectRef comp_port = obj_mod->get_out_port(i);
1810  if(comp_port->get_kind() == port_o_K)
1811  {
1812  remove_port_connection(comp_port);
1813  }
1814  else if(comp_port->get_kind() == port_vector_o_K)
1815  {
1816  for(unsigned int p = 0; p < GetPointer<port_o>(comp_port)->get_ports_size(); p++)
1817  {
1818  remove_port_connection(GetPointer<port_o>(comp_port)->get_port(p));
1819  }
1820  }
1821  }
1822 
1823  // std::cerr << "removing signals" << std::endl;
1824  auto* top = GetPointer<module>(top_obj);
1825  top->remove_internal_object(obj);
1826  for(const auto& k : remove)
1827  {
1828  top->remove_internal_object(k);
1829  }
1830 }
1831 
1833 {
1834  THROW_ERROR("Not yet implemented");
1835 }
1836 
1838  structural_objectRef owner)
1839 {
1840  auto* p_old = GetPointer<port_o>(old_obj);
1841  THROW_ASSERT(p_old, "Only port can change their connection");
1842  THROW_ASSERT(new_obj, "New connection has to be a valid one");
1843  // std::cerr << "change connection of: " << old_obj->get_path() << " with port " << new_obj->get_path() << std::endl;
1844  for(unsigned int i = 0; i < p_old->get_connections_size(); i++)
1845  {
1846  structural_objectRef conn_comp = p_old->get_connection(i);
1847  // std::cerr << "change connection between " << old_obj->get_path() << " and " << conn_comp->get_path() << " -
1848  // will be conneted to " << new_obj->get_path() << std::endl;
1849  if(GetPointer<signal_o>(conn_comp) and
1850  GetPointer<signal_o>(conn_comp)->get_owner()->get_kind() != signal_vector_o_K and
1851  conn_comp->get_owner() != owner)
1852  {
1853  continue;
1854  }
1855  if(GetPointer<port_o>(conn_comp) and conn_comp->get_owner() != owner and
1856  conn_comp->get_owner()->get_owner() != owner and
1857  (conn_comp->get_owner()->get_kind() != port_vector_o_K or conn_comp->get_owner()->get_owner() != owner))
1858  {
1859  continue;
1860  }
1861  if(GetPointer<port_o>(new_obj) and !GetPointer<port_o>(new_obj)->is_connected(conn_comp))
1862  {
1863  add_connection(new_obj, conn_comp);
1864  }
1865  if(GetPointer<port_o>(conn_comp))
1866  {
1867  GetPointer<port_o>(conn_comp)->substitute_connection(old_obj, new_obj);
1868  }
1869  else if(GetPointer<signal_o>(conn_comp))
1870  {
1871  GetPointer<signal_o>(conn_comp)->substitute_port(old_obj, new_obj);
1872  }
1873  else
1874  {
1875  THROW_ERROR("Connected component not supported: " + std::string(conn_comp->get_kind_text()));
1876  }
1877  }
1878 }
void add_connection(structural_objectRef src, structural_objectRef dest)
Create a connection between a source structural object and a destination structural object...
#define EXIT
Definition: global.h:46
void remove_module(structural_objectRef obj)
static void xload(const xml_element *node, structural_managerRef const &CM)
Load a structural manager from an xml file.
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
void remove_empty_signal(structural_objectRef &signal)
Remove an existing signal from the SM.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
void * top(node_stack *head)
Definition: tree.c:75
File containing functions and utilities to support the printing of debug messagges.
refcount< NP_functionality > NP_functionalityRef
RefCount type definition of the connection class structure.
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_id() const
Return the identifier associated with the structural_object.
void remove_connection(structural_objectRef src, structural_objectRef dest)
structural_objectRef find_bounded_object(const structural_objectConstRef f_owner=structural_objectConstRef()) const
Find the object bounded to the port.
string target
Definition: lenet_tvm.py:16
#define GET_CLASS(obj)
Macro returning the actual type of an object.
static const unsigned int PARAMETRIC_PORT
so_kind
Enumerative type for structural object classes, it is used with get_kind() function to know the actua...
This class describes a port associated with a component or a channel.
const structural_objectRef get_circ() const
Get a reference to circ field.
const std::vector< std::string > SplitString(const std::string &input, const std::string &separators)
Function which splits a string into tokens.
#define GET_NODE_INFO(data, NodeInfo, vertex_index)
Definition: graph.hpp:601
structural_manager(const structural_manager &inst)=delete
This class describes a generic channel.
static bool check_object(std::string id, structural_objectRef owner, so_kind type)
Verify if the component is already associated with owner.
unsigned int get_out_port_size() const
Return the number of output ports.
bool get_critical() const
return if the component is critical or not
std::string get_NP_functionality(NP_functionaly_type type) const
Return the description provided the type.
Node, edge and graph description of the graph associated with a structural description.
Class specification of the graph structures.
int debug_level
debug level
static void add_directed_edge(graphs_collection *bg, const std::map< structural_objectRef, boost::graph_traits< graphs_collection >::vertex_descriptor > &module_vertex_rel, const structural_objectRef &p1, const structural_objectRef &p2, boost::graph_traits< graphs_collection >::vertex_descriptor en, boost::graph_traits< graphs_collection >::vertex_descriptor ex, bool is_critical=false)
Add a directed edge between the nodes associated with p1 and p2.
exceptions managed by PandA
const ParameterConstRef Param
class containing all the parameters
const structural_objectRef get_in_port(unsigned int n) const
Return the ith input port.
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...
The property associated with edge.
Definition: graph.hpp:204
unsigned int get_internal_objects_size() const
Return the number of internal objects.
#define EDGE_ADD_FROM_PORT(data, edge_index, from)
Add a from port to the edge.
Definition: cg_node.hpp:147
Class specification of the manager of the technology library data structures.
Base class description of data information associated with each node of a graph.
redefinition of map to manage ordered/unordered structures
#define GET_TYPE_NAME(structural_obj)
Macro returning the string name of a type.
#define CHANNEL_SELECTOR
Channel line selector.
Definition: cg_node.hpp:67
void print(std::ostream &os) const
Function that prints the circuit data structure.
virtual void xwrite(xml_element *Enode)
Add a structural_object to an xml tree.
#define A
Definition: generate.c:13
#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
Auxiliary methods for manipulating string.
port_direction
Enumerative type describing the direction of a port.
void add_sensitivity(structural_objectRef obj, structural_objectRef pr)
Add an object to the sensitivity list of process/service.
static bool check_type(structural_type_descriptorRef src_type, structural_type_descriptorRef dest_type)
Check if two type descriptors are consistent.
void INIT(bool permissive=false)
virtual std::string get_kind_text() const =0
Virtual function used to get the string name of a structural_object instance.
#define TYPE_EXIT
constant identifying the node type of an exit node.
void check_structure(structural_objectRef obj, bool permissive=false)
perform some check on the circuit manager.
structural_objectRef create(std::string id, so_kind ctype, structural_objectRef owner, structural_type_descriptorRef obj_type, unsigned int treenode=0)
Create a new object of the circuit.
bool starts_with(const std::string &str, const std::string &pattern)
static void add_NP_functionality(structural_objectRef cir, NP_functionality::NP_functionaly_type dt, std::string functionality_description)
Add a not-parsed functionality.
void add_NP_functionality(NP_functionaly_type type, const std::string &functionality_description)
Add a non SystemC based description.
#define GET_TO_PORT(data, edge_index)
Helper macro returning the to port/channel.
Definition: cg_node.hpp:154
unsigned map[NUM_VERTICES]
Definition: bfs.c:12
#define ENTRY
Superclass include.
void set_top_info(const std::string &id, const technology_managerRef &LM, const std::string &Library="")
~structural_manager()
Destructor.
static const uint32_t k[]
Definition: sha-256.c:22
void circuit_add_edge(typename boost::graph_traits< Graph >::vertex_descriptor A, typename boost::graph_traits< Graph >::vertex_descriptor B, int selector, Graph &g, const structural_objectRef from1, structural_objectRef to1, bool is_critical=false)
this template function adds an edge to the bulk graph and possibly a label to the edge...
void remove_port_connection(const structural_objectRef &obj)
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.
static structural_objectRef add_port(const std::string &id, port_o::port_direction pdir, structural_objectRef owner, structural_type_descriptorRef type_descr, unsigned int treenode=0)
Create a new port.
const structural_objectRef get_out_port(unsigned int n) const
Return the ith output port.
static const unsigned int PARAMETRIC_SIGNAL
const vertex & get_PI(structural_objectRef level) const
Return the PI vertex of the circuit, at a specific level.
#define DATA_SELECTOR
Data line selector.
Definition: cg_node.hpp:63
bool check_type(structural_objectRef src_type, structural_objectRef dest_type)
Check if two type structural object are consistent.
redefinition of set to manage ordered/unordered structures
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
Definition: graph.hpp:1303
bool check_bound(structural_objectRef src, structural_objectRef sign)
Function that check if a signal (or port) is already bound on a port.
General class used to describe a graph in PandA.
Definition: graph.hpp:771
virtual enum so_kind get_kind() const =0
Virtual function used to find the real type of a structural_object instance.
#define GET_CLASS_NAME(meth)
Macro returning the name of a class.
Definition: utility.hpp:102
std::list< xml_nodeRef > node_list
type for list of xml nodes
Definition: xml_node.hpp:90
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
Definition: exceptions.hpp:263
structural_objectRef circuit
Structure that represent circuit.
graph * data_graph
Graph only composed by the data flow in the circuit.
refcount< NodeInfo > NodeInfoRef
RefCount type definition of the NodeInfo class structure.
Definition: node_info.hpp:98
static void add_directed_edge_single(graphs_collection *bg, const std::map< structural_objectRef, boost::graph_traits< graphs_collection >::vertex_descriptor > &module_vertex_rel, const structural_objectRef &p1, const structural_objectRef &p2, boost::graph_traits< graphs_collection >::vertex_descriptor en, boost::graph_traits< graphs_collection >::vertex_descriptor ex, bool is_critical=false)
Add a directed edge between the nodes associated with p1 and p2.
Base class for graph property.
#define HIERARCHY_SEPARATOR
Information associated with a circuit graph node.
Definition: cg_node.hpp:76
GraphInfoRef GetGraphInfo()
FIXME: this method should become protected and called by equivalent method in subclasses Get the grap...
Definition: graph.hpp:1051
structural_objectRef add_constant(std::string id, structural_objectRef owner, structural_type_descriptorRef type, std::string value, unsigned int treenode=0)
Create a new constant;.
structural_objectRef add_module_from_technology_library(const std::string &id, const std::string &fu_name, const std::string &library_name, const structural_objectRef owner, const technology_managerConstRef TM)
Create a new object starting from a library component.
Template definition of refcount.
void SetParameter(const std::string &name, const std::string &value)
Specify a parameter for the top module.
refcount< GraphInfo > GraphInfoRef
RefCount type definition of the GraphInfo class structure.
Definition: graph_info.hpp:74
unsigned int get_in_port_size() const
Return the number of input ports.
This class describes a simple logic/RTL signal.
bulk graph.
Definition: graph.hpp:287
std::string id_type
Original type id of the structural object.
void reconnect_signal_member(structural_objectRef &member, structural_objectRef &from_signal, structural_objectRef &to_signal)
Disconnects a member from from_signal and reconnects it to to_signal.
const structural_type_descriptorRef & get_typeRef() const
Return the type descriptor of the structural_object.
graph * circuit_graph
Graph containing all lines of the circuit.
static structural_objectRef add_sign(std::string id, structural_objectRef owner, structural_type_descriptorRef sign_type, unsigned int treenode=0)
Create a new signal.
const structural_objectRef get_owner() const
Return the owner.
#define GET_FROM_PORT(data, edge_index)
Helper macro returning the from port.
Definition: cg_node.hpp:132
virtual void copy(structural_objectRef dest) const
Perform a copy of the structural object.
int debug_level
debug level for the object
void change_connection(structural_objectRef old_obj, structural_objectRef new_obj, structural_objectRef owner)
static void change_port_direction(structural_objectRef port_object, port_o::port_direction pdir, structural_objectRef owner)
Change the direction of the port.
refcount< structural_object > structural_objectRef
RefCount type definition of the structural_object class structure.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
this class is used to manage the command-line or XML options.
NP_functionaly_type
functionality type descriptors.
#define EDGE_ADD_TO_PORT(data, edge_index, _to)
Add a to port/channel to the edge.
Definition: cg_node.hpp:162
node_list const & get_children()
Obtain the list of child nodes.
Definition: xml_node.hpp:310
#define TYPE_ENTRY
constant identifying the node type of an entry node.
Class implementation of the structural_manager.
This class describes a generic component.
uint32_t sign
graphs_collection * og
Bulk graph used to represent all graphs.
Class specification of the manager for each library.
#define CLOCK_SELECTOR
Clock line selector.
Definition: cg_node.hpp:65
This class describes a constant value.
#define PURE_DATA_SELECTOR
All but clock lines selector.
Definition: cg_node.hpp:71
void build_graph(const structural_objectRef &top, graphs_collection *bg)
build a graph starting from a structural object.
#define DEBUG_LEVEL_VERBOSE
verbose debugging print is performed.
Information associated with the whole graph of a circuit.
Definition: cg_node.hpp:175
Not parsed functionality descriptor of a module.
#define ALL_LINES_SELECTOR
All lines selector.
Definition: cg_node.hpp:69
#define B
Definition: generate.c:14
This class describes a generic module.
static structural_objectRef add_port_vector(std::string id, port_o::port_direction pdir, unsigned int n_ports, structural_objectRef owner, structural_type_descriptorRef type_descr, unsigned int treenode=0)
Create a new port_vector.
const std::string get_name() const
Returns the name of the type descriptor.
virtual boost::graph_traits< boost_graphs_collection >::vertex_descriptor AddVertex(const NodeInfoRef info)
Add a vertex to this graph with a property.
Definition: graph.cpp:57
xml_element * add_child_element(const std::string &name)
Add a child element to this node.
Definition: xml_node.cpp:54
void xwrite(xml_element *rootnode, const technology_nodeRef &tn=technology_nodeRef()) const
Add a component to an xml tree.
void WriteDot(const std::string &file_name, circuit_graph_type gt, graph *g=nullptr) const
Function that writes the dot file of the graph by using the AT&T dot format.
static structural_objectRef add_sign_vector(std::string id, unsigned int n_signs, structural_objectRef owner, structural_type_descriptorRef sign_type, unsigned int treenode=0)
#define EDGE_SET_CRITICAL(data, edge_index, critical)
Set the edge as critical.
Definition: cg_node.hpp:169
#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