source: sources/src/graph_cass.cc @ 53

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

Code formatting in all source files.

File size: 9.9 KB
Line 
1/*------------------------------------------------------------\
2  |                                                             |
3  | Tool    :                  systemcass                       |
4  |                                                             |
5  | File    :                 graph_cass.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_cass.cc,v $
40 * Revision 1.5  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.4  2005/09/14 14:08:24  buchmann
57 * Add Werror flag to compile the debug library.
58 * Split sc_clock implementation from sc_port to sc_clock.
59 * Add a helper message to write mealy functions avoiding combinational cycle.
60 *
61 * Bug fix :
62 * - cvs rules is no longer circular
63 * - bit2string
64 * - port binding (sc_in to sc_out)
65 * - error message from FSM rules checker
66 * - sc_time copy operator
67 *
68 * Code cleaning :
69 * - remove duplicated code (entity.cc and sc_port.cc)
70 * - remove duplicated declarations (internal_ext.h and internal.h)
71 *
72 * Revision 1.3  2005/06/22 09:15:03  buchmann
73 * Add some *_ext.h files to split internal implementation from API interface.
74 *
75 * Add -Wunused to detect unused functions.
76 *
77 * Include directory now contains API interface file only.
78 *
79 * Declar all the implementation/interface inside sc_core namespace as LRM 2.1
80 * advices.
81 *
82 * Remove casc namespace.
83 *
84 * Clean up dead code segments.
85 *
86 * Add hexadecimal dumping support.
87 *
88 * Add empty implementation of functions for object hierarchy traversal. (LRM 2.1)
89 *
90 * Bug fixes :
91 * - reference return of the following functions : operators =, |=, &= and so on.
92 * - range functions now return an sc_int_subref instead of an int.
93 *
94 * Revision 1.2  2005/05/30 12:33:50  buchmann
95 * Makefile :
96 * - use ${...} form instead of $(...) one.
97 * - add entity file object and entity, sc_signal headers.
98 *
99 * Split sc_signal(s)/sc_port(s) into two separate files.
100 * Add some codes to check hex2string function.
101 * Add some informations about -rdynamic when there is an error using dlopen.
102 * Add some ASSERT(s) for debug library.
103 * Add module name into the warning printing.
104 * Minor changes for PAT traces.
105 *
106 * Revision 1.1  2004/09/27 14:40:13  buchmann
107 * bug fix :
108 * - allow the use of user-defined structs in sc_signal/sc_in/sc_out/sc_inout
109* - use sc_dt namespace like official SystemC engine
110*
111* add :
112* - dump the signal/port/module dependancy graph in dot format
113*
114* Graph library is now splitted from the SystemCASS specific code.
115*
116*/
117
118#include <iostream>
119#include <fstream>
120#include <cstdio>
121#include <cstring>
122#include <map>
123#include <string>
124
125#include "graph_cass.h"
126#include "sc_sensitive.h"
127#include "sc_module.h"
128#include "sc_port.h"
129#include "entity.h"
130#include "simplify_string.h" // simplify_string
131#include "sc_ver_ext.h" // sc_version for dumping to DOT
132#ifdef HAVE_CONFIG_H
133#include "config.h"
134#endif
135
136using namespace std;
137
138namespace sc_core {
139
140std::map < const method_process_t *, Vertex * >m_v;
141
142/* Ajoute un arc */
143void add_arcs(const method_process_t & mp, const sc_module & module) {
144    std::map < const method_process_t *, Vertex * >::iterator i;
145    for (i = m_v.begin(); i != m_v.end(); ++i) {
146        if (i->first->module == &module)
147            new_arc(m_v[&mp], i->second);
148    }
149}
150
151
152/* Ajoute un arc */
153void add_arcs(const method_process_t & mp, tab_t * signal_pointer) {
154    equi_t & e = get_equi(signal_pointer);
155    equi_t::iterator i;
156    for (i = e.begin(); i != e.end(); ++i) {
157        const char * kind = i->kind();
158        if (strstr(kind, "out")) {
159            const sc_port_base & port = *(i->port);
160            const sc_module & module = port.get_module();
161            if (&module == mp.module) {
162                continue;
163            }
164            add_arcs(mp, module);
165            break;
166        }
167    }
168}
169
170
171void add_arcs(const method_process_t & mp) {
172    sensitivity_list_t::const_iterator port_bound;
173    for (port_bound = mp.sensitivity_list.begin();
174            port_bound != mp.sensitivity_list.end(); ++port_bound) {
175        // pour tous les ports/signaux p associés à la fonction au couple m
176        /* si pp est un port de sortie d'une autre fonction de mealy,
177           crée un arc entre m et mm */
178        /* on ne peut pas savoir si un port est la sortie d'une fonction de mealy.
179           on va donc chercher à savoir si c'est un port de sortie d'un automate de moore,
180           sinon on considère que c'est une sortie de mealy.
181           */
182        add_arcs(mp, port_bound->get_interface().get_pointer());
183    }
184}
185
186
187/* Construit le graph de dépendance des signaux de Mealy */
188/* lm est la liste des fonctions de Mealy */
189/* -----
190   Graph
191   -----
192   node = module
193   edge = dependency
194
195   Vertex is an array of (method_process_t*)
196   Edge is a couple Vertex->Vertex.
197   */
198extern Graph * makegraph(const method_process_list_t * lm) {
199    method_process_list_t::const_iterator mp;
200
201    int n = 0; /* Number of vertices */
202    Graph * g;
203    Vertex * v;
204
205    /* Compute the number of vertices in the graph:
206     * The vertices set is the method set. */
207
208    /*  for (m = lm->begin(); m != lm->end(); m++)
209        n++;*/
210    n = lm->size();
211
212    /* Create the graph */
213    g = gb_new_graph(n);
214
215    /* Associate the netlist elements to the graph vertices, and vice-versa */
216    v = g->vertices;
217
218    /* initialisation des vertices */
219    for (mp = lm->begin(); mp != lm->end(); ++mp) {
220        v->data = *mp;
221        m_v[*mp] = v++;
222    }
223
224    for (mp = lm->begin(); mp != lm->end(); ++mp) {
225        // pour tous couples m, instance module/function de la liste lm
226        add_arcs(**mp);
227    }
228
229    return g;
230}
231
232
233static string & get_method_process_fullname(string & name, const method_process_t & mp) {
234    sc_module * module = mp.module;
235    name = module->name();
236    name += "_";
237    name += mp.name;
238    return name;
239}
240
241
242static bool dot_write(ofstream & o, const Graph & g) {
243    string name1, name2, s;
244    // Printing into dot file
245    for (int i = 0; i < g.n; ++i) { // Printing node list
246        Vertex * v = g.vertices + i;
247        method_process_t *mp = (method_process_t *) (v->data);
248        get_method_process_fullname(name1, *mp);
249        const char * pname1 = name1.c_str();
250        o << "node [name=";
251        o.width(35);
252        o << simplify_name(pname1, s);
253        o << "];\n";
254    }
255    for (int i = 0; i < g.n; ++i) { // Printing edge list
256        Vertex * v1 = g.vertices + i;
257        method_process_t *mp1 = (method_process_t *) (v1->data);
258        get_method_process_fullname(name1, *mp1);
259        const char * pname1 = name1.c_str();
260        for (Arc * a = v1->arcs; a != NULL; a = a->next) {
261            Vertex *v2 = a->tip;
262            method_process_t * mp2 = (method_process_t *) (v2->data);
263            get_method_process_fullname(name2, *mp2);
264            const char * pname2 = name2.c_str();
265            o.width(35);
266            o << simplify_name(pname2, s);
267            o << " -> ";
268            o.width(35);
269            o << simplify_name(pname1, s);
270            o << ";\n";
271        }
272    }
273    return true;
274}
275
276extern bool graph2dot(const char * name, const Graph & g) {
277    if (!name) {
278        return false;
279    }
280    string filename;
281    filename = name;
282    filename += ".dot";
283    ofstream o;
284    o.open(filename.c_str(), ios::out | ios::trunc);
285    if (o.is_open() == false) {
286        return false;
287    }
288    o << "// Module dependency graph\n// Generated by " << sc_version() << "\n";
289    o << "strict digraph " << name << " {\n";
290    o << "node [shape=box];\n";
291    //       "concentrate=true;\n";
292    o << left;
293    dot_write(o, g);
294    // Closing dot file
295    o << "}\n";
296    o.close();
297    if (dump_stage) {
298        cerr << "Module dependency graph written into '" << filename << "'.\n";
299    }
300    return true;
301}
302
303} // end of sc_core namespace
304
305/*
306# Local Variables:
307# tab-width: 4;
308# c-basic-offset: 4;
309# c-file-offsets:((innamespace . 0)(inline-open . 0));
310# indent-tabs-mode: nil;
311# End:
312#
313# vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
314*/
315
Note: See TracBrowser for help on using the repository browser.