source: sources/src/sc_port.cc @ 60

Last change on this file since 60 was 60, checked in by meunier, 8 years ago
  • Intégration des modifications de Clément, qui a intégré la version parallélisée de systemcass faite par Manuel.
File size: 9.7 KB
RevLine 
[1]1/*------------------------------------------------------------\
2|                                                             |
3| Tool    :                  systemcass                       |
4|                                                             |
5| File    :                   sc_port.cc                      |
6|                                                             |
7| Author  :                 Buchmann Richard                  |
8|                           Taktak Sami                       |
9|                                                             |
10| Date    :                   09_07_2004                      |
11|                                                             |
12\------------------------------------------------------------*/
13
14/*
15 * This file is part of the Disydent Project
16 * Copyright (C) Laboratoire LIP6 - Département ASIM
17 * Universite Pierre et Marie Curie
18 *
19 * Home page          : http://www-asim.lip6.fr/disydent
20 * E-mail             : mailto:richard.buchmann@lip6.fr
21 *
22 * This library is free software; you  can redistribute it and/or modify it
23 * under the terms  of the GNU Library General Public  License as published
24 * by the Free Software Foundation; either version 2 of the License, or (at
25 * your option) any later version.
26 *
27 * Disydent is distributed  in the hope  that it  will be
28 * useful, but WITHOUT  ANY WARRANTY; without even the  implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
30 * Public License for more details.
31 *
32 * You should have received a copy  of the GNU General Public License along
33 * with the GNU C Library; see the  file COPYING. If not, write to the Free
34 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 */
36
37
[27]38#include <iomanip>
39#include <map>
40#include <cassert>
[1]41
[27]42#include "sc_port.h"
43#include "sc_signal.h"
44#include "sc_module.h"
45#include "entity.h"
46#include "global_functions.h"
[1]47
[27]48#ifdef HAVE_CONFIG_H
49#include "config.h"
50#endif
51
[1]52extern "C" {
[52]53    extern char unstable;
54    char unstable = 0; // not in sc_core namespace because dynamic link support C linkage only
[60]55    int32 * pending_write_vector_nb = 0;
56    unsigned long long int total_assig = 0;
57#pragma omp threadprivate (pending_write_vector_nb, total_assig)
[1]58}
59
60using namespace std;
61
62namespace sc_core {
63
[52]64const char * const sc_port_base::kind_string = "sc_port";
65const char * const sc_signal_base::kind_string = "sc_signal";
[1]66
67unsigned int pending_write_vector_capacity = 512;
68pending_write_vector_t pending_write_vector = NULL;
[60]69#pragma omp threadprivate (pending_write_vector)
[1]70extern equi_list_t equi_list;
71
[59]72const char * get_module_name(const tab_t * pointer) {
73    const equi_t & eq = get_equi(pointer);
74    return get_module_name(eq);
[1]75}
76
77port2module_t port2module;
78
79// KIND STRING
80const char * const sc_inout_string = "sc_inout";
81const char * const sc_in_string    = "sc_in";
82const char * const sc_out_string   = "sc_out";
83
[52]84
[1]85// ----------------------------------------------------------------------------
86//  CLASS : sc_port_base
87//
88//                                               
89// ----------------------------------------------------------------------------
90
[52]91sc_port_base::sc_port_base() {
[59]92    init ();
[1]93}
94
[52]95
96sc_port_base::sc_port_base(const char * name_) : sc_object(name_) {
97    init ();
[1]98}
99
[52]100
101sc_port_base::sc_port_base(const sc_port_base & parent_) : sc_object (parent_.name ()) {
102    init ();
[1]103}
104
[52]105
106void sc_port_base::init() {
[27]107#ifdef CONFIG_DEBUG
[52]108    if (modules_stack.empty()) {
109        cerr << "Internal error : modules stack empty\n";
110        exit (9);
111    }
[1]112#endif
[52]113    const sc_module * last_module = sc_core::modules_stack.top();
114    port2module[this] = last_module;
115    set_kind(kind_string);
[1]116}
117
[52]118
119const sc_module & sc_port_base::get_module() const {
120    port2module_t::iterator i = port2module.find ((sc_port_base *) this);
121    if (i == port2module.end()) {
122        cerr << "Internal error : Modules contain ports. "
[1]123            "SystemCASS needs to identify the module that contains the following port : '" 
[52]124            << name()
125            << "'\n";
126        exit (17);
127    }
128    const sc_module * m = i->second;
129    return *m;
[1]130}
131
[52]132
[35]133static bool check_multiwriting2port_error_message = true;
[52]134
135void sc_port_base::check_multiwriting2port() const {
136    static std::map<sc_port_base *, double> s;
137    double t = sc_simulation_time();
138    if (t == 0) {
139        return;
140    }
141    sc_port_base * port = (sc_port_base *) this;
142    if ((s[port] == t) && (check_multiwriting2port_error_message)) {
143        check_multiwriting2port_error_message = 0;
144        if (use_port_dependency) {
145            std::cerr << "Error at cycle #" << t << " : "
146                "SystemCASS allows only 1 writing for each ports/signals.\n"
[1]147                << "Functions write several times into '" << name () << "'.\n";
[52]148        }
149        else {
150            std::cerr << "Error : "
151                "Multiwriting to port assertion works only "
152                "when SystemCASS uses port dependency information "
153                "(--p parameter).\n";
154        }
155        sc_core::sc_stop();
156        exit (31072006); // 6
[1]157    }
[52]158    else {
159        s[port] = t;
160    }
[1]161}
162
[52]163
164std::ostream & operator << (std::ostream & o, const sc_port_base & p) {
165    return o << p.name();
[1]166}
[52]167
168
[1]169// ----------------------------------------------------------------------------
170//  CLASS : sc_signal_base
171//
172//  The sc_signal<T> primitive channel class.
173// ----------------------------------------------------------------------------
[52]174void sc_signal_base::init() {
175    set_kind(kind_string);
176    bind(*this);
[1]177}
178
[52]179
[1]180sc_signal_base::sc_signal_base() { 
[52]181    init();
[1]182}
183
184
[52]185sc_signal_base::sc_signal_base(const char * name_) : sc_object(name_) { 
186    init ();
[1]187}
188
[52]189
190sc_signal_base::sc_signal_base(const char * name_, void *) : sc_object(name_) {
191    // this overload is only used for SC_BIND_PROXY_NIL constant.
192    // this signal should not be added to the signal list.
[1]193}
194
[52]195
196sc_signal_base::~sc_signal_base() {}
197
198
[1]199/*
200 * Signals copy
201 */
202
203#ifdef DUMP_SIGNAL_STATS
[52]204typedef map<tab_t *, long long int> counter_t;
205static counter_t counter;
[1]206long long int unnecessary = 0;
207long long int total_assig = 0;
208#endif
209
210} // end of sc_core namespace
211
[52]212
[1]213extern "C" {
[52]214
215    void update() {
[1]216#if defined(DUMP_STAGE)
[52]217            cerr << "Updating... ";
[1]218#endif
[52]219            // stl vectors are too slow
220            // memcopy is not better
[59]221            // signal table sorting doesn't give any better performance
[1]222#if defined(DUMP_STAGE)
[60]223            cerr << "(" << *pending_write_vector_nb
[52]224                << " internal pending writings) ";
[1]225#endif
[52]226            unsigned int i;
[60]227            for (i = 0; i < *pending_write_vector_nb; ++i) {
[1]228#define iter (sc_core::pending_write_vector[i])
[27]229#ifdef CONFIG_DEBUG
[52]230                if (iter.pointer == NULL) {
231                    cerr << "Internal error : trying to apply a posted write from an unassigned signal/port\n";
232                    exit (8);
233                }
[59]234#endif
[1]235#ifdef DUMP_SIGNAL_STATS
[52]236                if (*(iter.pointer) == iter.value) {
237                    unnecessary++;
238                }
239                counter[iter.pointer]++;
[1]240#endif
[59]241                *(iter.pointer) = iter.value;
[1]242#undef iter
[52]243            }
[1]244#ifdef DUMP_SIGNAL_STATS
[60]245            total_assig += *pending_write_vector_nb;
[1]246#endif
[60]247            total_assig += *pending_write_vector_nb;
248            *pending_write_vector_nb = 0;
[1]249
250#if defined(DUMP_STAGE)
[52]251            cerr << "done.\n";
[1]252#endif
[52]253        }
[1]254
255} // end of extern "C"
256
257namespace sc_core {
258
[52]259void print_registers_writing_stats (ostream & o) {
[1]260#ifdef DUMP_SIGNAL_STATS
[52]261    o << "signal index / name / usage (>1%)\n";
262    o << setprecision(2);
263    double t = sc_simulation_time();
264    if (t == 0) {
265        o << "Warning : simulation too short.\n";
266        t = 0.01;
267    }
268    if (total_assig == 0) {
269        return;
270    }
271    counter_t::iterator k;
272    for (k = counter.begin(); k != counter.end(); ++k) {
273        double usage = k->second / t * 100;
274        if (usage <= 1) {
275            continue;
276        }
277        o << k->first << "   " << get_name (k->first) << "   " << usage << "%\n";
278    }
279    typedef map<string, int> counter_module_t;
280    counter_module_t counter_by_module;
281    for (k = counter.begin(); k != counter.end(); ++k) {
282        string module_name = get_module_name (k->first);
[59]283        counter_by_module[module_name] += k->second;
[52]284    }
285    o << "module name / usage\n";
286    counter_module_t::iterator i;
287    for (i = counter_by_module.begin(); i != counter_by_module.end(); ++i) {
288        o << i->first << "   " << (i->second * 100 / total_assig) << "%\n";
289    }
290    cerr << "average of assignment number per cycle " << (total_assig / t) << "\n";
291    cerr << (unnecessary * 100 / total_assig) << "% of assignment are unecessary\n";
[1]292#else
[52]293    cerr << "Register usage not available.\n";
[1]294#endif
295}
296
[59]297
[52]298static bool is_bound(/*const*/ sc_port_base & port) {
299    const tab_t * pointer = port.get_pointer();
300    //assert(pointer != NULL);
301    if (pointer == NULL) {
302        return false; // case : sc_in not bound
303    }
[59]304    return has_equi(port);
[1]305}
306
[59]307
[52]308static void check_port(/*const*/ sc_port_base & port) {
[59]309    if (!is_bound(port)) {
[52]310        cerr << "Error : '" << port.name() << "' port"
[1]311            " (" << port.kind() << ")"
312            " is not bound.\n";
[52]313        exit (29);
314    }
[1]315}
316
[52]317
318void check_all_ports() {
319    if (dump_stage) {
320        cerr << "checking ports...";
321    }
322    port2module_t::/*const_*/iterator i;
323    for (i = port2module.begin(); i != port2module.end(); ++i) {
[59]324        /*const*/ sc_port_base * port = i->first;
[52]325        assert(port != NULL);
326        check_port(*port);
327    }
328    if (dump_stage) {
329        cerr << " done.";
330    }
[1]331}
332
[52]333
[1]334} // end of sc_core namespace
335
336
[52]337/*
338# Local Variables:
339# tab-width: 4;
340# c-basic-offset: 4;
341# c-file-offsets:((innamespace . 0)(inline-open . 0));
342# indent-tabs-mode: nil;
343# End:
344#
345# vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
346*/
347
Note: See TracBrowser for help on using the repository browser.