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

Subversion Repositories nocmodel

[/] [nocmodel/] [trunk/] [nocmodel/] [basicmodels/] [basic_noc_codegen.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
# Basic NoC Code generation model 
6
#  * VHDL code support
7
#
8
# Author:  Oscar Diaz
9
# Version: 0.2
10
# Date:    14-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
# 14-03-2011 : (OD) initial release
33
#
34
 
35
"""
36
* Basic NoC VHDL code generation model
37
"""
38
 
39
from nocmodel import *
40
from nocmodel.noc_codegen_base import *
41
from nocmodel.noc_codegen_vhdl import *
42
from intercon_model import *
43
 
44
from myhdl import intbv
45
 
46
class basic_noc_arch_vhdl(noc_codegen_ext):
47
    """
48
    Code generation extension for NoC objects in VHDL.
49
 
50
    This extension object generates the architecture needed to connect all
51
    objects into a top VHDL file.
52
    """
53
    def __init__(self, codegen_ref):
54
        noc_codegen_ext.__init__(self, codegen_ref)
55
        self.noc_ref = codegen_ref.nocobject_ref
56
        if not isinstance(self.noc_ref, noc):
57
            raise TypeError("Argument must be a 'noc_codegen_base' instance defined for a NoC object.")
58
 
59
        codegen_ref.modulename = self.noc_ref.name
60
 
61
        # NoC model: must generate all needed components and join them together
62
        # in this top module.
63
 
64
        # 1. convert some attributes to generics
65
        codegen_ref.add_generic("name", self.noc_ref.name, "NoC Name")
66
 
67
        # 2. define a basic port signals:
68
        codegen_ref.add_external_signal("rst_i", "in", intbv(0)[1:], "System reset in")
69
        codegen_ref.add_external_signal("clk_i", "in", intbv(0)[1:], "System clock in")
70
 
71
        # 2. keep a list of needed components
72
        hash_list = {}
73
 
74
        # 2. search for defined external_ports in codegen objects
75
        for obj in self.noc_ref.all_list(True):
76
            for sig in obj.codegen.external_signals:
77
                # make a copy of the signal dict, adding a reference to the 
78
                # nocobject which belongs
79
                csig = sig.copy()
80
                csig["back_ref"] = obj
81
                codegen_ref.external_signals.append(csig)
82
 
83
        # 3. Build implementation string
84
        codegen_ref.implementation += "-- Implementation for '%s' name '%s' generated by '%s'\n" % (repr(self.noc_ref), self.noc_ref.name, repr(self))
85
        # 3.1 add components
86
        # TODO: check the components name
87
        for obj in self.noc_ref.all_list():
88
            # add only for routers and ipcores (WARNING)
89
            if isinstance(obj, (router, ipcore)):
90
                if obj.codegen.interface_hash == "":
91
                    # update hash
92
                    obj.codegen.model_hash()
93
                # check if the component is already declared
94
                if hash(obj.codegen.interface_hash) in hash_list:
95
                    # already declared component
96
                    hash_list[hash(obj.codegen.interface_hash)]["instance_list"].append(obj)
97
                else:
98
                    # new component
99
                    codegen_ref.implementation += "\n-- Component for '%s' name '%s'\n" % (repr(obj), obj.name)
100
                    codegen_ref.implementation += obj.codegen.generate_component()
101
                    hash_list[hash(obj.codegen.interface_hash)] = {
102
                        "str_hash": obj.codegen.interface_hash,
103
                        "component_name": obj.codegen.modulename,
104
                        "instance_list": [obj]
105
                        }
106
 
107
        # 3.2 intermediate signals
108
        codegen_ref.implementation += "\n-- Intermediate signals\n\n"
109
        # signals here has the format: "sig_<obj.name>_<signal_name>"
110
        for obj in self.noc_ref.all_list():
111
            # add only for routers and ipcores (WARNING)
112
            if isinstance(obj, (router, ipcore)):
113
                for s in obj.codegen.generate_port_declaration(None, True):
114
                    if s[0:2] != "--":
115
                        # note that port declaration will put "in" or "out". Filter it
116
                        sf = s.replace(": in", ":").replace(": out", ":")
117
                        codegen_ref.implementation += "signal sig_%s_%s;\n" % (obj.name, sf)
118
                    else:
119
                        codegen_ref.implementation += "-- Object %s : %s\n" % (obj.name, s[2:])
120
 
121
        codegen_ref.implementation += "begin\n"
122
        codegen_ref.implementation += codegen_ref.add_tab("-- component instantiation\n\n")
123
 
124
        # 3.3 instances and port mapping
125
        # hash_list has the declared components and its related objects 
126
        for hcomp in hash_list.itervalues():
127
            for obj in hcomp["instance_list"]:
128
                codegen_ref.implementation += codegen_ref.add_tab("-- Instance for '%s' name '%s'\n" % (repr(obj), obj.name))
129
                codegen_ref.implementation += codegen_ref.add_tab("i_%s : %s" % (obj.name, hcomp["component_name"]))
130
                # generic map
131
                if len(obj.codegen.generics) > 0:
132
                    codegen_ref.implementation += " generic map (\n"
133
                    strl = []
134
                    for g in obj.codegen.generics:
135
                        strl.append("%s => %s" % (g["name"], convert_value(g["default_value"], g["type"])))
136
                    codegen_ref.implementation += ",\n".join(codegen_ref.add_tab(strl, 2))
137
                    codegen_ref.implementation += codegen_ref.add_tab("\n)")
138
                # port map
139
                if (len(obj.codegen.ports) + len(obj.codegen.external_signals)) > 0:
140
                    codegen_ref.implementation += " port map (\n"
141
                    strl = []
142
                    for p in obj.codegen.ports:
143
                        # search for each signal in a port
144
                        for sig in p["signal_list"]:
145
                            # format: <portname>_<signame> => sig_<obj.name>_<portname>_<signal_name>
146
                            strl.append("%s_%s => sig_%s_%s_%s" % (p["name"], sig["name"], obj.name, p["name"], sig["name"]))
147
                    # and then in external_signals
148
                    for sig in obj.codegen.external_signals:
149
                        # format: <signame> => <obj.name>_<signal_name>
150
                        strl.append("%s => %s_%s" % (sig["name"], obj.name, sig["name"]))
151
                    codegen_ref.implementation += ",\n".join(codegen_ref.add_tab(strl, 2))
152
                    codegen_ref.implementation += codegen_ref.add_tab("\n)")
153
                codegen_ref.implementation += ";\n\n"
154
 
155
        # 3.4 signal connections
156
        # connect routers first
157
        for obj in self.noc_ref.router_list():
158
            # go through all ports and check its use
159
            codegen_ref.implementation += codegen_ref.add_tab("-- Signal mapping for '%s' name '%s'\n" % (repr(obj), obj.name))
160
            for p in obj.codegen.ports:
161
                if p["type"] == "dualwb":
162
                    if p["nocport"] is None:
163
                        codegen_ref.implementation += codegen_ref.add_tab("--   port '%s' unused\n" % p["name"])
164
                        # Unused port. Go through all signals and put input 
165
                        # values tied to 0
166
                        for sig in p["signal_list"]:
167
                            if sig["direction"] == "in":
168
                                # format: sig_<obj.name>_<portname>_<signal_name>
169
                                codegen_ref.implementation += codegen_ref.add_tab("sig_%s_%s_%s <= %s;\n" % (obj.name, p["name"], sig["name"], convert_value(sig["default_value"], sig["type"])))
170
                    else:
171
                        # connected with a port. Assign only input signals.
172
                        peerobj = obj.ports[p["nocport"]]["peer"]
173
                        # search for peer object codegen ports
174
                        peerpname = None
175
                        for peerp in peerobj.codegen.ports:
176
                            if peerp["nocport"] is not None:
177
                                findobj = peerobj.ports[peerp["nocport"]]["peer"]
178
                                if findobj == obj:
179
                                    peerpname = peerp["name"]
180
                                    break
181
                        if peerpname is None:
182
                            raise ValueError("Connected object '%s'->'%s': port not found" % (obj.name, peerobj.name))
183
                        codegen_ref.implementation += codegen_ref.add_tab("--   port '%s' connected to object '%s' port '%s'\n" % (p["name"], peerobj.name, peerpname))
184
                        for sig in p["signal_list"]:
185
                            if sig["direction"] == "in":
186
                                peersig = obj.ports[p["nocport"]]["channel"].ports[obj.address]["intercon"].get_complement_signal(sig["name"])
187
                                if peersig is not None:
188
                                    # format: sig_<obj.name>_<portname>_<signal_name>
189
                                    codegen_ref.implementation += codegen_ref.add_tab("sig_%s_%s_%s <= sig_%s_%s_%s;\n" % (obj.name, p["name"], sig["name"], peerobj.name, peerpname, peersig))
190
                                else:
191
                                    codegen_ref.implementation += codegen_ref.add_tab("-- Special signal sig_%s_%s_%s not assigned yet.\n" % (obj.name, p["name"], sig["name"]))
192
 
193
        # then ipcores
194
        for obj in self.noc_ref.ipcore_list():
195
            codegen_ref.implementation += codegen_ref.add_tab("-- Signal mapping for '%s' name '%s'\n" % (repr(obj), obj.name))
196
            # connect signals from and to ipcore
197
            # get local and remote intercon
198
            obj_icon = obj.ports[obj.get_address()]["channel"].ports[None]["intercon"]
199
            dest_icon = obj.ports[obj.get_address()]["channel"].ports[obj.get_address()]["intercon"]
200
            obj_port = obj.codegen.ports[0]
201
            dest_port = None
202
            for p in obj.router_ref.codegen.ports:
203
                if p["type"] == dest_icon.intercon_type:
204
                    dest_port = p
205
            if dest_port is None:
206
                raise ValueError("Router object '%s': local port not found" % obj.router_ref.name)
207
            codegen_ref.implementation += codegen_ref.add_tab("--   port '%s' connected to object '%s' port '%s'\n" % (p["name"], obj.router_ref.name, dest_port["name"]))
208
            # first ipcore <= router
209
            for sig in obj_port["signal_list"]:
210
                if sig["direction"] == "in":
211
                    peersig = obj_icon.get_complement_signal(sig["name"])
212
                    if peersig is not None:
213
                        # format: sig_<obj.name>_<portname>_<signal_name>
214
                        codegen_ref.implementation += codegen_ref.add_tab("sig_%s_%s_%s <= sig_%s_%s_%s;\n" % (obj.name, obj_port["name"], sig["name"], obj.router_ref.name, dest_port["name"], peersig))
215
                    else:
216
                        # special port (TODO!)
217
                        codegen_ref.implementation += codegen_ref.add_tab("-- Special signal sig_%s_%s_%s not assigned yet.\n" % (obj.name, obj_port["name"], sig["name"]))
218
            # then router <= ipcore
219
            for sig in dest_port["signal_list"]:
220
                if sig["direction"] == "in":
221
                    peersig = dest_icon.get_complement_signal(sig["name"])
222
                    if peersig is not None:
223
                        # format: sig_<obj.name>_<portname>_<signal_name>
224
                        codegen_ref.implementation += codegen_ref.add_tab("sig_%s_%s_%s <= sig_%s_%s_%s;\n" % (obj.router_ref.name, dest_port["name"], sig["name"], obj.name, obj_port["name"], peersig))
225
                    else:
226
                        codegen_ref.implementation += codegen_ref.add_tab("-- Special signal sig_%s_%s_%s not assigned yet.\n" % (obj.router_ref.name, dest_port["name"], sig["name"]))
227
 
228
        codegen_ref.implementation += codegen_ref.add_tab("-- Implementation code for Noc --")
229
 

powered by: WebSVN 2.1.0

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