OpenCores
URL https://opencores.org/ocsvn/nocmodel/nocmodel/trunk

Subversion Repositories nocmodel

[/] [nocmodel/] [trunk/] [nocmodel/] [noc_tbm_base.py] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 dargor
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
 
4
#
5
# NoC TBM simulation support
6
#   This module declares classes for Transaction Based Model simulation
7
#
8
# Author:  Oscar Diaz
9
# Version: 0.2
10
# Date:    17-03-2011
11
 
12
#
13
# This code is free software; you can redistribute it and/or
14
# modify it under the terms of the GNU Lesser General Public
15
# License as published by the Free Software Foundation; either
16
# version 2.1 of the License, or (at your option) any later version.
17
#
18
# This code is distributed in the hope that it will be useful,
19
# but WITHOUT ANY WARRANTY; without even the implied warranty of
20
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21
# Lesser General Public License for more details.
22
#
23
# You should have received a copy of the GNU Lesser General Public
24
# License along with this library; if not, write to the
25
# Free Software  Foundation, Inc., 59 Temple Place, Suite 330,
26
# Boston, MA  02111-1307  USA
27
#
28
 
29
#
30
# Changelog:
31
#
32
# 03-03-2011 : (OD) initial release
33
#
34
 
35
"""
36
===============================
37
NoCmodel TBM simulation support
38
===============================
39
 
40
This module declares classes for Transaction Based Model simulation
41
 
42
* Class 'noc_tbm_base'
43
* Class 'noc_tbm_simulation'
44
* Class 'noc_tbm_errcodes'
45
"""
46
 
47
import networkx as nx
48
import myhdl
49
import logging
50
 
51
from noc_base import *
52
 
53
import inspect
54
 
55
class noc_tbm_base():
56
    """
57
    Base class for NoC TBM simulator.
58
 
59
    This class add methods to a NoC object, required for the TBM model. Each
60
    derived class must override the methods:
61
 
62
    * __init__() : its constructor contains the object TBM model (data
63
      structures, generators, etc).
64
    * send()
65
    * recv()
66
 
67
    Other methods are related to simulation configuration and logging support.
68
    """
69
    def __init__(self):
70
        self.log = logging.getLogger()
71
        self.logname = "BASECLASS"
72
        self.generators = []
73
        self.tracesend = []
74
        self.tracerecv = []
75
 
76
    def __repr__(self):
77
        if self.logname != "":
78
            return "<%s '%s'>" % (self.__class__.__name__, self.logname)
79
        else:
80
            return "<%s at '%d'>" % (self.__class__.__name__, id(self))
81
 
82
    def get_generators(self):
83
        return self.generators
84
 
85
    def _do_build_generators(self):
86
        self.generators.extend(self.build_generators())
87
 
88
    # TBM main: every object must define this functions
89
    def send(self, src, dest, data, addattrs=None):
90
        """
91
        SEND method: this method MUST be called only by the local
92
        object who wants to start a transaction.
93
 
94
        This function will call the recv method in the right object.
95
 
96
        Arguments:
97
        * src: source object (or router address) that call this method, i.e. the
98
          object that starts the transaction.
99
        * dest: destination object (or router address) that receive the data in
100
          the transaction. This method will call dest' recv method.
101
        * data: data to be sent. Can be anything, but normally is an object of
102
          type packet.
103
        * addattrs: optional dictionary with additional arguments
104
 
105
        Return: Must return a number: 0 for everything OK, != 0 to show an error
106
            relevant to the caller, an exception in case of attribute error
107
        """
108
        self.debug("-> send( %s , %s , %s , %s )" % (repr(src), repr(dest), repr(packet), repr(addattrs)))
109
        return noc_tbm_errcodes.not_implemented
110
 
111
    def recv(self, src, dest, data, addattrs=None):
112
        """
113
        RECV method: this method MUST be called only by the send
114
        method of the object who started the transaction.
115
 
116
        Arguments:
117
        * src: source object (or router address) that call this method, i.e. the
118
          object that starts the transaction.
119
        * dest: destination object (or router address) that receive the data in
120
          the transaction. This method will call dest' recv method.
121
        * data: data to be sent. Can be anything, but normally is an object of
122
          type packet.
123
        * addattrs: optional dictionary with additional arguments
124
 
125
        @return Must return a number: 0 for everything OK, != 0 to show an error
126
            relevant to the caller, an exception in case of attribute error
127
        """
128
        self.debug("-> recv( %s , %s , %s , %s )" % (repr(src), repr(dest), repr(packet), repr(addattrs)))
129
        return noc_tbm_errcodes.not_implemented
130
 
131
    # logging methods (only use 4 levels)
132
    def debug(self, msg, *args, **kwargs):
133
        self.log.debug(msg, extra={"objname": self.logname}, *args, **kwargs)
134
    def info(self, msg, *args, **kwargs):
135
        self.log.info(msg, extra={"objname": self.logname}, *args, **kwargs)
136
    def warning(self, msg, *args, **kwargs):
137
        self.log.warning(msg, extra={"objname": self.logname}, *args, **kwargs)
138
    def error(self, msg, *args, **kwargs):
139
        self.log.error(msg, extra={"objname": self.logname}, *args, **kwargs)
140
 
141
    # special log
142
    def debugstate(self):
143
        self.debug(" '%s' object state: " % repr(self))
144
        for i in dir(self):
145
            # exclude hidden attributes
146
            if i[0] == "_":
147
                continue
148
            self.debug("     ['%s'] = %s " % (i, repr(getattr(self, i))))
149
    def generators_info(self):
150
        self.debug(" Registered generators for '%s': " % repr(self))
151
        for g in self.generators:
152
            self.debug("     '%s': %s" % (getattr(g, "name", "-GEN-"), repr(g)))
153
 
154
class noc_tbm_simulation():
155
    """
156
    NoC TBM simulator object
157
 
158
    This class manages the MyHDL simulation on a NoC object and its logging
159
    support.
160
 
161
    Attributes:
162
    * noc_ref: reference to NoC model to simulate
163
    * log_file: optional file to save the simulation log
164
    * log_level: optional logging level for the previous file
165
    * kwargs: optional attributes to add to this object
166
    """
167
    def __init__(self, noc_ref, log_file=None, log_level=logging.INFO, **kwargs):
168
        if isinstance(noc_ref, noc):
169
            self.noc_ref = noc_ref
170
        else:
171
            raise TypeError("This class needs a noc object as constructor argument.")
172
        # configure logging system
173
        # log errors to console, custom log to log_file if specified
174
        addmsg = ""
175
        self.log = logging.getLogger()
176
        self.log.setLevel(log_level)
177
        console_hdl = logging.StreamHandler()
178
        console_hdl.setLevel(logging.WARNING)
179
        class SimTimeFilter(logging.Filter):
180
            def filter(self, record):
181
                record.myhdltime = myhdl.now()
182
                return True
183
        self.log.addFilter(SimTimeFilter())
184
        self.noc_formatter = logging.Formatter("%(myhdltime)4d:%(levelname)-5s:%(objname)-16s - %(message)s")
185
        console_hdl.setFormatter(self.noc_formatter)
186
        self.log.addHandler(console_hdl)
187
        if log_file != None:
188
            file_hdl = logging.FileHandler(log_file, 'w')
189
            file_hdl.setLevel(log_level)
190
            file_hdl.setFormatter(self.noc_formatter)
191
            self.log.addHandler(file_hdl)
192
            addmsg = "and on file (%s) level %s" % (log_file, logging._levelNames[log_level])
193
        # ready to roll
194
        self.debug("Logging enabled! Running log on console level WARNING %s" % addmsg)
195
 
196
    def configure_simulation(self, max_time=None, add_generators=[]):
197
        """
198
        Configure MyHDL simulation.
199
 
200
        Arguments:
201
        * max_time: optional max time to simulate. None means simulation
202
          without time limit.
203
        * add_generators: external MyHDL generators to add to the simulation
204
        """
205
        # myhdl simulation: extract all generators and prepare 
206
        # arguments
207
        for obj in self.noc_ref.all_list():
208
            prevcount = len(add_generators)
209
            add_generators.extend(obj.tbm.get_generators())
210
            #self.debug("configure_simulation: adding %d generators from object %s" % (len(add_generators)-prevcount, repr(obj)))
211
            if isinstance(obj, ipcore):
212
                add_generators.extend(obj.channel_ref.tbm.get_generators())
213
                #self.debug("configure_simulation: plus ipcore channel: adding %d generators from object %s" % (len(add_generators)-prevcount, repr(obj.channel_ref)))
214
        # --------------------------------
215
        # debug info
216
        # TODO: try to get info about generators, particularly obtain origin 
217
        # info about @always and @always_comb generators
218
        #self.debug("configure_simulation: list of generators: (count = %d)" % len(add_generators))
219
        #for genl in add_generators:
220
            #if not isinstance(genl, list):
221
                #gen2 = [genl]
222
            #else:
223
                #gen2 = genl
224
                #self.debug("configure_simulation:   generator list '%s'" % repr(genl))
225
            #for gen in gen2:
226
                #self.debug("configure_simulation:   generator '%s'" % repr(gen))
227
                #try:
228
                    #self.debug("configure_simulation:   inspect info name '%s'" % gen.gen.__name__)
229
                    #self.debug("configure_simulation:   inspect info locals '%s'" % repr(gen.gen.gi_frame.f_locals.keys()))
230
                    #for k, v in gen.gen.gi_frame.f_locals.iteritems():
231
                        #self.debug("configure_simulation:   inspect info locals[%s] '%s'" % (k, repr(v)))
232
                    #if gen.gen.__name__ == "genfunc":
233
                        #self.debug("configure_simulation:   inspect info deep name '%s'" % gen.func.__name__)
234
                #except:
235
                    #pass
236
        # --------------------------------
237
        self.sim_object = myhdl.Simulation(*add_generators)
238
        self.sim_duration = max_time
239
        self.debug("configure_simulation: will run until simulation time '%d'" % max_time)
240
 
241
    def run(self):
242
        """
243
        Run MyHDL simulation
244
        """
245
        self.debug("Start simulation")
246
        self.sim_object.run(self.sim_duration)
247
        self.debug("End simulation")
248
 
249
    # custom logging methods (only use 4 levels)
250
    def debug(self, msg, *args, **kwargs):
251
        self.log.debug(msg, extra={"objname": "TopNoC"}, *args, **kwargs)
252
    def info(self, msg, *args, **kwargs):
253
        self.log.info(msg, extra={"objname": "TopNoC"}, *args, **kwargs)
254
    def warning(self, msg, *args, **kwargs):
255
        self.log.warning(msg, extra={"objname": "TopNoC"}, *args, **kwargs)
256
    def error(self, msg, *args, **kwargs):
257
        self.log.error(msg, extra={"objname": "TopNoC"}, *args, **kwargs)
258
 
259
    # special log filter: log individually by object name
260
    def configure_byobject_logging(self, basefilename="", log_level=logging.INFO):
261
        """
262
        Special log filter: log individually by object name
263
 
264
        Arguments:
265
        * basefilename: generated filenames will start with this string
266
        * log_level: optional logging level for previous files
267
        """
268
        # base filter
269
        class ObjFilter(logging.Filter):
270
            def __init__(self, basename):
271
                self.basename = basename
272
            def filter(self, record):
273
                if record.objname == self.basename:
274
                    return True
275
                return False
276
        # need a handler for each object
277
        for obj in self.noc_ref.all_list():
278
            newfilter = ObjFilter(obj.tbm.logname)
279
            newhandler = logging.FileHandler("%s_%s.log" % (basefilename, obj.tbm.logname), "w")
280
            newhandler.setLevel(log_level)
281
            newhandler.addFilter(newfilter)
282
            newhandler.setFormatter(self.noc_formatter)
283
            self.log.addHandler(newhandler)
284
        # Transactions logger
285
        class TransFilter(logging.Filter):
286
            def filter(self, record):
287
                if record.message.find("->") == 0:
288
                    return True
289
                return False
290
        newhandler = logging.FileHandler("%s_transactions.log" % basefilename, "w")
291
        newhandler.setLevel(log_level)
292
        newhandler.addFilter(TransFilter())
293
        newhandler.setFormatter(self.noc_formatter)
294
        self.log.addHandler(newhandler)
295
        # TopNoC will not be added to this set
296
        self.debug("Special logging enabled. basefilename=%s level %s" % (basefilename, logging._levelNames[log_level]))
297
 
298
class noc_tbm_errcodes():
299
    """
300
    Common error codes definition
301
    """
302
    no_error = 0
303
    full_fifo = -1
304
    packet_bad_data = -2
305
    tbm_badcall_recv = -3
306
    tbm_badcall_send = -4
307
    tbm_busy_channel = -5
308
    not_implemented = -15

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.