source: sources/src/graph.cc @ 28

Last change on this file since 28 was 27, checked in by buchmann, 16 years ago

SystemCASS now uses autoconf/automake to build the API. Regression tests still
use the old Makefiles.
(thanks to Nicolas Pouillon)

The library directory no longer is "lib-arch-system". The directory now is "lib-linux". Everyone needs to pay attention about SYSTEMCASS environment variable.

Changes:

  • system header includes
  • Add includes to config.h (generated by autoconf/automake)
  • test:
    • linux preprocessor macro instead of _WIN32
    • CONFIG_DEBUG instead of DEBUG

Removes:

  • Makefile
  • guess_endianness.cc
  • guess_os.sh
  • assert.h (we now use standard assert.h)
  • Options.def
File size: 8.9 KB
Line 
1/*------------------------------------------------------------\
2|                                                             |
3| Tool    :                  systemcass                       |
4|                                                             |
5| File    :                 graph.cc                          |
6|                                                             |
7| Author  :                 Petrot Frédéric                   |
8|                           Taktak Sami                       |
9|                           Buchmann Richard                  |
10|                                                             |
11| Date    :                   09_07_2004                      |
12|                                                             |
13\------------------------------------------------------------*/
14
15/*
16 * This file is part of the Disydent Project
17 * Copyright (C) Laboratoire LIP6 - Département ASIM
18 * Universite Pierre et Marie Curie
19 *
20 * Home page          : http://www-asim.lip6.fr/disydent
21 * E-mail             : mailto:richard.buchmann@lip6.fr
22 *
23 * This library is free software; you  can redistribute it and/or modify it
24 * under the terms  of the GNU Library General Public  License as published
25 * by the Free Software Foundation; either version 2 of the License, or (at
26 * your option) any later version.
27 *
28 * Disydent is distributed  in the hope  that it  will be
29 * useful, but WITHOUT  ANY WARRANTY; without even the  implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
31 * Public License for more details.
32 *
33 * You should have received a copy  of the GNU General Public License along
34 * with the GNU C Library; see the  file COPYING. If not, write to the Free
35 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
36 */
37
38/*
39 * $Log: graph.cc,v $
40 * Revision 1.10  2006/06/12 14:02:04  buchmann
41 * - Now sort transition and generation functions by fonction pointer
42 *   (Thank to Nicolas Pouillon)
43 * - Add Nicolas Pouillon as contributor into splash screen
44 * - Rename files and classes from "dependancy" to "dependency".
45 * - Add some references to bibliography file
46 * - Add licence note to every files
47 * - Rename "module graph" to "process graph"
48 * - Now dump module graph when using --t option and CASS scheduling at the same
49 *   time
50 *
51 * Bug fixes :
52 * - check user time ( != 0) before computing simulation performance
53 * - Remove reinterpret_cast (for pending write) because of unexpected results
54 * - Add ASSERT in trace functions
55 *
56 * Revision 1.9  2005/10/12 10:00:59  buchmann
57 * Bug fix :
58 * - test to avoid malloc(0)
59 *
60 * Remove :
61 * - unused variable
62 *
63 * Revision 1.8  2005/09/14 14:08:24  buchmann
64 * Add Werror flag to compile the debug library.
65 * Split sc_clock implementation from sc_port to sc_clock.
66 * Add a helper message to write mealy functions avoiding combinational cycle.
67 *
68 * Bug fix :
69 * - cvs rules is no longer circular
70 * - bit2string
71 * - port binding (sc_in to sc_out)
72 * - error message from FSM rules checker
73 * - sc_time copy operator
74 *
75 * Code cleaning :
76 * - remove duplicated code (entity.cc and sc_port.cc)
77 * - remove duplicated declarations (internal_ext.h and internal.h)
78 *
79 * Revision 1.7  2005/03/29 14:04:30  buchmann
80 * Bug fix :
81 * -  Evaluation order of Mealy functions
82 *
83 * Print more informations when DUMP_STAGE is defined.
84 *
85 * Revision 1.6  2005/01/20 09:15:12  buchmann
86 * add following functions to sc_uint classes :
87 * - operator []
88 * - range (left,right)
89 *
90 * support to port dependancy declarations.
91 * print used precompiled options in verbose mode.
92 * use pedantic flag.
93 * add some rules to generate documentations.
94 *
95 * Revision 1.5  2004/09/27 14:40:13  buchmann
96 * bug fix :
97 * - allow the use of user-defined structs in sc_signal/sc_in/sc_out/sc_inout
98 * - use sc_dt namespace like official SystemC engine
99 *
100 * add :
101 * - dump the signal/port/module dependancy graph in dot format
102 *
103 * Graph library is now splitted from the SystemCASS specific code.
104 *
105 */
106
107#include <cstdio>
108#include <cstring>
109#include <map>
110
111#include "graph.h"
112#include "sc_sensitive.h"
113#include "sc_module.h"
114#include "sc_port.h"
115#ifdef HAVE_CONFIG_H
116#include "config.h"
117#endif
118
119using namespace std;
120
121/* Sorry for that, Mr Knuth :-) */
122
123Graph *gb_new_graph(int n)
124{
125Graph *g;
126
127   g = (Graph *) malloc(sizeof(Graph));
128   g->n = n;
129   if (n)
130   {
131     g->vertices = (Vertex *) malloc(n * sizeof(Vertex));
132     (void)memset(g->vertices, 0, n * sizeof(Vertex));
133   } else {
134     g->vertices = NULL;
135   }
136   return g;
137}
138
139static void gb_new_arc(Vertex *u, Vertex *v, long l)
140{
141Arc *a;
142
143   a       = (Arc *) malloc(sizeof(Arc));
144   a->next = u->arcs;
145   u->arcs = a;
146   a->tip  = v;
147   a->len  = l;
148}
149
150/* end Sorry */
151
152#define VERTEX 220898
153
154#define type     u.I
155
156void new_arc(Vertex *u, Vertex *v)
157{
158Arc *a;
159#ifdef CONFIG_DEBUG
160        if ((u == NULL) || (v == NULL))
161                exit(29042004);
162#endif
163   for (a = u->arcs; a; a = a->next)
164      if (a->tip == v)
165         return;
166   gb_new_arc(u, v, 0L);
167}
168
169#define rank z.I
170#define parent y.V
171#define untagged x.A
172#define link w.V
173#define min v.V
174
175#define infinity g->n
176
177/* strong_component: extracts and topologically sorts the strong components of
178 * a graph.
179 * The returned data structure is a chain_list of chain_lists.
180 * The first list implicitely lists the components in order, and the pointed
181 * to ones list the components contents (one or more vertices) */
182
183extern strong_component_list_t *strong_component(Graph *g)
184{
185  long nn;
186  Vertex *active_stack;
187  Vertex *settled_stack;
188  Vertex *vv;
189 
190  register Vertex *v;
191 
192  strong_component_list_t *strongcomponents = new strong_component_list_t;
193        typedef std::vector<void*> void_list_t;
194  void_list_t *component;
195
196  if (g->vertices == NULL)
197    return strongcomponents;
198
199 /* Make all vertices unseen and all arcs untagged */
200 for (v = g->vertices + g->n - 1; v >= g->vertices; v--) {
201   v->rank = 0;
202   v->untagged = v->arcs;
203 }
204 nn = 0;
205 active_stack = settled_stack = NULL;
206
207 for (vv = g->vertices; vv < g->vertices + g->n; vv++)
208   if (vv->rank == 0) { /* vv is still unseen */
209     v = vv;
210     v->parent = NULL;
211     
212     v->rank = ++nn;
213     v->link = active_stack;
214     active_stack = v;
215     v->min = v;
216     
217     do { /* Eplore one step from the current vertex v, possibly moving to another vertex
218             and calling it v */
219       register Vertex *u;               /* a vertex adjacent to v */
220       register Arc *a = v->untagged;    /* v's first remaining untagged arc, if any */
221       if (a) {
222         u = a->tip;
223         v->untagged = a->next;    /* tag the arc from v to u */
224         if (u->rank) {    /* we've seen u already */
225           if (u->rank < v->min->rank) /* non-tree arc, jutt update v->min */
226             v->min = u;
227         } else {   /* u is presently unseen */
228           u->parent = v; /* the arcfrom v to u is a new tree arc */
229           v = u;         /* u will now be the currnt vertex */
230           v->rank = ++nn;  /* make vertex v active */
231           v->link = active_stack;
232           active_stack = v;
233           v->min = v;
234         }
235       } else { /* all arcs from v are tagged, so v matures */
236         u = v->parent; /* prepare to backtrack in the tree */
237         if (v->min == v) {
238           /* Remove v and all its successors on the activestack from the tree,
239              and mark them as a strong component of the graph */
240           register Vertex *t; /* runs though the vertices of the new strong component */
241           
242           t = active_stack;
243           active_stack = v->link;
244           v->link = settled_stack;
245           settled_stack = t; /* we've moved the top of one stack to the other */
246           component = new void_list_t;
247           /* singe vetex */
248           if (t != v) { /* NOT singe vetex */
249             while (t != v) {
250               component->push_back(t->data);
251               t->rank = infinity; /* now t is settled */
252               t->parent = v;  /* and v represents the new strong component */
253               t = t->link;
254             }
255           }
256           component->push_back(v->data);
257           strongcomponents->push_back(component);
258           v->rank = infinity; /* v too is settled */
259           v->parent = v; /* and represents its own strong component */
260         } else /* the arc from u to v has just matured, making v->min visible from u */
261           if (v->min->rank < u->min->rank) u->min = v->min;
262         v = u; /* the former parent of v is the new current vertex v */
263       }
264     } while (v != NULL);
265   }
266
267 return strongcomponents;
268}
269
270bool 
271has_cycle (const strong_component_list_t &l)
272{       
273        strong_component_list_t::const_iterator it;
274        for (it = l.begin (); it != l.end (); ++it)
275        {
276                if ((*it)->size() > 1)
277                        return true;
278        }
279        return false;
280}
281
282#if 0
283const component_list_t*
284get_cycle (const strong_component_list_t &l)
285{       
286        strong_component_list_t::const_iterator it;
287        for (it = l.begin (); it != l.end (); ++it)
288        {
289    const component_list_t *c = *it;
290                if (c->size() > 1)
291                        return c;
292        }
293        return NULL;
294}
295
296void
297print_cycle (std::ostream &o,
298             const component_list_t *c)
299{
300  if (c == NULL)
301    return;
302  component_list_t::const_iterator it;
303  for (it = c->begin (); it != c->end (); ++it)
304  {
305    void *v = *it;
306    o << hex << (int) v << " ";
307  }
308  o << "\n";
309}
310#endif
311
Note: See TracBrowser for help on using the repository browser.