OpenCores
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 --")
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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