URL
https://opencores.org/ocsvn/nocmodel/nocmodel/trunk
Subversion Repositories nocmodel
[/] [nocmodel/] [trunk/] [nocmodel/] [basicmodels/] [basic_noc_codegen.py] - Rev 4
Compare with Previous | Blame | View Log
#!/usr/bin/env python # -*- coding: utf-8 -*- # # Basic NoC Code generation model # * VHDL code support # # Author: Oscar Diaz # Version: 0.2 # Date: 14-03-2011 # # This code is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This code 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 # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place, Suite 330, # Boston, MA 02111-1307 USA # # # Changelog: # # 14-03-2011 : (OD) initial release # """ * Basic NoC VHDL code generation model """ from nocmodel import * from nocmodel.noc_codegen_base import * from nocmodel.noc_codegen_vhdl import * from intercon_model import * from myhdl import intbv class basic_noc_arch_vhdl(noc_codegen_ext): """ Code generation extension for NoC objects in VHDL. This extension object generates the architecture needed to connect all objects into a top VHDL file. """ def __init__(self, codegen_ref): noc_codegen_ext.__init__(self, codegen_ref) self.noc_ref = codegen_ref.nocobject_ref if not isinstance(self.noc_ref, noc): raise TypeError("Argument must be a 'noc_codegen_base' instance defined for a NoC object.") codegen_ref.modulename = self.noc_ref.name # NoC model: must generate all needed components and join them together # in this top module. # 1. convert some attributes to generics codegen_ref.add_generic("name", self.noc_ref.name, "NoC Name") # 2. define a basic port signals: codegen_ref.add_external_signal("rst_i", "in", intbv(0)[1:], "System reset in") codegen_ref.add_external_signal("clk_i", "in", intbv(0)[1:], "System clock in") # 2. keep a list of needed components hash_list = {} # 2. search for defined external_ports in codegen objects for obj in self.noc_ref.all_list(True): for sig in obj.codegen.external_signals: # make a copy of the signal dict, adding a reference to the # nocobject which belongs csig = sig.copy() csig["back_ref"] = obj codegen_ref.external_signals.append(csig) # 3. Build implementation string codegen_ref.implementation += "-- Implementation for '%s' name '%s' generated by '%s'\n" % (repr(self.noc_ref), self.noc_ref.name, repr(self)) # 3.1 add components # TODO: check the components name for obj in self.noc_ref.all_list(): # add only for routers and ipcores (WARNING) if isinstance(obj, (router, ipcore)): if obj.codegen.interface_hash == "": # update hash obj.codegen.model_hash() # check if the component is already declared if hash(obj.codegen.interface_hash) in hash_list: # already declared component hash_list[hash(obj.codegen.interface_hash)]["instance_list"].append(obj) else: # new component codegen_ref.implementation += "\n-- Component for '%s' name '%s'\n" % (repr(obj), obj.name) codegen_ref.implementation += obj.codegen.generate_component() hash_list[hash(obj.codegen.interface_hash)] = { "str_hash": obj.codegen.interface_hash, "component_name": obj.codegen.modulename, "instance_list": [obj] } # 3.2 intermediate signals codegen_ref.implementation += "\n-- Intermediate signals\n\n" # signals here has the format: "sig_<obj.name>_<signal_name>" for obj in self.noc_ref.all_list(): # add only for routers and ipcores (WARNING) if isinstance(obj, (router, ipcore)): for s in obj.codegen.generate_port_declaration(None, True): if s[0:2] != "--": # note that port declaration will put "in" or "out". Filter it sf = s.replace(": in", ":").replace(": out", ":") codegen_ref.implementation += "signal sig_%s_%s;\n" % (obj.name, sf) else: codegen_ref.implementation += "-- Object %s : %s\n" % (obj.name, s[2:]) codegen_ref.implementation += "begin\n" codegen_ref.implementation += codegen_ref.add_tab("-- component instantiation\n\n") # 3.3 instances and port mapping # hash_list has the declared components and its related objects for hcomp in hash_list.itervalues(): for obj in hcomp["instance_list"]: codegen_ref.implementation += codegen_ref.add_tab("-- Instance for '%s' name '%s'\n" % (repr(obj), obj.name)) codegen_ref.implementation += codegen_ref.add_tab("i_%s : %s" % (obj.name, hcomp["component_name"])) # generic map if len(obj.codegen.generics) > 0: codegen_ref.implementation += " generic map (\n" strl = [] for g in obj.codegen.generics: strl.append("%s => %s" % (g["name"], convert_value(g["default_value"], g["type"]))) codegen_ref.implementation += ",\n".join(codegen_ref.add_tab(strl, 2)) codegen_ref.implementation += codegen_ref.add_tab("\n)") # port map if (len(obj.codegen.ports) + len(obj.codegen.external_signals)) > 0: codegen_ref.implementation += " port map (\n" strl = [] for p in obj.codegen.ports: # search for each signal in a port for sig in p["signal_list"]: # format: <portname>_<signame> => sig_<obj.name>_<portname>_<signal_name> strl.append("%s_%s => sig_%s_%s_%s" % (p["name"], sig["name"], obj.name, p["name"], sig["name"])) # and then in external_signals for sig in obj.codegen.external_signals: # format: <signame> => <obj.name>_<signal_name> strl.append("%s => %s_%s" % (sig["name"], obj.name, sig["name"])) codegen_ref.implementation += ",\n".join(codegen_ref.add_tab(strl, 2)) codegen_ref.implementation += codegen_ref.add_tab("\n)") codegen_ref.implementation += ";\n\n" # 3.4 signal connections # connect routers first for obj in self.noc_ref.router_list(): # go through all ports and check its use codegen_ref.implementation += codegen_ref.add_tab("-- Signal mapping for '%s' name '%s'\n" % (repr(obj), obj.name)) for p in obj.codegen.ports: if p["type"] == "dualwb": if p["nocport"] is None: codegen_ref.implementation += codegen_ref.add_tab("-- port '%s' unused\n" % p["name"]) # Unused port. Go through all signals and put input # values tied to 0 for sig in p["signal_list"]: if sig["direction"] == "in": # format: sig_<obj.name>_<portname>_<signal_name> 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"]))) else: # connected with a port. Assign only input signals. peerobj = obj.ports[p["nocport"]]["peer"] # search for peer object codegen ports peerpname = None for peerp in peerobj.codegen.ports: if peerp["nocport"] is not None: findobj = peerobj.ports[peerp["nocport"]]["peer"] if findobj == obj: peerpname = peerp["name"] break if peerpname is None: raise ValueError("Connected object '%s'->'%s': port not found" % (obj.name, peerobj.name)) codegen_ref.implementation += codegen_ref.add_tab("-- port '%s' connected to object '%s' port '%s'\n" % (p["name"], peerobj.name, peerpname)) for sig in p["signal_list"]: if sig["direction"] == "in": peersig = obj.ports[p["nocport"]]["channel"].ports[obj.address]["intercon"].get_complement_signal(sig["name"]) if peersig is not None: # format: sig_<obj.name>_<portname>_<signal_name> 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)) else: codegen_ref.implementation += codegen_ref.add_tab("-- Special signal sig_%s_%s_%s not assigned yet.\n" % (obj.name, p["name"], sig["name"])) # then ipcores for obj in self.noc_ref.ipcore_list(): codegen_ref.implementation += codegen_ref.add_tab("-- Signal mapping for '%s' name '%s'\n" % (repr(obj), obj.name)) # connect signals from and to ipcore # get local and remote intercon obj_icon = obj.ports[obj.get_address()]["channel"].ports[None]["intercon"] dest_icon = obj.ports[obj.get_address()]["channel"].ports[obj.get_address()]["intercon"] obj_port = obj.codegen.ports[0] dest_port = None for p in obj.router_ref.codegen.ports: if p["type"] == dest_icon.intercon_type: dest_port = p if dest_port is None: raise ValueError("Router object '%s': local port not found" % obj.router_ref.name) 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"])) # first ipcore <= router for sig in obj_port["signal_list"]: if sig["direction"] == "in": peersig = obj_icon.get_complement_signal(sig["name"]) if peersig is not None: # format: sig_<obj.name>_<portname>_<signal_name> 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)) else: # special port (TODO!) codegen_ref.implementation += codegen_ref.add_tab("-- Special signal sig_%s_%s_%s not assigned yet.\n" % (obj.name, obj_port["name"], sig["name"])) # then router <= ipcore for sig in dest_port["signal_list"]: if sig["direction"] == "in": peersig = dest_icon.get_complement_signal(sig["name"]) if peersig is not None: # format: sig_<obj.name>_<portname>_<signal_name> 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)) else: 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"])) codegen_ref.implementation += codegen_ref.add_tab("-- Implementation code for Noc --")