coriolis/stratus1/src/stratus/st_instance.py

395 lines
15 KiB
Python

#!/usr/bin/python
# This file is part of the Coriolis Project.
# Copyright (C) Laboratoire LIP6 - Departement ASIM
# Universite Pierre et Marie Curie
#
# Main contributors :
# Christophe Alexandre <Christophe.Alexandre@lip6.fr>
# Sophie Belloeil <Sophie.Belloeil@lip6.fr>
# Hugo Clement <Hugo.Clement@lip6.fr>
# Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
# Damien Dupuis <Damien.Dupuis@lip6.fr>
# Christian Masson <Christian.Masson@lip6.fr>
# Marek Sroka <Marek.Sroka@lip6.fr>
#
# The Coriolis Project is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# The Coriolis Project 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with the Coriolis Project; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
# License-Tag
# Authors-Tag
# ===================================================================
#
# x-----------------------------------------------------------------x
# | |
# | C O R I O L I S |
# | S t r a t u s - Netlists/Layouts Description |
# | |
# | Author : Sophie BELLOEIL |
# | E-mail : Sophie.Belloeil@asim.lip6.fr |
# | =============================================================== |
# | Py Module : "./st_instance.py" |
# | *************************************************************** |
# | U p d a t e s |
# | |
# x-----------------------------------------------------------------x
import CRL
from Hurricane import *
from st_model import Model, MODELMAP
from st_getrealmodel import GetRealModel, InitBV
import sys, re, types, os
## Alliance's libraries ##
SXLIB = "_x[0-8]"
PXLIB = "_px"
RAMLIB = "ram_"
RFLIB = "rf_"
RF2LIB = "rf2_"
ROMLIB = "rom_"
DPSXLIB = "dp_.*_x[1-8]"
## Puts MBK_CATA_LIB at the begining of PYTHONPATH ##
#cata_lib = os.environ['MBK_CATA_LIB']
#chaine = re.search ( "([^:]*):(.*)", cata_lib )
#while chaine :
# rep = chaine.group ( 1 )
# cata_lib = chaine.group ( 2 )
#
# sys.path.insert ( 0, rep )
#
# chaine = re.search ( "([^:]*):(.*)", cata_lib )
## Class of nets ##
NET = ( "st_net.SignalIn", "st_net.SignalOut", "st_net.SignalInOut" \
, "st_net.SignalUnknown", "st_net.TriState" \
, "st_net.CkIn", "st_net.SignalCk" \
, "st_net.Signal", "st_net.Sig" \
, "st_net.VddIn", "st_net.VssIn" \
, "st_net.VddInFromHur", "st_net.VssInFromHur" \
, "st_net.SignalVdd" , "st_net.SignalVss" \
)
ALIM_NET = ( "st_net.VddIn", "st_net.VssIn" \
, "st_net.VddInFromHur", "st_net.VssInFromHur"
)
################
##### Inst #####
################
class Inst :
################
##### Init #####
################
def __init__ ( self, model, name = None, map = {}, cell = None ) :
global MODELMAP, CELLS, FRAMEWORK
from st_model import MODELMAP, CELLS, FRAMEWORK
from util_Place import UNPLACED, NOSYM
if not cell : cell = CELLS[-1]
##### Virtual library #####
global BV
from st_parser import BV
if BV == [] : InitBV()
if model in BV : model, self._inout = GetRealModel ( model )
##### Attributes of the instance #####
self._model = model.lower()
self._st_cell = cell
self._hur_instance = None
self._plac = UNPLACED
self._map = map
##### Name of the instance ######
if not name :
name = "%s_i%d" % ( self._model, cell._NB_INST )
cell._NB_INST += 1
self._name = name
##### The instance is put in the instances' list of the cell #####
cell._st_insts.append ( self )
##### Errors #####
# Error : if the model is not a string
if type ( model ) != types.StringType :
err = "\n[Stratus ERROR] Inst : the model must be described in a string.\n"
raise Exception ( err )
# Warning : the model can not contain capitalized letters
if re.search ( "[A-Z]", model ) :
print "[Stratus Warning] Inst : Upper case letters are not supported, the name", model, "is lowered."
model = model.lower()
# Error : spaces are forbidden
if re.search ( " ", model ) :
err = "\n[Stratus ERROR] Inst : " + name + " the name of the model \"" + model + "\" can not contain a space.\n"
raise Exception ( err )
if name :
if re.search ( " ", name ) :
err = "\n[Stratus ERROR] Inst : \"" + name + "\" the name of the instance can not contain a space.\n"
raise Exception ( err )
# Warning : the name can not contain capitalized letters
if re.search ( "[A-Z]", name ) :
print "[Stratus Warning] : Upper case letters are not supported, the name", name, "is lowered."
name = name.lower ()
# Error : if map[pin] is not a net
if map :
for pin in map :
if str ( map[pin].__class__ ) not in NET :
err = "\n[Stratus ERROR] Inst : \"" + name + "\" one argument is not a net : "
err += "pin is : " + pin + " and is associated to : "
if map[pin] : err += str(map[pin])
else : err += "None"
err += "\n"
raise Exception ( err )
##### MasterCell #####
self._hur_masterCell = FRAMEWORK.getCell ( self._model, CRL.Catalog.State.Views )
self._st_masterCell = None
for c in CELLS[0]._underCells :
if self._model == c._name :
self._st_masterCell = c
break
# if not( self._hur_masterCell or self._st_masterCell ) : print "\n[Stratus Warning] Inst : no master cell found for instance " + self._name
# Creation of the hurricane instance
if CELLS[0]._hur_plug : self.create_hur_inst ( model )
##############
### Delete ###
##############
def Delete ( self ) :
# Erasement of the references to the instance
for i in range ( len ( self._st_cell._st_insts ) ) :
if self._st_cell._st_insts[i] == self :
del self._st_cell._st_insts[i]
break
# Erasement of the hurricane instance associated
if self._hur_instance : self._hur_instance.Delete()
##############################################
##### Creation of the hurricane instance #####
##############################################
def create_hur_inst ( self, model ) :
if not self._hur_masterCell :
#self._hur_masterCell = FRAMEWORK.getCell ( self._model, CRL.Catalog.State.Views )
self._hur_masterCell = FRAMEWORK.getCell ( model, CRL.Catalog.State.Views )
if not self._hur_masterCell :
err = "\n[Stratus ERROR] HurricanePlug : Problem of master cell " + model + ".\nCheck model name and/or .environment.alliance.xml configuration file.\n"
raise Exception ( err )
if not self._st_masterCell :
if MODELMAP.has_key ( str ( self._hur_masterCell ) ) :
self._st_masterCell = MODELMAP[str ( self._hur_masterCell )]
else :
self._st_masterCell = Model ( str ( self._hur_masterCell.getName() ), hurCell = self._hur_masterCell )
if not self._st_cell._hur_cell :
err = "\n[Stratus ERROR] HurricanePlug : Problem of hurricane cell.\nTry to contact Coriolis team.\n"
raise Exception ( err )
UpdateSession.open()
inst = Instance.create ( self._st_cell._hur_cell
, self._name
, self._hur_masterCell
)
# The hurricane instance is connected to the stratus instance
self._hur_instance = inst
##### Connection #####
##### Function to be applied on each pin
def connectPin ( pin ) :
# Error : if there is a space in the name of the pin (usually done at the end of the pin ...)
if re.search ( " ", pin ) :
err = "\n[Stratus ERROR] Inst : " + self._name + " the keys of the connection map can not contain a space : \"" + pin + "\".\n"
raise Exception ( err )
# Error : if the net to connect does not have it's arity defined
if not ( mapNet._arity ) :
err = "\n[Stratus ERROR] Inst : " + self._name + " : the size of " + mapNet._name + " has not been defined properly.\n"
raise Exception ( err )
wrong_pin = 1
for net in self._hur_masterCell.getExternalNets():
if ( pin == str(net.getName()) ) or re.search ( "%s\(" % pin, str(net.getName()) ) :
wrong_pin = 0
break
# Error : if the pin doesn't exist in the model's ports
if wrong_pin :
err = "\n[Stratus ERROR] Inst : " + str(self._name) + " : port " + pin \
+ " does not exist in model " + str(self._hur_masterCell.getName()) + ". Pins are :"
for pin in self._hur_masterCell.getExternalNets():
err += str ( pin.getName() )
err += ","
sea = re.search ( "(.*),$", err )
if not sea : err += "No pins found ..."
else : err = sea.group(1)
raise Exception ( err )
# Error : if the arities of the nets don't correspond
tabPins = self._st_masterCell._st_ports + self._st_masterCell._st_cks + self._st_cell._st_vdds + self._st_cell._st_vsss
for net in tabPins :
if net._name == pin :
if net._arity != mapNet._arity :
err = "\n[Stratus ERROR] Inst : " + str(self._name) + " : The arity of the net " + mapNet._name + " " + str(mapNet._arity) \
+ " does not correspond to the arity of the port of the cell : "+ net._name + " " + str(net._arity) + ".\n"
raise Exception ( err )
# If the port of the masterCell doesn't have a LSB which is 0
lsb = 0
if mapNet._arity > 1 :
netBus = None
while not ( netBus ) :
netBus = self._hur_masterCell.getNet ( pin.lower() + "(" + str ( lsb ) + ")" )
lsb += 1
if lsb > 20 : # value chosen in order to avoid infinite loop in case of a problem (may be higher)
err = "\n[Stratus ERROR] Inst : " + str(self._name) + " : Probem of map, check the arities of your nets.\n"
raise Exception ( err )
if lsb : lsb -= 1
### Connection ###
if mapNet._real_net : realNet = mapNet._real_net
else : realNet = mapNet
# range 1: given the indice's net
nbit1 = mapNet._ind - realNet._ind
# range 2: deal with reverse nets
if ( '_reverse' in mapNet.__dict__ ) and ( mapNet._reverse ) :
nbit2 = nbit1 - mapNet._arity
pas = -1
else :
nbit2 = nbit1 + mapNet._arity
pas = 1
j = 0
for i in range ( nbit1, nbit2, pas ) :
# If the net has to be concatened
if ( realNet._to_cat ) and ( realNet._to_cat[i] ) :
net = realNet._to_cat[i][0]
bit = realNet._to_cat[i][1]
if net._real_net : net = net._real_net
# If the net which is concatened is an alias
if ( net._alias ) and ( net._alias[bit] ) :
netA = net._alias[bit].keys()[0]
bitA = net._alias[bit][netA]
if net._real_net : netA = netA._real_net
hurNet = netA._hur_net[bitA-net._ind]
else :
hurNet = net._hur_net[bit-net._ind]
# If the net is an alias
elif ( realNet._alias ) and ( realNet._alias[i] ) :
net = realNet._alias[i].keys()[0]
bit = realNet._alias[i][net]
if net._real_net : net = net._real_net
hurNet = net._hur_net[bit+net._ind]
else :
hurNet = realNet._hur_net[i]
if mapNet._arity == 1 : tempNet = self._hur_masterCell.getNet ( pin.lower() )
else : tempNet = self._hur_masterCell.getNet ( pin.lower() + "(" + str(j+lsb) + ")" )
j += 1
if not ( tempNet ) :
err = "\n[Stratus ERROR] Inst : Problem in map. Check that the arities of your nets are correct.\n"
raise Exception ( err )
plug = self._hur_instance.getPlug ( tempNet )
plug.setNet ( hurNet )
# In order to see the ring
#if str ( realNet.__class__ ) not in ALIM_NET : CRL.createPartRing ( self._st_cell._hur_cell, hurNet.getName() )
##### Loop on each pin
for pin in self._map :
mapNet = self._map[pin]
### Virtual library ###
if "_inout" in self.__dict__ :
import types
if type ( self._inout[pin] ) == types.ListType :
for realpin in self._inout[pin] :
connectPin ( realpin )
else :
realpin = self._inout[pin]
connectPin ( realpin )
### Other ###
else :
connectPin ( pin )
# Error message if the connection is not correct (detection before vst driver)
# Not for vdd/vss in case of utilisation of SetGlobal
# The detection is done with vst driver in this case ...
for plug in self._hur_instance.getUnconnectedPlugs():
if plug.getMasterNet().getType() not in ( Net.Type.POWER, Net.Type.GROUND ) :
name = str(plug.getMasterNet().getName())
chaine = re.search ( "(.*)\(", name )
if chaine : name = chaine.group(1)
err = "\n[Stratus ERROR] Inst : plug " + name + " of instance " + self._name + " must be connected.\n"
err += ' (raw name: <%s>)\n' % str(plug.getMasterNet().getName())
raise Exception ( err )
UpdateSession.close()
##############
### Prints ###
##############
def printInstance ( self ) :
print " => model", self._model
print " => map"
for pin in self._map :
n = self._map[pin]
if n._to_merge : n = n._to_merge[0][0]
print " ", pin, "->", n._name
def printMap ( self ) :
print "Map:", self._name
for pin in self._map :
print " ", pin, self._map[pin]._name
#########################
#### SetCurrentModel ####
#########################
def SetCurrentModel ( instance ) :
global CELLS
from st_model import CELLS
if not instance :
err = "\n[Stratus ERROR] SetCurrentModel : argument given does not exist.\n"
raise Exception ( err )
cell = instance._st_masterCell
if not cell :
err = "\n[Stratus ERROR] SetCurrentModel : cannot find model for instance " + str ( getName ( instance ) ) + ".\n"
raise Exception ( err )
CELLS.append ( cell )
return cell