1 |
2 |
dargor |
#!/usr/bin/env python
|
2 |
|
|
# -*- coding: utf-8 -*-
|
3 |
|
|
|
4 |
|
|
#
|
5 |
|
|
# Basic IPcore model
|
6 |
|
|
# * TLM model
|
7 |
|
|
#
|
8 |
|
|
# Author: Oscar Diaz
|
9 |
|
|
# Version: 0.1
|
10 |
|
|
# Date: 03-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 |
|
|
Basic ipcore TLM model
|
37 |
|
|
"""
|
38 |
|
|
|
39 |
|
|
from nocmodel.noc_tlm_base import *
|
40 |
|
|
|
41 |
|
|
# ---------------------------
|
42 |
|
|
# Basic IPCore TLM model
|
43 |
|
|
|
44 |
|
|
class basic_ipcore_tlm(noc_tlm_base):
|
45 |
|
|
"""
|
46 |
|
|
TLM model of a NoC ipcore. Its based on sending and receiving packets
|
47 |
|
|
to a custom-based MyHDL generators. This class does not define any
|
48 |
|
|
functionality.
|
49 |
|
|
|
50 |
|
|
Attributes:
|
51 |
|
|
* ipcore_ref: reference to ipcore base object
|
52 |
|
|
|
53 |
|
|
Notes:
|
54 |
|
|
* This model is completely behavioral.
|
55 |
|
|
* See code comments to better understanding.
|
56 |
|
|
"""
|
57 |
|
|
def __init__(self, ipcore_ref):
|
58 |
|
|
noc_tlm_base.__init__(self)
|
59 |
|
|
if isinstance(ipcore_ref, ipcore):
|
60 |
|
|
self.ipcore_ref = ipcore_ref
|
61 |
|
|
self.graph_ref = ipcore_ref.graph_ref
|
62 |
|
|
self.logname = "IPCore '%s'" % ipcore_ref.name
|
63 |
|
|
if ipcore_ref.name == "":
|
64 |
|
|
self.logname = "IPCore '%s'" % ipcore_ref.router_ref.name
|
65 |
|
|
else:
|
66 |
|
|
raise TypeError("This class needs a ipcore object as constructor argument.")
|
67 |
|
|
|
68 |
|
|
self.debug("constructor")
|
69 |
|
|
# generic parameters
|
70 |
|
|
|
71 |
|
|
# one-port support: get a reference to the related channel
|
72 |
|
|
self.localch = self.ipcore_ref.channel_ref
|
73 |
|
|
|
74 |
|
|
# get protocol reference
|
75 |
|
|
self.protocol_ref = self.ipcore_ref.get_protocol_ref()
|
76 |
|
|
|
77 |
|
|
# bidirectional port: the sender part will write data to the signal
|
78 |
|
|
# outgoing_packet. This class provides a generator thar call send()
|
79 |
|
|
# method when there is new data.
|
80 |
|
|
# for receiving data, recv() method will write
|
81 |
|
|
# to the signal incoming_packet, and the ipcore must provide a generator
|
82 |
|
|
# sensible to that signal. Use the method register_generator()
|
83 |
|
|
self.incoming_packet = myhdl.Signal(packet())
|
84 |
|
|
self.outgoing_packet = myhdl.Signal(packet())
|
85 |
|
|
|
86 |
|
|
@myhdl.instance
|
87 |
|
|
def outgoing_process():
|
88 |
|
|
while True:
|
89 |
|
|
yield self.outgoing_packet
|
90 |
|
|
retval = self.send(self.ipcore_ref, self.localch, self.outgoing_packet.val)
|
91 |
|
|
|
92 |
|
|
self.generators = [outgoing_process]
|
93 |
|
|
self.debugstate()
|
94 |
|
|
|
95 |
|
|
def register_generator(self, genfunction, **kwargs):
|
96 |
|
|
"""
|
97 |
|
|
Register a new generator for this ipcore.
|
98 |
|
|
|
99 |
|
|
Arguments:
|
100 |
|
|
* genfunction: function that returns a MyHDL generator
|
101 |
|
|
* kwargs: optional keyed arguments to pass to genfunction call
|
102 |
|
|
|
103 |
|
|
Notes:
|
104 |
|
|
* This method requires that genfunction has the following prototype:
|
105 |
|
|
* my_function(din, dout, tlm_ref, <other_arguments>)
|
106 |
|
|
* din is a MyHDL Signal of type packet, and is the input signal
|
107 |
|
|
to the ipcore. Use this signal to react to input events and
|
108 |
|
|
receive input packets.
|
109 |
|
|
* dout is a MyHDL Signal of type packet, and is the output
|
110 |
|
|
signal to the ipcore. Use this signal to send out packets to
|
111 |
|
|
local channel (and then insert into the NoC).
|
112 |
|
|
* tlm_ref is a reference to this object. Normal use is to access
|
113 |
|
|
logging methods (e.g. tlm_ref.info("message") ).
|
114 |
|
|
* <other_arguments> may be defined, this method use kwargs
|
115 |
|
|
argument to pass them.
|
116 |
|
|
"""
|
117 |
|
|
makegen = genfunction(din=self.incoming_packet, dout=self.outgoing_packet, tlm_ref=self, **kwargs)
|
118 |
|
|
self.debug("register_generator( %s ) generator is %s args %s" % (repr(genfunction), repr(makegen), repr(kwargs)))
|
119 |
|
|
self.generators.append(makegen)
|
120 |
|
|
|
121 |
|
|
# Transaction - related methods
|
122 |
|
|
def send(self, src, dest, packet, addattrs=None):
|
123 |
|
|
"""
|
124 |
|
|
Assumptions:
|
125 |
|
|
* Safely ignore src and dest arguments, because this method
|
126 |
|
|
is called only by this object generators, therefore it always send
|
127 |
|
|
packets to the ipcore related channel.
|
128 |
|
|
* In theory src should be self.ipcore_ref, and dest should be
|
129 |
|
|
self.localch . This may be checked for errors.
|
130 |
|
|
"""
|
131 |
|
|
self.debug("-> send( %s , %s , %s , %s )" % (repr(src), repr(dest), repr(packet), repr(addattrs)))
|
132 |
|
|
|
133 |
|
|
# call recv on the local channel object
|
134 |
|
|
retval = self.localch.tlm.recv(self.ipcore_ref, self.localch, packet, addattrs)
|
135 |
|
|
|
136 |
|
|
# something to do with the retval? Only report it.
|
137 |
|
|
self.debug("-> send returns code '%s'" % repr(retval))
|
138 |
|
|
return retval
|
139 |
|
|
|
140 |
|
|
def recv(self, src, dest, packet, addattrs=None):
|
141 |
|
|
"""
|
142 |
|
|
Assumptions:
|
143 |
|
|
* Safely ignore src and dest arguments, because this method
|
144 |
|
|
is called only by local channel object.
|
145 |
|
|
* In theory src should be self.localch, and dest should be
|
146 |
|
|
self.ipcore_ref . This may be checked for errors.
|
147 |
|
|
"""
|
148 |
|
|
self.debug("-> recv( %s , %s , %s , %s )" % (repr(src), repr(dest), repr(packet), repr(addattrs)))
|
149 |
|
|
|
150 |
|
|
# update signal
|
151 |
|
|
self.incoming_packet.next = packet
|
152 |
|
|
|
153 |
|
|
self.debug("-> recv returns 'noc_tlm_errcodes.no_error'")
|
154 |
|
|
return noc_tlm_errcodes.no_error
|