Line 1... |
Line 1... |
#!/usr/bin/env python
|
#!/usr/bin/env python
|
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
|
|
#
|
#
|
# Basic IPcore model
|
# Basic IPcore model
|
# * TLM model
|
# * TBM model
|
|
# * Code generation model
|
#
|
#
|
# Author: Oscar Diaz
|
# Author: Oscar Diaz
|
# Version: 0.1
|
# Version: 0.2
|
# Date: 03-03-2011
|
# Date: 14-03-2011
|
|
|
#
|
#
|
# This code is free software; you can redistribute it and/or
|
# This code is free software; you can redistribute it and/or
|
# modify it under the terms of the GNU Lesser General Public
|
# modify it under the terms of the GNU Lesser General Public
|
# License as published by the Free Software Foundation; either
|
# License as published by the Free Software Foundation; either
|
Line 28... |
Line 29... |
|
|
#
|
#
|
# Changelog:
|
# Changelog:
|
#
|
#
|
# 03-03-2011 : (OD) initial release
|
# 03-03-2011 : (OD) initial release
|
|
# 14-03-2011 : (OD) adding code generation model
|
#
|
#
|
|
|
"""
|
"""
|
Basic ipcore TLM model
|
* Basic ipcore TBM model
|
|
* Ipcore code generation model
|
"""
|
"""
|
|
|
from nocmodel.noc_tlm_base import *
|
from nocmodel.noc_tbm_base import *
|
|
from nocmodel.noc_codegen_base import *
|
|
from intercon_model import *
|
|
|
# ---------------------------
|
# ---------------------------
|
# Basic IPCore TLM model
|
# Basic IPCore TBM model
|
|
|
class basic_ipcore_tlm(noc_tlm_base):
|
class basic_ipcore_tbm(noc_tbm_base):
|
"""
|
"""
|
TLM model of a NoC ipcore. Its based on sending and receiving packets
|
TBM model of a NoC ipcore. Its based on sending and receiving packets
|
to a custom-based MyHDL generators. This class does not define any
|
to a custom-based MyHDL generators. This class does not define any
|
functionality.
|
functionality.
|
|
|
Attributes:
|
Attributes:
|
* ipcore_ref: reference to ipcore base object
|
* ipcore_ref: reference to ipcore base object
|
Line 53... |
Line 58... |
Notes:
|
Notes:
|
* This model is completely behavioral.
|
* This model is completely behavioral.
|
* See code comments to better understanding.
|
* See code comments to better understanding.
|
"""
|
"""
|
def __init__(self, ipcore_ref):
|
def __init__(self, ipcore_ref):
|
noc_tlm_base.__init__(self)
|
noc_tbm_base.__init__(self)
|
if isinstance(ipcore_ref, ipcore):
|
if isinstance(ipcore_ref, ipcore):
|
self.ipcore_ref = ipcore_ref
|
self.ipcore_ref = ipcore_ref
|
self.graph_ref = ipcore_ref.graph_ref
|
self.graph_ref = ipcore_ref.graph_ref
|
self.logname = "IPCore '%s'" % ipcore_ref.name
|
self.logname = "IPCore '%s'" % ipcore_ref.name
|
if ipcore_ref.name == "":
|
if ipcore_ref.name == "":
|
Line 65... |
Line 70... |
else:
|
else:
|
raise TypeError("This class needs a ipcore object as constructor argument.")
|
raise TypeError("This class needs a ipcore object as constructor argument.")
|
|
|
self.debug("constructor")
|
self.debug("constructor")
|
# generic parameters
|
# generic parameters
|
|
self.retrytimes = 3
|
|
self.retrydelay = 2
|
|
|
# one-port support: get a reference to the related channel
|
# one-port support: get a reference to the related channel
|
self.localch = self.ipcore_ref.channel_ref
|
self.localch = self.ipcore_ref.channel_ref
|
|
|
# get protocol reference
|
# get protocol reference
|
Line 85... |
Line 92... |
|
|
@myhdl.instance
|
@myhdl.instance
|
def outgoing_process():
|
def outgoing_process():
|
while True:
|
while True:
|
yield self.outgoing_packet
|
yield self.outgoing_packet
|
|
# multiple tries
|
|
for i in range(self.retrytimes):
|
retval = self.send(self.ipcore_ref, self.localch, self.outgoing_packet.val)
|
retval = self.send(self.ipcore_ref, self.localch, self.outgoing_packet.val)
|
|
if retval == noc_tbm_errcodes.no_error:
|
|
break;
|
|
yield myhdl.delay(self.retrydelay)
|
|
|
self.generators = [outgoing_process]
|
self.generators = [outgoing_process]
|
self.debugstate()
|
self.debugstate()
|
|
|
def register_generator(self, genfunction, **kwargs):
|
def register_generator(self, genfunction, **kwargs):
|
Line 100... |
Line 112... |
* genfunction: function that returns a MyHDL generator
|
* genfunction: function that returns a MyHDL generator
|
* kwargs: optional keyed arguments to pass to genfunction call
|
* kwargs: optional keyed arguments to pass to genfunction call
|
|
|
Notes:
|
Notes:
|
* This method requires that genfunction has the following prototype:
|
* This method requires that genfunction has the following prototype:
|
* my_function(din, dout, tlm_ref, <other_arguments>)
|
* my_function(din, dout, tbm_ref, <other_arguments>)
|
* din is a MyHDL Signal of type packet, and is the input signal
|
* din is a MyHDL Signal of type packet, and is the input signal
|
to the ipcore. Use this signal to react to input events and
|
to the ipcore. Use this signal to react to input events and
|
receive input packets.
|
receive input packets.
|
* dout is a MyHDL Signal of type packet, and is the output
|
* dout is a MyHDL Signal of type packet, and is the output
|
signal to the ipcore. Use this signal to send out packets to
|
signal to the ipcore. Use this signal to send out packets to
|
local channel (and then insert into the NoC).
|
local channel (and then insert into the NoC).
|
* tlm_ref is a reference to this object. Normal use is to access
|
* tbm_ref is a reference to an object with logging methods.
|
logging methods (e.g. tlm_ref.info("message") ).
|
(e.g. tbm_ref.info("message") ).
|
* <other_arguments> may be defined, this method use kwargs
|
* <other_arguments> may be defined, this method use kwargs
|
argument to pass them.
|
argument to pass them.
|
"""
|
"""
|
makegen = genfunction(din=self.incoming_packet, dout=self.outgoing_packet, tlm_ref=self, **kwargs)
|
makegen = genfunction(din=self.incoming_packet, dout=self.outgoing_packet, tbm_ref=self, **kwargs)
|
self.debug("register_generator( %s ) generator is %s args %s" % (repr(genfunction), repr(makegen), repr(kwargs)))
|
self.debug("register_generator( %s ) generator is %s args %s" % (repr(genfunction), repr(makegen), repr(kwargs)))
|
self.generators.append(makegen)
|
self.generators.append(makegen)
|
|
|
# Transaction - related methods
|
# Transaction - related methods
|
def send(self, src, dest, packet, addattrs=None):
|
def send(self, src, dest, packet, addattrs=None):
|
Line 129... |
Line 141... |
self.localch . This may be checked for errors.
|
self.localch . This may be checked for errors.
|
"""
|
"""
|
self.debug("-> send( %s , %s , %s , %s )" % (repr(src), repr(dest), repr(packet), repr(addattrs)))
|
self.debug("-> send( %s , %s , %s , %s )" % (repr(src), repr(dest), repr(packet), repr(addattrs)))
|
|
|
# call recv on the local channel object
|
# call recv on the local channel object
|
retval = self.localch.tlm.recv(self.ipcore_ref, self.localch, packet, addattrs)
|
retval = self.localch.tbm.recv(self.ipcore_ref, self.localch, packet, addattrs)
|
|
|
# something to do with the retval? Only report it.
|
# something to do with the retval? Only report it.
|
self.debug("-> send returns code '%s'" % repr(retval))
|
self.debug("-> send returns code '%s'" % repr(retval))
|
return retval
|
return retval
|
|
|
Line 148... |
Line 160... |
self.debug("-> recv( %s , %s , %s , %s )" % (repr(src), repr(dest), repr(packet), repr(addattrs)))
|
self.debug("-> recv( %s , %s , %s , %s )" % (repr(src), repr(dest), repr(packet), repr(addattrs)))
|
|
|
# update signal
|
# update signal
|
self.incoming_packet.next = packet
|
self.incoming_packet.next = packet
|
|
|
self.debug("-> recv returns 'noc_tlm_errcodes.no_error'")
|
self.debug("-> recv returns 'noc_tbm_errcodes.no_error'")
|
return noc_tlm_errcodes.no_error
|
return noc_tbm_errcodes.no_error
|
|
|
|
# ---------------------------
|
|
# Ipcore code generation model
|
|
|
|
class basic_ipcore_codegen(noc_codegen_ext):
|
|
"""
|
|
Code generation extension for Ipcore objects.
|
|
"""
|
|
|
|
def __init__(self, codegen_ref):
|
|
noc_codegen_ext.__init__(self, codegen_ref)
|
|
#self.codegen_ref = codegen_ref
|
|
self.ipcore_ref = codegen_ref.nocobject_ref
|
|
if not isinstance(self.ipcore_ref, ipcore):
|
|
raise TypeError("Argument must be a 'noc_codegen_base' instance defined for a ipcore object.")
|
|
|
|
# ipcore model: This basic ipcore has some parameters put in the
|
|
# generics list, and only one port of type masterwb.
|
|
|
|
codegen_ref.modulename = "basic_ipcore"
|
|
|
|
# 1. convert some attributes to generics
|
|
codegen_ref.add_generic("name", self.ipcore_ref.name, "Ipcore Name")
|
|
codegen_ref.add_generic("address", self.ipcore_ref.router_ref.address, "Ipcore router Address")
|
|
|
|
# 2. check intercon on ipcore port
|
|
|
|
ch = self.ipcore_ref.channel_ref
|
|
icon = ch.ports[None]["intercon"]
|
|
if not isinstance(icon, masterwb_intercon):
|
|
raise UserWarning("Port Local on ipcore '%s' does not use intercon 'masterwb_intercon'." % self.ipcore_ref.name)
|
|
|
|
# 2. convert ipcore port to codegen port
|
|
codegen_ref.add_port("PortLocal", None, "Port Local", type=icon.intercon_type)
|
|
|
|
for signame, sigval in icon.signals.iteritems():
|
|
stmp = get_new_signal(
|
|
name=signame,
|
|
direction=sigval["direction"],
|
|
default_value=intbv(0)[sigval["width"]:],
|
|
description=sigval["description"])
|
|
codegen_ref.add_port("PortLocal", stmp)
|
|
|
|
# 3. Calculate a Hash with generics and ports info.
|
|
# WARNING: You must recalculate the hash when you change the model!
|
|
codegen_ref.model_hash()
|
|
|
|
# 4. Implementation comment
|
|
codegen_ref.implementation += "-- Add here implementation code for Ipcore %s" % self.ipcore_ref.name
|
|
|
|
def add_external_signal(self, name, direction, value, description="", **kwargs):
|
|
"""
|
|
Wrapper to noc_codegen_base.add_external_signal method, to support hash
|
|
updating.
|
|
"""
|
|
retval = self.codegen_ref.add_external_signal(name, direction, value, description, **kwargs)
|
|
self.codegen_ref.model_hash()
|
|
return retval
|
|
|
No newline at end of file
|
No newline at end of file
|