/*------------------------------------------------------------\ | | | 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()) { 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()) { 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 (dump_stage) { cerr << "'" << get_name (*(s.destination)) << "'" << " depends on '" << get_name (*(s.source)) << "'" << " in the module '" << s.method->module->name() << "'\n"; } 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 /* # Local Variables: # tab-width: 4; # c-basic-offset: 4; # c-file-offsets:((innamespace . 0)(inline-open . 0)); # indent-tabs-mode: nil; # End: # # vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 */