/*------------------------------------------------------------\ | | | Tool : systemcass | | | | File : port_dependency.cc | | | | Author : Buchmann Richard | | | | Date : 21_09_2004 | | | \------------------------------------------------------------*/ /* * This file is part of the Disydent Project * Copyright (C) Laboratoire LIP6 - Département ASIM * Universite Pierre et Marie Curie * * Home page : http://www-asim.lip6.fr/disydent * E-mail : mailto:richard.buchmann@lip6.fr * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published * by the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * Disydent is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. * * You should have received a copy of the GNU General Public License along * with the GNU C Library; see the file COPYING. If not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "signal_dependency.h" #include "simplify_string.h" #include "sc_fwd.h" #include "sc_port.h" #include "sc_module.h" #include "sc_ver_ext.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif using namespace std; namespace sc_core { bool SignalDependency::operator < (const SignalDependency &b) const { if (source < b.source) return true; if (destination < b.destination) return true; return false; } static void txt_write (ofstream &o, const component_list_t &l) { component_list_t::const_iterator it; for (it = l.begin (); it != l.end (); ++it) { o << get_name(*((equi_t*)(*it))) << " "; } } static void txt_write (ofstream &o, const strong_component_list_t &l) { strong_component_list_t::const_iterator it; for (it = l.begin (); it != l.end (); ++it) { txt_write (o,**it); o << "\n"; } } bool SignalDependencyOrder2txt (const char *name, const strong_component_list_t&l) { if (!name) return false; string filename; filename = name; filename += ".txt"; ofstream o; o.open (filename.c_str(),ios::out | ios::trunc); if (o.is_open () == false) return false; txt_write (o,l); o.close (); return true; } static void dot_write (ofstream &o, const SignalDependencyGraph &g) { string s; SignalDependencyGraph::const_iterator it; for (it = g.begin (); it != g.end (); ++it) { string name; name = it->method->module->name(); name += "_"; name += it->method->name; o << "edge [label=" << simplify_name(name.c_str(),s) << "];\n"; const equi_t *equi = it->source; name = get_name (*equi); o << simplify_name(name.c_str(),s); o << " -> "; equi = it->destination; name = get_name (*equi); o << simplify_name(name.c_str(),s); o << ";\n"; } } bool SignalDependencyGraph2dot (const char *name, const SignalDependencyGraph& g) { if (!name) return false; string filename; filename = name; filename += ".dot"; ofstream o; o.open (filename.c_str(),ios::out | ios::trunc); if (o.is_open () == false) return false; o << "// Signal dependency graph\n" "// Generated by " << sc_version () << "\n"; o << "strict digraph " << name << " {\n"; dot_write (o,g); o << "}\n"; o.close (); if (dump_stage) cerr << "Signal Dependency Graph written into '" << filename << "'.\n"; return true; } SignalDependencyGraph* MakeSignalDependencyGraph (const PortDependencyGraph& g) { if (dump_stage) cerr << "Making signal dependency graph...\n"; SignalDependencyGraph *sig_g = new SignalDependencyGraph (); PortDependencyGraph::const_iterator it; for (it = g.begin(); it != g.end(); ++it) { SignalDependency s; s.method = it->method; const sc_interface *inter; inter = it->source; if (inter) s.source = &(get_equi (*inter)); else continue; inter = it->destination; s.destination = &(get_equi (*inter)); sig_g->insert(s); } return sig_g; } static bool is_in (const equi_t &e, const method_process_t &m) { const tab_t *pt = e.begin ()->interface->get_pointer (); const sensitivity_list_t &sens = m.sensitivity_list; sensitivity_list_t::const_iterator it; for (it = sens.begin (); it != sens.end (); ++it) { const sc_event &event = *it; if (pt == event.get_interface().get_pointer ()) return true; } return false; } static bool is_valid (const SignalDependency &s) { #if 0 cerr << "'" << get_name (*(s.destination)) << "'" << " depends on '" << get_name (*(s.source)) << "'" << " in the module '" << s.method->module->name() << "'\n"; return true; #endif if (is_in (*(s.source), *(s.method))) return true; const char *src = get_name (*(s.source)); cerr << "'" << get_name (*(s.destination)) << "'" << " depends on '" << src << "'" << " in the module '" << s.method->module->name() << "'" << " but '" << src << "' is not in the sensitivity_list.\n"; return false; } bool Check (const SignalDependencyGraph &g) { SignalDependencyGraph::const_iterator it; for (it = g.begin(); it != g.end(); ++it) { const SignalDependency &s = (*it); if (!is_valid (s)) return false; } return true; } static bool is_in (const equi_t &e, const SignalDependencyGraph &g) { SignalDependencyGraph::const_iterator it; for (it = g.begin (); it != g.end (); ++it) { const SignalDependency &s = *it; if (&e == s.source) return true; } return false; } static bool is_in (const sensitivity_list_t &sens, const SignalDependencyGraph &g) { sensitivity_list_t::const_iterator it; for (it = sens.begin (); it != sens.end (); ++it) { const sc_event &event = *it; const sc_interface &i = event.get_interface(); const equi_t &equi = get_equi (i); if (is_clock (i)) continue; if (!is_in (equi, g)) { cerr << "'" << get_name(equi) << "'" << " is in the sensitivity list of "; return false; } } return true; } bool Check (const method_process_list_t &ml, const SignalDependencyGraph &g) { method_process_list_t::const_iterator it; for (it = ml.begin(); it != ml.end(); ++it) { const method_process_t &m = *(*it); const sensitivity_list_t &sens = m.sensitivity_list; if (!is_in (sens, g)) { cerr << "'" << m.module->name() << "' module instance " << "but any output port doesn't depend on this input.\n"; return false; } } return true; } } // end of sc_core namespace