source: sources/src/graph.cc @ 60

Last change on this file since 60 was 52, checked in by meunier, 12 years ago

Code formatting in all source files.

File size: 9.8 KB
RevLine 
[1]1/*------------------------------------------------------------\
[52]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  \------------------------------------------------------------*/
[1]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
[12]107#include <cstdio>
[17]108#include <cstring>
[1]109#include <map>
110
111#include "graph.h"
112#include "sc_sensitive.h"
113#include "sc_module.h"
114#include "sc_port.h"
[27]115#ifdef HAVE_CONFIG_H
116#include "config.h"
117#endif
[1]118
119using namespace std;
120
121/* Sorry for that, Mr Knuth :-) */
122
[52]123Graph * gb_new_graph(int n) {
124    Graph * g;
[1]125
[52]126    g = (Graph *) malloc(sizeof(Graph));
127    g->n = n;
128    if (n) {
129        g->vertices = (Vertex *) malloc(n * sizeof(Vertex));
130        (void) memset(g->vertices, 0, n * sizeof(Vertex));
131    }
132    else {
133        g->vertices = NULL;
134    }
135    return g;
[1]136}
137
138
[52]139static void gb_new_arc(Vertex * u, Vertex * v, long l) {
140    Arc * a;
141    a = (Arc *) malloc(sizeof(Arc));
142    a->next = u->arcs;
143    u->arcs = a;
144    a->tip = v;
145    a->len = l;
[1]146}
147
148/* end Sorry */
149
150#define VERTEX 220898
151
[52]152#define type u.I
[1]153
[52]154void new_arc(Vertex * u, Vertex * v) {
155    Arc * a;
[27]156#ifdef CONFIG_DEBUG
[52]157    if ((u == NULL) || (v == NULL)) {
158        exit(29042004);
159    }
[1]160#endif
[52]161    for (a = u->arcs; a != NULL; a = a->next) {
162        if (a->tip == v) {
163            return;
164        }
165    }
166    gb_new_arc(u, v, 0L);
[1]167}
168
[52]169
[1]170#define rank z.I
171#define parent y.V
172#define untagged x.A
173#define link w.V
174#define min v.V
175
176#define infinity g->n
177
178/* strong_component: extracts and topologically sorts the strong components of
179 * a graph.
180 * The returned data structure is a chain_list of chain_lists.
181 * The first list implicitely lists the components in order, and the pointed
182 * to ones list the components contents (one or more vertices) */
183
[52]184extern strong_component_list_t *strong_component(Graph * g) {
185    long nn;
186    Vertex * active_stack;
187    Vertex * settled_stack;
188    Vertex * vv;
[1]189
[52]190    register Vertex * v;
[1]191
[52]192    strong_component_list_t * strongcomponents = new strong_component_list_t;
193    typedef std::vector < void *>void_list_t;
194    void_list_t * component;
[1]195
[52]196    if (g->vertices == NULL) {
197        return strongcomponents;
198    }
[1]199
[52]200    /* Make all vertices unseen and all arcs untagged */
201    for (v = g->vertices + g->n - 1; v >= g->vertices; v--) {
202        v->rank = 0;
203        v->untagged = v->arcs;
204    }
205    nn = 0;
206    active_stack = settled_stack = NULL;
[1]207
[52]208    for (vv = g->vertices; vv < g->vertices + g->n; vv++) {
209        if (vv->rank == 0) { /* vv is still unseen */
210            v = vv;
211            v->parent = NULL;
[1]212
[52]213            v->rank = ++nn;
214            v->link = active_stack;
215            active_stack = v;
216            v->min = v;
217
218            do { /* Eplore one step from the current vertex v, possibly moving to another vertex
219                           and calling it v */
220                register Vertex *u; /* a vertex adjacent to v */
221                register Arc *a = v->untagged; /* v's first remaining untagged arc, if any */
222                if (a) {
223                    u = a->tip;
224                    v->untagged = a->next; /* tag the arc from v to u */
225                    if (u->rank) { /* we've seen u already */
226                        if (u->rank < v->min->rank) { /* non-tree arc, jutt update v->min */
227                            v->min = u;
228                        }
229                    }
230                    else { /* u is presently unseen */
231                        u->parent = v; /* the arcfrom v to u is a new tree arc */
232                        v = u; /* u will now be the currnt vertex */
233                        v->rank = ++nn; /* make vertex v active */
234                        v->link = active_stack;
235                        active_stack = v;
236                        v->min = v;
237                    }
238                }
239                else { /* all arcs from v are tagged, so v matures */
240                    u = v->parent; /* prepare to backtrack in the tree */
241                    if (v->min == v) {
242                        /* Remove v and all its successors on the activestack from the tree,
243                           and mark them as a strong component of the graph */
244                        register Vertex * t; /* runs though the vertices of the new strong component */
245
246                        t = active_stack;
247                        active_stack = v->link;
248                        v->link = settled_stack;
249                        settled_stack = t; /* we've moved the top of one stack to the other */
250                        component = new void_list_t;
251                        /* singe vetex */
252                        if (t != v) { /* NOT singe vetex */
253                            while (t != v) {
254                                component->push_back(t->data);
255                                t->rank = infinity; /* now t is settled */
256                                t->parent = v; /* and v represents the new strong component */
257                                t = t->link;
258                            }
259                        }
260                        component->push_back(v->data);
261                        strongcomponents->push_back(component);
262                        v->rank = infinity; /* v too is settled */
263                        v->parent = v; /* and represents its own strong component */
264                    }
265                    else {
266                        /* the arc from u to v has just matured, making v->min visible from u */
267                        if (v->min->rank < u->min->rank) {
268                            u->min = v->min;
269                        }
270                    }
271                    v = u;/* the former parent of v is the new current vertex v */
272                }
273            } while (v != NULL);
274        }
275    }
276
277    return strongcomponents;
[1]278}
279
[52]280
281bool has_cycle(const strong_component_list_t & l) {
282    strong_component_list_t::const_iterator it;
283    for (it = l.begin(); it != l.end(); ++it) {
284        if ((*it)->size() > 1) {
285            return true;
286        }
287    }
288    return false;
[1]289}
290
[52]291
292/*
293# Local Variables:
294# tab-width: 4;
295# c-basic-offset: 4;
296# c-file-offsets:((innamespace . 0)(inline-open . 0));
297# indent-tabs-mode: nil;
298# End:
299#
300# vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
301*/
302
Note: See TracBrowser for help on using the repository browser.