2010-07-12 10:33:22 -05:00
#!/usr/bin/python
#
2012-12-03 02:31:26 -06:00
# This file is part of the Coriolis Software.
# Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved
2010-07-12 10:33:22 -05:00
#
2012-12-03 02:31:26 -06:00
# +-----------------------------------------------------------------+
2010-07-12 10:33:22 -05:00
# | C O R I O L I S |
2012-12-03 02:31:26 -06:00
# | S t r a t u s - Netlists/Layouts Description |
2010-07-12 10:33:22 -05:00
# | |
# | Author : Sophie BELLOEIL |
# | E-mail : Sophie.Belloeil@asim.lip6.fr |
# | =============================================================== |
# | Py Module : "./st_model.py" |
2012-12-03 02:31:26 -06:00
# +-----------------------------------------------------------------+
2010-07-12 10:33:22 -05:00
2012-12-03 02:31:26 -06:00
import re
import types
import string
import Cfg
2010-07-12 10:33:22 -05:00
import CRL
2010-11-16 08:09:53 -06:00
import Viewer
2012-12-03 02:31:26 -06:00
from Hurricane import *
2010-07-12 10:33:22 -05:00
2012-03-09 01:50:55 -06:00
2010-07-12 10:33:22 -05:00
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 #####
#######################
2017-08-02 03:38:48 -05:00
class Model ( ) :
2010-07-12 10:33:22 -05:00
##########################
##### Initialisation #####
##########################
def __init__ ( self , nom , param = { } , hurCell = None , hurricane_plug = True ) :
global FRAMEWORK , CELLS
2010-09-06 04:12:24 -05:00
# Look up the editor
if globals ( ) . has_key ( " __editor " ) : setEditor ( __editor )
2010-07-12 10:33:22 -05:00
self . _name = nom
self . _param = param
2012-03-09 01:50:55 -06:00
self . pat = None
2010-07-12 10:33:22 -05:00
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()
2010-07-17 05:34:21 -05:00
FRAMEWORK = CRL . AllianceFramework . get ( )
2010-07-12 10:33:22 -05:00
self . _st_vdds = [ ]
self . _st_vsss = [ ]
if hurCell :
from st_net import VddInFromHur
from st_net import VssInFromHur
2010-09-06 04:12:24 -05:00
try :
netVdd = iter ( hurCell . getPowerNets ( ) ) . next ( )
2010-09-06 06:22:30 -05:00
self . _st_vdds . append ( VddInFromHur ( netVdd ) )
2010-09-06 04:12:24 -05:00
except StopIteration :
print " [Stratus Warning] : Cell " , self . _name , " does not have a vdd port. "
pass
try :
netVss = iter ( hurCell . getGroundNets ( ) ) . next ( )
2010-09-06 06:22:30 -05:00
self . _st_vsss . append ( VssInFromHur ( netVss ) )
2010-09-06 04:12:24 -05:00
except StopIteration :
print " [Stratus Warning] : Cell " , self . _name , " does not have a vss port. "
pass
2010-07-12 10:33:22 -05:00
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 :
2010-07-22 09:33:55 -05:00
err = " \n Error : no cell found with model %s . \n " % model
raise Exception ( err )
2010-07-12 10:33:22 -05:00
# Hurricane cell found:
if hurCell :
found = False
2011-02-16 07:59:03 -06:00
for net in hurCell . getExternalNets ( ) :
2010-07-12 10:33:22 -05:00
direction = net . getDirection ( )
name = str ( net . getName ( ) )
2016-11-10 03:34:34 -06:00
if net . getType ( ) in ( Net . Type . POWER , Net . Type . GROUND , Net . Type . CLOCK ) :
2010-07-12 10:33:22 -05:00
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 "
2010-07-22 09:33:55 -05:00
else :
err = " \n Error : unable to find direction of port %s in model %s . Direction is %d \n " % ( pin , model , direction )
raise Exception ( err )
2010-07-12 10:33:22 -05:00
2010-07-22 09:33:55 -05:00
if not found :
err = " \n Error : unable to find port %s in model %s . \n " % ( pin , model )
raise Exception ( err )
2010-07-12 10:33:22 -05:00
# 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 "
2010-07-22 09:33:55 -05:00
else :
err = " \n Error : unable to find direction of port %s in model %s . \n " % ( pin , model )
raise Exception ( err )
2010-07-12 10:33:22 -05:00
if not found :
ports = " "
for net in stCell . _st_ports : ports + = net . _name + " , "
2010-07-22 09:33:55 -05:00
err = " \n Error : unable to find port %s in model %s . \n Ports are : %s \n " % ( pin , model , ports )
raise Exception ( err )
2010-07-12 10:33:22 -05:00
else :
err = " \n [ERROR] InitGraph : no model named " + model + " in the database. \n "
2010-07-22 09:33:55 -05:00
raise Exception ( err )
2010-07-12 10:33:22 -05:00
#############################
##### 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
2010-11-16 08:09:53 -06:00
#############################
##### Find An Instance #####
#############################
def getInstance ( self , name ) :
for instance in self . _st_insts :
if instance . _name == name :
return instance
return None
2010-07-12 10:33:22 -05:00
#########################
def PrintGraph ( self ) :
if " _graph " not in self . __dict__ :
err = " \n [Stratus ERROR] PrintGraph : The graph does not exist. Use initGraph before. \n "
2010-07-22 09:33:55 -05:00
raise Exception ( err )
2010-07-12 10:33:22 -05:00
else :
if self . _graph == False :
err = " \n [Stratus ERROR] PrintGraph : The graph does not exist. Use initGraph before. \n "
2010-07-22 09:33:55 -05:00
raise Exception ( err )
2010-07-12 10:33:22 -05:00
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 #####
2011-02-16 07:59:03 -06:00
def View ( self , stopLevel = 1 , message = " Status stop point " ) :
2010-07-12 10:33:22 -05:00
global EDITOR
if not self . _hur_cell :
err = " \n [Stratus ERROR] View : Hurricane Cell does not exist. \n Check CRL_IN_LO/CRL_IN_PH variables. \n "
2010-07-22 09:33:55 -05:00
raise Exception ( err )
2010-07-12 10:33:22 -05:00
if EDITOR :
EDITOR . setCell ( self . _hur_cell )
EDITOR . fit ( )
2012-11-16 06:56:08 -06:00
if stopLevel > 0 :
Breakpoint . stop ( stopLevel , message )
2010-07-12 10:33:22 -05:00
##### Save : in order to create the output files #####
def Save ( self , views = 0 , fileName = None ) :
global FRAMEWORK
global CELLS
2012-12-03 02:31:26 -06:00
netlistFormat = Cfg . getParamString ( ' stratus1.format ' ) . asString ( )
2010-07-12 10:33:22 -05:00
if views == STRATUS :
self . exportStratus ( fileName )
2017-08-02 03:38:48 -05:00
elif netlistFormat == ' vst ' :
2010-07-12 10:33:22 -05:00
UpdateSession . open ( )
hurCell = self . _hur_cell
if str ( hurCell . getName ( ) ) != " __Scratch__ " :
2017-08-02 03:38:48 -05:00
FRAMEWORK . saveCell ( hurCell , views | CRL . Catalog . State . Logical )
2010-07-12 10:33:22 -05:00
if len ( CELLS ) == 0 :
err = " \n [Stratus ERROR] Save : CELLS stack is empty. \n "
2010-07-22 09:33:55 -05:00
raise Exception ( err )
2010-07-12 10:33:22 -05:00
CELLS . pop ( )
UpdateSession . close ( )
2012-12-03 02:31:26 -06:00
elif netlistFormat == ' stratus ' :
2012-03-09 01:50:55 -06:00
self . exportStratus ( fileName )
2017-08-02 03:38:48 -05:00
elif netlistFormat in [ ' vhd ' , ' vlog ' , ' json ' ] :
self . export ( netlistFormat )
2012-03-09 01:50:55 -06:00
else :
2012-12-03 02:31:26 -06:00
raise Exception ( ' Unrecognized format %s ' % netlistFormat )
2012-03-09 01:50:55 -06:00
2010-07-12 10:33:22 -05:00
##### Simul : in order to use simulation tool #####
def Simul ( self , name = None , tool = ' asimut ' ) :
from utils import runpat
if not name : name = self . _name
2012-12-03 02:31:26 -06:00
simulator = Cfg . getParamString ( ' stratus1.simulator ' ) . asString ( )
if simulator == ' asimut ' :
2012-08-20 03:29:31 -05:00
runpat ( self . _name , name , ' -l 1 -p 100 -zerodelay -bdd ' )
2012-12-03 02:31:26 -06:00
elif simulator == ' ghdl ' :
2012-03-09 01:50:55 -06:00
import os
cmd_str = ( ' ghdl -c -g -Psxlib --ieee=synopsys *.vhd -r %s _run --vcd= %s .vcd ' % ( name , name ) )
os . system ( cmd_str )
2012-08-20 03:29:31 -05:00
elif tool == ' asimut ' : runpat ( self . _name , name , ' -l 1 -p 100 -zerodelay -bdd ' )
2010-07-22 09:33:55 -05:00
else : raise Exception ( ' not implemented yet ' )
2010-07-12 10:33:22 -05:00
2012-03-09 01:50:55 -06:00
##### TestBench : in order to create testbench #####
def Testbench ( self ) :
2012-12-03 02:31:26 -06:00
netlistFormat = Cfg . getParamString ( ' stratus1.format ' ) . asString ( )
2012-03-09 01:50:55 -06:00
import stimuli
stim = stimuli . Stimuli ( self )
2012-12-03 02:31:26 -06:00
if netlistFormat == ' vhd ' :
2012-03-09 01:50:55 -06:00
# 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 )
2012-12-03 02:31:26 -06:00
elif netlistFormat == ' vst ' :
2012-03-09 01:50:55 -06:00
stim . create_pat_file ( )
else :
2012-12-03 02:31:26 -06:00
raise Exception ( ' Testbench not yet implemented for format %s ' % netlistFormat )
2012-03-09 01:50:55 -06:00
2010-07-12 10:33:22 -05:00
##### 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 ( )
2012-03-09 01:50:55 -06:00
2017-08-02 03:38:48 -05:00
##### 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 )
2012-03-09 01:50:55 -06:00
##### 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 ( " \n begin \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 ( )
2010-07-12 10:33:22 -05:00
#### 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 :
2010-07-22 09:33:55 -05:00
err = " \n [Stratus ERROR] Inst : instanciation of a user ' s defined generator. The methods ' arguments must be dictionnaries. \n "
raise Exception ( err )
2010-07-12 10:33:22 -05:00
##### Creation of the instance #####
2019-10-25 04:20:15 -05:00
# dict['flags'] = F_MSB_FIRST # When vst driver permits to do F_LSB_FIRST or F_LSB_FIRST TODO
# dict['flags'] = 0
2010-07-12 10:33:22 -05:00
## 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 )
2012-08-16 12:17:21 -05:00
2010-07-12 10:33:22 -05:00
# Roselyne : pour prendre en compte les modeles recursifs
2012-08-16 12:17:21 -05:00
#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 )
2010-07-12 10:33:22 -05:00
# 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 ( )
2016-11-10 03:34:34 -06:00
if type not in ( Net . Type . POWER , Net . Type . GROUND ) : net_entree_inst . append ( plug_de_inst . getNet ( ) )
2010-07-12 10:33:22 -05:00
### 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 ##############################
#############################################################################
2015-03-17 16:50:00 -05:00
#def getCore ( self ) :
# '''This function returns the instance "core" : the only one which is not a pad'''
2010-07-12 10:33:22 -05:00
2015-03-17 16:50:00 -05:00
# from placeandroute import isPad
2010-07-12 10:33:22 -05:00
2015-03-17 16:50:00 -05:00
# cores = []
# for instance in self._hur_cell.getInstances():
# if not isPad ( instance ):
# cores.append ( instance )
2010-07-12 10:33:22 -05:00
2015-03-17 16:50:00 -05:00
# 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 )
2010-07-12 10:33:22 -05:00
2015-03-17 16:50:00 -05:00
# return cores[0]