#!/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 # Sophie Belloeil # Hugo Clement # Jean-Paul Chaput # Damien Dupuis # Christian Masson # Marek Sroka # # 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 = "instance%d_%s" % ( cell._NB_INST, self._model ) 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 CRL_IN_LO/CRL_IN_PH variables .\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 ) inst = Instance ( 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() ) if mapNet._arity == 1 : tempNet = self._hur_masterCell.getNet ( pin ) 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 ( TypePOWER, TypeGROUND ) : 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" raise Exception ( err ) ############## ### 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