coriolis/stratus1/src/stratus/st_model.py

1351 lines
44 KiB
Python

#!/usr/bin/python
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | 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_model.py" |
# +-----------------------------------------------------------------+
import re
import types
import string
import Cfg
import CRL
import Viewer
from Hurricane import *
FRAMEWORK = None
EDITOR = None
MODELMAP = {}
CELLS = []
STRATUS = 100
LOGICAL = CRL.Catalog.State.Logical
PHYSICAL = CRL.Catalog.State.Physical
VIEWS = CRL.Catalog.State.Views
def setEditor ( editor ):
global EDITOR
EDITOR = editor
return
#######################
##### Class Model #####
#######################
class Model() :
##########################
##### Initialisation #####
##########################
def __init__ ( self, nom, param = {}, hurCell = None, hurricane_plug = True ) :
global FRAMEWORK, CELLS
# Look up the editor
if globals().has_key ( "__editor" ) : setEditor ( __editor )
self._name = nom
self._param = param
self.pat = None
self._hur_cell = hurCell
self._st_insts = [] # Tab : list of the instances
self._st_ports = [] # Tab : list of the nets
self._st_sigs = [] # Tab : list of the nets
self._st_partsigs = [] # Tab : list of the partial nets
self._st_merge = [] # Tab : list of the nets to merge, in order to have them in the right order
self._hierarchy = 0 # Modified in ModelCreation
self._TAB_NETS_OUT = []
self._TAB_NETS_CAT = []
self._NB_INST = 0
# List of the generators used for overload
self._and = 'A2'
self._or = 'O2'
self._xor = 'Xr2'
self._not = 'Inv'
self._buff = 'Buf'
self._reg = 'Sff1'
# Stratus generators
self._mux = 'Smux'
self._shift = 'Shifter'
self._comp = 'Comp'
# Arithmetic generators
self._add = 'Slansky'
self._sub = 'Sub'
self._mult = 'Multiplier'
self._div = None
self._signed = True
self._extended = False
self._model_map = {}
# List of the under-cells of a cell
self._underCells = {}
# self._tabPlacement = []
# Instance reference for placement
self._insref = None
# Place and Route
self._nb_alims_verticales = 0
self._nb_pins = 0 # to number the pins of the core
self._nb_vdd_pins = 0 # to number the pins vdd of the core
self._nb_vss_pins = 0 # to number the pins vss of the core
self.standard_instances_list = []
self.pad_north = [] # list to save the pads names
self.pad_south = []
self.pad_east = []
self.pad_west = []
# Creation of the database
if not FRAMEWORK :
#Initialize()
FRAMEWORK = CRL.AllianceFramework.get()
self._st_vdds = []
self._st_vsss = []
if hurCell :
from st_net import VddInFromHur
from st_net import VssInFromHur
try:
netVdd = iter(hurCell.getPowerNets()).next()
self._st_vdds.append ( VddInFromHur ( netVdd ) )
except StopIteration:
print "[Stratus Warning] : Cell", self._name, "does not have a vdd port."
pass
try:
netVss = iter(hurCell.getGroundNets()).next()
self._st_vsss.append ( VssInFromHur ( netVss ) )
except StopIteration:
print "[Stratus Warning] : Cell", self._name, "does not have a vss port."
pass
self._st_cks = []
if not hurCell :
# List of the cells
CELLS.append ( self )
# List of the undercells
if CELLS[0] != self :
CELLS[0]._underCells[self] = 0
# CELLS[0]._tabPlacement.append ( self )
self._hur_plug = hurricane_plug
# HurricanePLug if : no hurCell, in mode hurricane plug (i.e. hurricane_plug and hurricane_plug of the masterCell)
if ( not hurCell ) and ( hurricane_plug ) :
if CELLS[0] == self :
self.HurricanePlug()
else :
if CELLS[0]._hur_plug :
self.HurricanePlug()
##### Delete #####
def Delete ( self ) :
UpdateSession.open()
under_cells = self._underCells
self._hur_cell.Delete()
for cell in under_cells : cell._hur_cell.Delete()
UpdateSession.close()
#####################################################
##### Initialisation of attributes for the cell #####
#####################################################
def InitGraph ( self ) :
self._graph = True
# External nets
for net in self._st_ports :
net._st_inst_in = None
net._st_insts_out = []
net._covered = False
# Internal nets
for net in self._st_sigs :
net._st_inst_in = None
net._st_insts_out = []
net._covered = False
# Part nets
for pnet in self._st_partsigs :
pnet._st_inst_in = None
pnet._st_insts_out = []
pnet._covered = False
# Instances
for inst in self._st_insts :
inst._st_nets_in = []
inst._st_nets_out = []
# Initialisation of instances and nets
self.initNet ( inst )
self.initInst ( inst )
########################################################
##### Initialisation of the attributes of the nets #####
########################################################
def initNet ( self, instance ) :
# For each pin
for pin in instance._map :
# Check if the pin is an output or an input
direct = ""
direct = self.getDirect ( instance._model, pin )
# Get the net connected to this pin
if instance._map[pin]._to_merge : mapNet = instance._map[pin]._to_merge[0][0]
else : mapNet = instance._map[pin]
if len ( instance._map[pin]._to_merge ) > mapNet._arity :
mapNet._real_arity = len ( instance._map[pin]._to_merge )
mapNet._inverse_merge = instance._map[pin]
# Initialisation
if direct == 'input' :
if mapNet._real_net :
mapNet = mapNet._real_net
if '_st_insts_out' not in mapNet.__dict__ : mapNet._st_insts_out = []
if instance not in mapNet._st_insts_out : mapNet._st_insts_out += [instance]
elif direct == 'output' : # FIXME _real_net not taken care of
mapNet._st_inst_in = instance
#############################################################
##### Initialisation of the attributes of the instances #####
#############################################################
def initInst ( self, instance ) :
# For each pin
for pin in instance._map :
# Check if the pin is an output or an input
direct = ""
direct = self.getDirect ( instance._model, pin )
# Get the net connected to this pin
if instance._map[pin]._to_merge : mapNet = instance._map[pin]._to_merge[0][0]
else : mapNet = instance._map[pin]
# Initialisation
if direct == 'input' : instance._st_nets_in += [mapNet]
elif direct == 'output' : instance._st_nets_out += [mapNet]
###########################################
##### Returns the direction of a port #####
###########################################
def getDirect ( self, model, pin ) :
global FRAMEWORK
hurCell = FRAMEWORK.getCell ( model, CRL.Catalog.State.Views )
stCell = None
if not hurCell :
for c in self._underCells :
if c._name == model :
stCell = c
break
if not hurCell and not stCell :
err = "\nError : no cell found with model %s.\n" % model
raise Exception ( err )
# Hurricane cell found:
if hurCell :
found = False
for net in hurCell.getExternalNets():
direction = net.getDirection()
name = str(net.getName())
if net.getType() in ( Net.Type.POWER, Net.Type.GROUND, Net.Type.CLOCK ) :
found = True
continue
chaine = re.search ( "(.*)\([0-9]+\)", name )
if chaine : name = chaine.group(1)
if name == pin :
found = True
if direction == DirectionOUT : return "output"
elif direction == DirectionIN : return "input"
else :
err = "\nError : unable to find direction of port %s in model %s. Direction is %d\n" % ( pin, model, direction )
raise Exception ( err )
if not found :
err = "\nError : unable to find port %s in model %s.\n" % ( pin, model )
raise Exception ( err )
# Stratus cell found:
elif stCell :
found = False
for net in stCell._st_vdds :
if net._name == pin :
found = True
break
for net in stCell._st_vsss :
if net._name == pin :
found = True
break
for net in stCell._st_cks :
if net._name == pin :
found = True
break
# _st_ports i.e. not alimentations and not clock
for net in stCell._st_ports :
if net._name == pin :
found = True
if net._direct == "OUT" : return "output"
elif net._direct == "IN" : return "input"
else :
err = "\nError : unable to find direction of port %s in model %s.\n" % ( pin, model )
raise Exception ( err )
if not found :
ports = ""
for net in stCell._st_ports : ports += net._name + ","
err = "\nError : unable to find port %s in model %s.\nPorts are : %s\n" % ( pin, model, ports )
raise Exception ( err )
else :
err = "\n[ERROR] InitGraph : no model named " + model + " in the database.\n"
raise Exception ( err )
#############################
##### Print of the cell #####
#############################
def Print ( self ) :
print "################## The Cell ##################"
for inst in self._st_insts :
print " * inst name :", inst._name
print " inst model :", inst._model
for pin in inst._map :
if pin != 'vdd' and pin != 'vss' :
net = inst._map[pin]
print " pin :", pin, "net :", net._name, "with arity :", net._arity
if net._to_merge :
net = inst._map[pin]._to_merge[0][0]
print " net merged with :", net._name, "with arity :", net._arity
#############################
##### Find An Instance #####
#############################
def getInstance ( self, name ):
for instance in self._st_insts:
if instance._name == name:
return instance
return None
#########################
def PrintGraph ( self ) :
if "_graph" not in self.__dict__ :
err = "\n[Stratus ERROR] PrintGraph : The graph does not exist. Use initGraph before.\n"
raise Exception ( err )
else :
if self._graph == False :
err = "\n[Stratus ERROR] PrintGraph : The graph does not exist. Use initGraph before.\n"
raise Exception ( err )
print "################## Cell's Graph features ##################"
for inst in self._st_insts :
print " => inst name :", inst._name, "( model :", inst._model, ")"
print " inst st_nets_in :"
for net in inst._st_nets_in : print " ", net._name
print " inst st_nets_out :"
for net in inst._st_nets_out : print " ", net._name
for port in self._st_ports :
print " => port name :", port._name
if port._st_inst_in : print " port _st_inst_in :", port._st_inst_in._name
print " port _st_insts_out :"
for p in port._st_insts_out : print " ", p._name
for sig in self._st_sigs :
print " => sig name :", sig._name
if sig._st_inst_in : print " sig _st_inst_in :", sig._st_inst_in._name
print " sig _st_insts_out :"
for s in sig._st_insts_out : print " ", s._name
for psig in self._st_partsigs :
print " => part sig name :", psig._name
if '_st_inst_in' in psig.__dict__ and psig._st_inst_in: print " part sig _st_inst_in :", psig._st_inst_in._name
if '_st_insts_out' in psig.__dict__ :
print " part sig _st_insts_out :"
for s in psig._st_insts_out : print " ", s._name
#####################
##### overloard #####
#####################
##### __getattr #####
# def __getattr__ ( self, attr ) :
##### __str #####
def __str__ ( self ) :
s = "Model" + str ( self._hur_cell )
return s
########################
##### VLSI Methods #####
########################
##### Interface #####
def Interface ( self ) :
print "[Stratus Warning] : Execution of empty Interface method for", self._name, "."
##### Netlist #####
def Netlist ( self ) :
print "[Stratus Warning] : Execution of empty Netlist method for", self._name, "."
pass
##### Layout #####
def Layout ( self ) :
print "[Stratus Warning] : Execution of empty Layout method for", self._name, "."
pass
##### Vbe #####
def Vbe ( self ) :
self._vbe = True
##### View : in order to see the in the editor #####
def View ( self, stopLevel=1, message="Status stop point" ) :
global EDITOR
if not self._hur_cell :
err = "\n[Stratus ERROR] View : Hurricane Cell does not exist.\nCheck CRL_IN_LO/CRL_IN_PH variables.\n"
raise Exception ( err )
if EDITOR:
EDITOR.setCell ( self._hur_cell )
EDITOR.fit ()
if stopLevel > 0:
Breakpoint.stop ( stopLevel, message )
##### Save : in order to create the output files #####
def Save ( self, views = 0, fileName = None ) :
global FRAMEWORK
global CELLS
netlistFormat = Cfg.getParamString('stratus1.format').asString()
if views == STRATUS :
self.exportStratus ( fileName )
elif netlistFormat == 'vst' :
UpdateSession.open()
hurCell = self._hur_cell
if str ( hurCell.getName() ) != "__Scratch__" :
FRAMEWORK.saveCell ( hurCell, views|CRL.Catalog.State.Logical|CRL.Catalog.State.VstUseConcat )
if len ( CELLS ) == 0 :
err = "\n[Stratus ERROR] Save : CELLS stack is empty.\n"
raise Exception ( err )
CELLS.pop()
UpdateSession.close()
elif netlistFormat == 'stratus' :
self.exportStratus ( fileName )
elif netlistFormat in ['vhd','vlog','json'] :
self.export(netlistFormat)
else :
raise Exception('Unrecognized format %s' % netlistFormat)
##### Simul : in order to use simulation tool #####
def Simul ( self, name = None, tool = 'asimut' ) :
from utils import runpat
if not name : name = self._name
simulator = Cfg.getParamString('stratus1.simulator').asString()
if simulator == 'asimut' :
runpat ( self._name, name, '-l 1 -p 100 -zerodelay -bdd' )
elif simulator == 'ghdl' :
import os
cmd_str = ('ghdl -c -g -Psxlib --ieee=synopsys *.vhd -r %s_run --vcd=%s.vcd' %(name,name))
os.system(cmd_str)
elif tool == 'asimut' : runpat ( self._name, name, '-l 1 -p 100 -zerodelay -bdd' )
else : raise Exception ( 'not implemented yet' )
##### TestBench : in order to create testbench #####
def Testbench ( self ) :
netlistFormat = Cfg.getParamString('stratus1.format').asString()
import stimuli
stim = stimuli.Stimuli(self)
if netlistFormat == 'vhd' :
# Create stimuli input file
stim.create_stimuli_text_file()
# Create testbench
stim.create_testbench(delay = 20, unit = 'ns', debug = False, downto = True, logic = False)
# Create testbench and block instance
stim.create_run(debug = False, downto = True)
elif netlistFormat == 'vst' :
stim.create_pat_file()
else :
raise Exception('Testbench not yet implemented for format %s' % netlistFormat)
##### Create a stratus file given the database #####
def exportStratus ( self, fileName ) :
## Cat formating ##
def catName ( net, tableau ) :
name = "Cat ( "
paire = tableau[-1]
if paire :
net1 = paire[0]
bit1 = str(paire[1])
else :
net1 = net
bit1 = str(len(tableau)-1)
for i in range ( len(tableau)-2, -1, -1 ) :
change = False
if tableau[i] and not tableau[i+1] :
change = True
elif not tableau[i] and tableau[i+1] :
change = True
elif tableau[i] and tableau[i+1] :
if tableau[i][0] != tableau[i+1][0] :
change = True
if change :
if tableau[i+1] : bit2 = str(tableau[i+1][1])
else : bit2 = str(i+1)
name += "self."
if int(bit2) == int(net1._ind) and int(bit1) == (net1._arity-1) :
name += net1._name
else :
name += net1._name
name += "["
name += bit1
name += ":"
name += bit2
name += "]"
name += ", "
if tableau[i] : net1 = tableau[i][0]
else : net1 = net
if tableau[i] : bit1 = str(tableau[i][1])
else : bit1 = str(i)
if tableau[0] :
bit2 = str(tableau[0][1])
else :
bit2 = "0"
name += "self."
if int(bit2) == int(net1._ind) and int(bit1) == (net1._arity-1) :
name += net1._name
else :
name += net1._name
name += "["
name += bit1
name += ":"
name += bit2
name += "]"
name += " )"
return name
#########################
nom = str(self.__class__)
chaine = re.search ( "[^\.]*\.(.*)", nom )
nom = chaine.group(1)
if not fileName : fileName = nom + "_created"
fileName += ".py"
file = open ( fileName, "w+" )
file.write ( "#!/usr/bin/python\n\n" )
file.write ( "from stratus import *\n\n" )
file.write ( "class %s ( Model ) :\n\n" % nom )
##### Interface #####
file.write ( " def Interface ( self ) :\n\n" )
for net in self._st_ports :
if net._direct == "IN" : classe = "SignalIn"
elif net._direct == "OUT" : classe = "SignalOut"
elif net._direct == "INOUT" : classe = "SignalInOut"
file.write ( " self.%s = %s ( \"%s\", %d )\n" % ( net._name, classe, net._name, net._arity ) )
file.write ( "\n" )
for ck in self._st_cks :
if ck._ext:
file.write ( " self.%s = CkIn ( \"%s\" )\n" % (ck._name, ck._name) )
file.write ( " self.vdd = VddIn ( \"vdd\" )\n" )
file.write ( " self.vss = VssIn ( \"vss\" )\n" )
file.write ( "\n" )
##### Netlist #####
file.write ( " def Netlist ( self ) :\n\n" )
# Signals
for net in self._st_sigs :
if net._to_merge :
towrite = False
for paire in net._to_merge :
if paire == 0 : towrite = True
if not towrite : continue
file.write ( " self.%s = Signal ( \"%s\", %d )\n" % ( net._name, net._name, net._arity ) )
file.write ( "\n" )
# Generate
for cell in CELLS[0]._underCells :
if CELLS[0]._underCells[cell] == 1 :
classe = str(cell.__class__)
nom = cell._name
param = cell._param
# Gestion of libraries with specific treatment
chaine = re.search ( "(.*)\.([^\.]*)", classe )
if chaine :
fichier = chaine.group(1)
if re.search ( "dpgen_", fichier ) or re.search ( "st_", fichier ) :
classe = chaine.group(2)
# Special treatment for virtual library
if classe == "Bool" :
nom = cell._name
classe = cell._param['model']
param = cell._param
del param['model']
del param['realModel']
classe = string.upper(classe[0]) + classe[1:] #FIXME !!!
if re.search ( "(.*)\.([^\.]*)", classe ) : # ArithLib generator
classe = string.lower(classe[0]) + classe[1:]
file.write ( " Generate ( \"%s\", \"%s\", param = %s )\n" % ( classe, nom, param ) )
file.write ( "\n" )
# Instances
for inst in self._st_insts :
#chaine = re.search ( "([^_]*)_(.*)", inst._name ) #XTOF FIXME !!!
#instName = chaine.group(1) #XTOF FIXME !!
file.write ( " self.%s = Inst ( \"%s\"\n" % ( inst._name, inst._model ) )
file.write ( " , \"%s\"\n" % inst._name )
file.write ( " , map = { " )
# Map
for pin in inst._map :
toto = False
tata = False
netInMap = inst._map[pin]
nom = "self." + netInMap._name
# <=
if netInMap._to_merge :
oneperone = True
for i in range ( len ( netInMap._to_merge ) ) :
paire = netInMap._to_merge[i]
if paire :
net = paire[0]
if i > 0 :
if netInMap._to_merge[i-1] != 0 :
netbefore = netInMap._to_merge[i-1][0]
else :
oneperone = False
break
if net != netbefore :
oneperone = False
break
if paire[1] != i :
oneperone = False
break
else :
toto = True
oneperone = False
break
# "easy" case : 1 per 1 corresponding
if oneperone :
netInMap = netInMap._to_merge[0][0]
nom = "self." + netInMap._name
# else : Cat of the different signals
else :
nom = catName ( netInMap, netInMap._to_merge )
# Cat
if netInMap._to_cat :
tata = True
nom = catName ( netInMap, netInMap._to_cat )
if toto and tata : print "Attention est ce un cas bien gere ???"
if pin == inst._map.keys()[0] : file.write ( "\"%s\" : %s\n" % ( pin, nom ) )
else : file.write ( " , \"%s\" : %s\n" % ( pin, nom ) )
file.write ( " }\n" )
file.write ( " )\n\n" )
##### End #####
file.close ()
##### Export the given database in the given format
def export ( self, format):
from st_export import write
if format not in ['vhd','vlog','json']:
raise "Unrecognized format %s" %(format)
write(self,format)
##### Create a IEEE VHDL file given the database #####
def exportVHD ( self ) :
file = open ( self._name + '.vhd', "w+" )
file.write ( "--\n" )
file.write ( "-- Generated by VHDL export\n" )
file.write ( "--\n" )
file.write ( "library ieee;\n" )
file.write ( "use ieee.std_logic_1164.all;\n\n" )
if 'realModel' in self._param :
file.write ( "library sxlib;\n" )
file.write ( "use sxlib.all;\n\n" )
##### Entity #####
file.write ( "entity %s is\n" % self._name )
file.write ( " port(\n" )
strPorts = ""
for net in self._st_ports :
if net._arity == 1 :
strPorts += " %s : %s std_logic;\n" % ( net._name, net._direct )
else :
strPorts += " %s : %s std_logic_vector(%d downto %d);\n" % ( net._name, net._direct, net._arity-1+net._ind, net._ind )
for ck in self._st_cks :
if ck._ext:
strPorts += " %s : IN std_logic;\n" % ( ck._name )
file.write(strPorts[:-2])
file.write ( "\n );\n" )
file.write ( "end %s ;\n\n" % self._name )
##### Architecture #####
file.write ( "architecture structural of %s is\n" % self._name )
# Components
if 'realModel' in self._param :
cellList = [self]
else :
cellList = self._underCells
for cell in cellList :
if 'realModel' in self._param :
nom = cell._param['realModel']
else :
nom = cell._name
#classe = str(cell.__class__)
#nom = cell._name
#param = cell._param
#print "nom " + nom
#print "classe " + classe
## Gestion of libraries with specific treatment
#chaine = re.search ( "(.*)\.([^\.]*)", classe )
#if chaine :
# fichier = chaine.group(1)
# if re.search ( "dpgen_", fichier ) or re.search ( "st_", fichier ) :
# classe = chaine.group(2)
# # Special treatment for virtual library
# if classe == "Bool" :
# #nom = cell._name
# nom = cell._param['realModel']
# classe = cell._param['model']
# param = cell._param
# #del param['model']
# #del param['realModel']
#classe = string.upper(classe[0]) + classe[1:] #FIXME !!!
#if re.search ( "(.*)\.([^\.]*)", classe ) : # ArithLib generator
# classe = string.lower(classe[0]) + classe[1:]
file.write ( " component %s\n" % nom )
file.write ( " port(\n" )
# Ports
strPorts = ""
for net in cell._st_ports :
if net._arity == 1 :
strPorts += " %s : %s std_logic;\n" % ( net._name, net._direct )
else :
strPorts += " %s : %s std_logic_vector(%d downto %d);\n" % ( net._name, net._direct, net._arity-1+net._ind, net._ind )
for ck in cell._st_cks :
if ck._ext:
strPorts += " %s : IN std_logic;\n" % ( ck._name )
file.write(strPorts[:-2])
file.write ( "\n );\n" )
file.write ( " end component;\n\n")
# Signals
for net in self._st_sigs :
if net._to_merge :
towrite = False
for paire in net._to_merge :
if paire == 0 : towrite = True
if not towrite : continue
if net._arity == 1 :
file.write ( " signal %s : std_logic;\n" % net._name )
else :
file.write ( " signal %s : std_logic_vector(%d downto %d);\n" % ( net._name, net._arity-1+net._ind, net._ind ) )
# Instances
file.write ( "\nbegin\n" )
for inst in self._st_insts :
#chaine = re.search ( "([^_]*)_(.*)", inst._name ) #XTOF FIXME !!!
#instName = chaine.group(1) #XTOF FIXME !!
file.write ( " %s : %s\n" % ( inst._name, inst._model ) )
file.write ( " port map(\n" )
# Map
strMap = ""
for pin in inst._map :
toto = False
tata = False
netInMap = inst._map[pin]
if netInMap._real_net :
nom = netInMap._real_net._name
else :
nom = netInMap._name
# <=
if netInMap._to_merge :
oneperone = True
for i in range ( len ( netInMap._to_merge ) ) :
paire = netInMap._to_merge[i]
if paire :
net = paire[0]
if i > 0 :
if netInMap._to_merge[i-1] != 0 :
netbefore = netInMap._to_merge[i-1][0]
else :
oneperone = False
break
if net != netbefore :
oneperone = False
break
if paire[1] != i :
oneperone = False
break
else :
toto = True
oneperone = False
break
# "easy" case : 1 per 1 corresponding
if oneperone :
netInMap = netInMap._to_merge[0][0]
nom = netInMap._name
# else : Cat of the different signals
else :
nom = catName ( netInMap, netInMap._to_merge )
# Cat
if netInMap._to_cat :
tata = True
nom = catName ( netInMap, netInMap._to_cat )
if toto and tata : print "Attention est ce un cas bien gere ???"
if netInMap not in self._st_vdds + self._st_vsss :
if pin == inst._map.keys()[0] : strMap += " %s => %s,\n" % ( pin, nom )
else : strMap += " %s => %s,\n" % ( pin, nom )
file.write(strMap[:-2] + '\n')
file.write ( " );\n\n" )
##### End #####
file.write('end structural;')
file.close ()
#### Quit : to quit the current cell without saving #####
def Quit ( self ) :
global CELLS
CELLS.pop ()
#########################################
##### GetModelName : Class's method #####
#########################################
def GetModelName ( param ) :
return None
GetModelName = staticmethod ( GetModelName )
#########################################
##### GetParam : Class's method #####
#########################################
def GetParam () :
return None
GetParam = staticmethod ( GetParam )
###############
##### Set #####
###############
def SetAnd ( self, model ) : self._and = model
def SetOr ( self, model ) : self._or = model
def SetXor ( self, model ) : self._xor = model
def SetNot ( self, model ) : self._not = model
def SetBuff ( self, model ) : self._buff = model
def SetReg ( self, model ) : self._reg = model
def SetMux ( self, model ) : self._mux = model
def SetShift ( self, model ) : self._shift = model
def SetComp ( self, model ) : self._comp = model
def SetAdd ( self, model ) : self._add = model
def SetMult ( self, model ) : self._mult = model
def SetDiv ( self, model ) : self._div = model
def SetSigned ( self, model ) : self._signed = model
def SetExtended ( self, model ) : self._extended = model
#############################
##### Creation of model #####
#############################
def ModelCreation ( self, modele, modele2, dict, hierarchy, realModele = None, inOut = None ) :
global CELLS
from st_parser import BVg
## Virtual library ##
from st_bool import Bool
## Stratus generators ##
from st_mux import Smux
from st_shifter import Shifter
from st_comp import Comp
from st_const import Constant
from st_extend import Extend
from st_slansky import Slansky
from st_slansky import Sub
from st_mult import Multiplier
## Genlib ##
from dpgen_Shifter import DpgenShifter
from dpgen_Shrot import DpgenShrot
from dpgen_Nul import DpgenNul
from dpgen_RAM import DpgenRam
from dpgen_ROM2 import DpgenRom2
from dpgen_ROM4 import DpgenRom4
from dpgen_ADSB2F import DpgenAdsb2f
from dpgen_RF1 import DpgenRf1, DpgenRf1d, DpgenRf1r0, DpgenRf1dr0, DpgenFifo
from dpgen_RF2 import DpgenRf2, DpgenRf2d, DpgenRf2r0, DpgenRf2dr0
from dpgen_Regular import DpgenAnd2, DpgenAnd3, DpgenAnd4, DpgenBuff, DpgenBuse, DpgenConst, DpgenDff, DpgenDfft, DpgenInv, DpgenMux2, DpgenNand2, DpgenNand2mask, DpgenNand3, DpgenNand4, DpgenNbuse, DpgenNmux2, DpgenNor2, DpgenNor2mask, DpgenNor3, DpgenNor4, DpgenOr2, DpgenOr3, DpgenOr4, DpgenSff, DpgenSfft, DpgenXnor2, DpgenXnor2mask, DpgenXor2
from util_Gen import F_MSB_FIRST
if type ( dict ) != types.DictType :
err = "\n[Stratus ERROR] Inst : instanciation of a user's defined generator. The methods' arguments must be dictionnaries.\n"
raise Exception ( err )
##### Creation of the instance #####
# dict['flags'] = F_MSB_FIRST # When vst driver permits to do F_LSB_FIRST or F_LSB_FIRST TODO
# dict['flags'] = 0
## Virtual library ##
if modele in BVg :
dict['model'] = modele.lower()
dict['realModel'] = realModele
instCell = Bool ( modele2, dict, inOut )
## Generator ##
elif re.search ( "\.", modele ) :
chaine = re.search ( "(.*)\.([^\.]*)$", modele )
ficName = chaine.group(1)
className = chaine.group(2)
# Roselyne : pour prendre en compte les modeles recursifs
#import sys
moduleClass = __import__ ( ficName, globals(), locals(), [className] )
modeleClass = getattr ( moduleClass, className )
#try :
# modeleClass = getattr ( sys.modules['__main__'], className )
#except AttributeError :
# moduleClass = __import__ ( ficName, globals(), locals(), [className] )
# modeleClass = getattr ( moduleClass, className )
# fin Roselyne
instCell = modeleClass ( modele2, dict )
else :
instCell = eval ( "%s ( \"%s\", %s )" % ( modele, modele2, str(dict) ) )
## MAJ of the hierarchy ##
instCell._hierarchy = hierarchy
##### Methods #####
if ( self._hur_cell ) and ( not instCell._hur_cell ) : instCell.HurricanePlug()
instCell.Interface()
instCell.Netlist()
if ( 'clean' in dict ) and ( dict['clean'] != False ) :
if 'interactive' not in dict : dict['interactive'] = False
instCell.Clean ( dict['interactive'], dict['clean'] )
if ( 'behavioral' in dict ) and ( dict['behavioral'] == True ) :
instCell.Vbe()
if instCell._hur_cell :
v = 0
if ( 'physical' in dict ) and ( dict['physical'] == True ) :
instCell.Layout()
v = CRL.Catalog.State.Physical
instCell.Save( v|CRL.Catalog.State.Logical )
else :
instCell.Quit()
if CELLS[0] != instCell : CELLS[0]._underCells[instCell] = hierarchy
return instCell
#################################################################
##### HurricanePlug : in order to create the hurricane cell #####
#################################################################
def HurricanePlug ( self ) :
global FRAMEWORK, CELLS
if self._hur_cell :
print "[Stratus Warning] : The stratus cell already exists."
return
self._hur_plug = True
##### Creation of all the under cells #####
# Initialisation of the max depth
max_depth = 0
for keyCell in self._underCells :
if self._underCells[keyCell] > max_depth : max_depth = self._underCells[keyCell]
# Creation from the leaf to the top cell
while max_depth :
for keyCell in self._underCells :
if self._underCells[keyCell] == max_depth :
if not FRAMEWORK.getCell ( keyCell._name, CRL.Catalog.State.Views ) :
CELLS.append ( keyCell )
keyCell.CellHurCreation()
max_depth -= 1
# Creation of the top cell
CELLS.append ( self )
self.CellHurCreation()
##### CellHurCreation #####
def CellHurCreation ( self ) :
global FRAMEWORK, CELLS
# The cell
hurCell = FRAMEWORK.createCell ( self._name )
hurCell.setTerminal ( 0 )
self._hur_cell = hurCell
MODELMAP [ str ( self._hur_cell ) ] = self
# The nets
for net in self._st_ports : net.create_hur_net()
for net in self._st_sigs : net.create_hur_net()
for net in self._st_cks : net.create_hur_net()
for net in self._st_vdds : net.create_hur_net()
for net in self._st_vsss : net.create_hur_net()
# The instances and the connection
for inst in self._st_insts : inst.create_hur_inst ( inst._model )
# Merge
for net in self._st_merge : net.hur_merge()
if ( self != CELLS[0] ) and ( self._st_insts ) : # Layout done if HurricanePlug after Netlist method
#self.Layout() # FIXME trouver une raison de le faire ou pas : instances placees ou pas ... HurricanePlug ne doit plus marcher avec placement A VERIFIER 14/01/08
if self._st_insts[0]._hur_instance.getPlacementStatus() : self.Save ( CRL.Catalog.State.Physical )
else : self.Save ( CRL.Catalog.State.Logical )
else :
self.Quit()
####################
##### Clean Up #####
####################
def Clean ( self, interactive = False, tab_name_net = [] ) :
# Hurricane cell
hurricane_cell = self._hur_cell
# Useful for print
TAB_NETS = []
TAB_INSTS = []
cpt_inst_del = 0
cpt_net_del = 0
##### Tabs initialisation #####
net_entree = []
net_sortie = []
net_interne = []
for net in hurricane_cell.getNets():
if net.getDirection() == DirectionUNDEFINED : net_interne.append ( net )
elif net.getDirection() == DirectionIN : net_entree.append ( net )
elif net.getDirection() == DirectionOUT : net_sortie.append ( net )
##### File initialisation #####
file = []
# Output nets put in the file if there are given as arguments
if tab_name_net != True :
for net_name in tab_name_net :
for net in net_sortie :
if net_name == str ( net.getName() ) :
file.insert ( 0, net )
if interactive : print "Output Net", net, "has to be erased, it is put in the fifo."
## Internal nets ##
# Number of plugs of each net :
# if equal to 0 : del net
# if equal to 1 : put net in the file
for net in net_interne :
nb_plugs = self.count_plugs ( net )
if nb_plugs == 0 :
if interactive : print "* One net suppressed (a) :", net
TAB_NETS.append ( net.getName () )
cpt_net_del += 1
net.Delete()
elif nb_plugs == 1 :
if net.getPlugs().next().getMasterNet().getDirection() == DirectionOUT: # output of an instance
if interactive : print "* One net put in the fifo :", net
file.insert ( 0, net )
## Ouput nets ##
# Number of plugs of each net :
# if equal to 0 : del net
for net in net_sortie + net_entree :
cpt_plugs_sor = self.count_plugs ( net )
if cpt_plugs_sor == 0 :
print "[Stratus Warning] Clean : Interface of", self._name, "changed, net :", net, "is suppressed"
TAB_NETS.append ( net.getName() )
cpt_net_del += 1
net.Delete()
##### Algorithm #####
while len ( file ) > 0 :
net_file = file.pop()
plug = net_file.getPlugs().next()
inst = plug.getInstance()
# input nets of the instance
plugs_inst = inst.getPlugs()
net_entree_inst = []
net_sortie_inst = []
cpt_sortie = 0
for plug_de_inst in plugs_inst:
# compute the number of outputs of the instance
if plug_de_inst.getMasterNet().getDirection() == DirectionOUT :
cpt_sortie += 1
# output nets of the instance put in tab, except for the net being worked on
if net_file != plug_de_inst.getNet() : net_sortie_inst.append ( plug_de_inst.getNet() )
if plug_de_inst.getMasterNet().getDirection() == DirectionIN :
# ignore vdd and vss
type = plug_de_inst.getNet().getType()
if type not in ( Net.Type.POWER, Net.Type.GROUND ) : net_entree_inst.append ( plug_de_inst.getNet() )
### Deletion of te instance ###
# If the instance has only one output
if cpt_sortie == 1 :
if interactive : print "* One net suppressed (b) :", net_file
TAB_NETS.append ( net_file.getName() )
cpt_net_del += 1
net_file.Delete()
if interactive : print "* One instance suppressed (a) :", inst, inst
TAB_INSTS.append(inst.getName())
cpt_inst_del += 1
UpdateSession.open()
inst.Delete()
UpdateSession.close()
for net_ent in net_entree_inst :
cpt_plugs_in = self.count_plugs ( net_ent )
if cpt_plugs_in == 0 :
if net_ent in net_entree :
print "[Stratus Warning] Clean : Interface of", self._name, "changed, net :", net_ent, "is suppressed"
TAB_NETS.append ( net_ent.getName() )
cpt_net_del += 1
net_ent.Delete()
else :
if interactive : print "* One net suppressed (c) : ", net_ent
TAB_NETS.append ( net_ent.getName() )
cpt_net_del += 1
net_ent.Delete()
elif cpt_plugs_in == 1 :
if net_ent.getPlugs().next().getMasterNet().getDirection() == DirectionOUT : # is an output net of another instance
if interactive : print "* One net put in the fifo :", net_ent
file.insert ( 0, net_ent )
# If the instance has more than one output
elif cpt_sortie >= 2 :
connect = False
for net_sor in net_sortie_inst:
cpt_sor = self.count_plugs ( net_sor )
if cpt_sor >= 2 :
connect = True # at least one output connected
break
elif cpt_sor == 1 :
if net_sor in net_sortie :
connect = True # at least one output connected
break
if not ( connect ) :
if interactive : print "* One net suppressed (d) :", net_file
TAB_NETS.append ( net_file.getName() )
cpt_net_del += 1
net_file.Delete()
for net_sor in net_sortie_inst :
if net_sor in file : file.remove ( net_sor )
if interactive : print "* One net suppressed (e) :", net_sor
TAB_NETS.append ( net_sor.getName() )
cpt_net_del += 1
net_sor.Delete()
if interactive : print "* One instance suppressed (b) :", inst
TAB_INSTS.append ( inst.getName() )
cpt_inst_del += 1
UpdateSession.open()
inst.Delete()
UpdateSession.close()
for net_ent in net_entree_inst :
cpt_plugs_in = self.count_plugs ( net_ent )
if cpt_plugs_in == 0 :
if net_ent in net_entree :
print "[Stratus Warning] Clean : Interface of", self._name, "changed, net :", net_ent, "is suppressed"
TAB_NETS.append ( net_ent.getName() )
cpt_net_del += 1
net_ent.Delete()
else :
if interactive : print "* One net suppressed (f) :", net_ent
TAB_NETS.append ( net_ent.getName() )
cpt_net_del += 1
net_ent.Delete()
elif cpt_plugs_in == 1 :
if net_ent.getPlugs().next().getMasterNet().getDirection() == DirectionOUT: # in an output net of another instance
if interactive : print "* One net net put in the fifo :", net_ent
file.insert ( 0, net_ent )
else :
if interactive : print "The net", net_file, "can not be delayed, it may be delayed later"
else :
print "[Warning] Pb in Clean."
if interactive :
print ""
print "* Number of net suppressed :", cpt_net_del
print "* List of these nets :", TAB_NETS
print ""
print "* Number of instances suppressed :", cpt_inst_del
print "* List of these instance :", TAB_INSTS
print ""
###############################
def count_plugs ( self, net ) :
return len(net.getPlugs())
#############################################################################
############################## Place and route ##############################
#############################################################################
#def getCore ( self ) :
# '''This function returns the instance "core" : the only one which is not a pad'''
# from placeandroute import isPad
# cores = []
# for instance in self._hur_cell.getInstances():
# if not isPad ( instance ):
# cores.append ( instance )
# if len(cores) == 0 : err = "\n[Stratus ERROR] getCore : No core found.\n"
# elif len(cores) > 1 : err = "\n[Stratus ERROR] getCore : More than one core found.\n"
# if len(cores) != 1 : raise Exception ( err )
# return cores[0]