coriolis/stratus1/src/stratus/st_net.py

1194 lines
44 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_net.py" |
# | *************************************************************** |
# | U p d a t e s |
# | |
# x-----------------------------------------------------------------x
import CRL
from Hurricane import *
from st_model import Model
from st_instance import Inst
from st_generate import Generate
import re, types, inspect
## Class of nets ##
PORT = ( "st_net.SignalIn", "st_net.SignalOut", "st_net.SignalInOut" \
, "st_net.SignalUnknown", "st_net.TriState" \
)
#####################
##### Class net #####
#####################
class net :
# Creation of the instance : coded for each herited class
def __init__ ( self, nbit ) : pass
# Deletion of the instance : the same for each net
def Delete ( self ) :
# Erasement of the references to the net
if str ( self.__class__ ) in PORT :
for i in range ( len ( self._st_cell._st_ports ) ) :
if self._st_cell._st_ports[i] == self :
del self._st_cell._st_ports[i]
break
else :
for i in range ( len ( self._st_cell._st_sigs ) ) :
if self._st_cell._st_sigs[i] == self :
del self._st_cell._st_sigs[i]
break
for net in self._st_cell._st_sigs :
if "_to_merge" in net.__dict__ :
if len ( net._to_merge ) :
for i in range ( len ( net._to_merge ) ):
if net._to_merge[i] != 0 :
if net._to_merge[i][0] == self : net._to_merge[i] = 0 # Erasement of a reference of the net
non = False
# Erasement of the net which wes going to be merged to the net being deleted
for i in range ( len ( net._to_merge ) ) :
if net._to_merge[i] != 0 :
non = True
break
if not non : net.Delete()
# Erasement in the connections
for inst in self._st_cell._st_insts :
for pin in inst._map :
if self == inst._map[pin] :
del inst._map[pin]
break
# Erasement of the huricane nets associated
for hurNet in self._hur_net :
if hurNet : hurNet.Delete()
##### For buses #####
def __getitem__ ( self, indice ) :
if indice == -1:
return Sig ( self, self._ind + self._arity - 1 )
if ( indice < self._ind ) or ( indice >= ( self._ind + self._arity ) ) :
err = "\n[Stratus ERROR] [] : bad index " + str(indice) + " for net : " \
+ self._name + " of arity " + str(self._arity)
if self._ind != 0 : err += " and LSB " + str(self._ind)
err += ".\n"
raise Exception ( err )
return Sig ( self, indice )
def __getslice__ ( self, ind1, ind2 ) :
if ind1 < ind2 :
indmin = ind1
indmax = ind2
else :
indmin = ind2
indmax = ind1
# Errors
if ( (indmax-indmin) < 1 ) or ( (indmax-indmin) > self._arity ) :
err = "\n[Stratus ERROR] [:] : bad indexes " + str(indmax) + ", and " + str(indmin) \
+ " for net : " + self._name + " of arity " + str(self._arity)
if self._ind != 0 : err += " and LSB " + str(self._ind)
err += ".\n"
raise Exception ( err )
if ( indmax >= ( self._ind + self._arity ) ) or ( indmin < self._ind ) :
err = "\n[Stratus ERROR] [:] : bad indexes " + str(indmax) + ", and " + str(indmin) \
+ " for net : " + self._name + " of arity " + str(self._arity)
if self._ind != 0 : err += " and LSB " + str(self._ind)
err += ".\n"
raise Exception ( err )
return Sig ( self, ind1, ind2 )
##### To affect a signal : <= #####
def __le__ ( self, net ) :
global CELLS
from st_model import CELLS
cell = CELLS[-1]
### Initialisation of net representing a constant ###
if type ( net ) == types.StringType :
from st_const import Constant
if not ( cell._st_vdds ) or not ( cell._st_vsss ) :
err = "\n[Stratus ERROR] : there is no alim.\n"
raise Exception ( err )
constParam = { 'nb' : net }
string = Constant.getString ( constParam )
num_net = len ( cell._TAB_NETS_OUT )
cell._TAB_NETS_OUT += [Signal ( "cst_o%d" % num_net, len ( string ) )]
# 3 possible constant operator output name (nq,q,output) => 3 differents map
if string == "0" :
inst_name = "zero"
map_cst = { 'nq' : cell._TAB_NETS_OUT[num_net]
, 'vdd': cell._st_vdds[0]
, 'vss': cell._st_vsss[0]
}
elif string == "1" :
inst_name = "one"
map_cst = { 'q' : cell._TAB_NETS_OUT[num_net]
, 'vdd': cell._st_vdds[0]
, 'vss': cell._st_vsss[0]
}
else :
inst_name = Constant.getModelName ( constParam )
map_cst = { 'o': cell._TAB_NETS_OUT[num_net]
, 'vdd': cell._st_vdds[0]
, 'vss': cell._st_vsss[0]
}
Generate ( "Constant", inst_name, param = constParam )
Inst ( inst_name
, map = map_cst
)
net = cell._TAB_NETS_OUT[num_net]
### Merging of two nets ###
# Resizement of the output net if needed thanks to the input net's lenght
if not ( self._arity ) : self.create_net ( self._name, net._arity )
# Error if the nets don t have the same size
if self._arity - net._arity :
err = "\n[Stratus ERROR] <= : the nets " + self._name + " " + str(self._arity) + " and " + net._name + " " + str(net._arity) \
+ " must have the same lenght\n"
raise Exception ( err )
# If the nets are virtual, Let s work with the corresponding real nets
if self._real_net : netInCell = self._real_net
else : netInCell = self
if net._real_net : netToMerge = net._real_net
else : netToMerge = net
# Error if self is an input net
if ( netInCell._ext ) and ( netInCell._direct == "IN" ) :
err = "\n[Stratus ERROR] <= : " + self._name + " One can not give a value to an input net.\n"
raise Exception ( err )
if netToMerge._ext :
err = "\n[Stratus ERROR] <= : " + self._name
# Error if net is an output net
if netToMerge._direct == "OUT" : err += " One can not initialise a net with an output net.\n"
# Error if net is an input net
elif netToMerge._direct == "IN" : err += " One can not initialise a net with an input net. The method Buffer() should be used.\n"
raise Exception ( err )
# Construction of the tab if needed
if not ( len ( netToMerge._to_merge ) ) :
for i in range ( netToMerge._arity ) : netToMerge._to_merge.append ( 0 )
# Initialisation of _to_merge
for i in range ( net._arity ) : netToMerge._to_merge[i+net._ind] = [netInCell, i+self._ind]
# Puts the net in the list of nets to merge in order to have them in the right order
self._st_cell._st_merge.append ( net )
if self._st_cell._hur_cell :
net.hur_merge()
#for i in range ( net._arity ) :
# CRL.createPartRing ( self._st_cell._hur_cell, netInCell._hur_net[i+self._ind].getName() ) # FIXME plante avec le adder mixed dans un cas particulier indetermine ....
##### Instanciation of a buffer #####
def Buffer ( self ) :
global CELLS
from st_model import CELLS
cell = CELLS[-1]
if not ( cell._st_vdds ) or not ( cell._st_vsss ) :
err = "\n[Stratus ERROR] : there is no alim.\n"
raise Exception ( err )
# Creation of the output net with the right size
num_net = len ( cell._TAB_NETS_OUT )
cell._TAB_NETS_OUT += [Signal ( "buf_o%d" % num_net, self._arity )]
buffMap = { 'q' : cell._TAB_NETS_OUT[num_net]
, 'vdd' : cell._st_vdds[0]
, 'vss' : cell._st_vsss[0]
}
if self._st_cell._buff == 'DpgenBuff' : buffMap['i0'] = self
else : buffMap['i'] = self
# if ( self._st_cell._buff == "Buf" ) and ( self._arity == 1 ) :
# inst_name = self._st_cell._buff.lower()
# else :
inst_name = self._st_cell._buff.lower()
inst_name = re.sub ( "\.", "_", inst_name )
inst_name += "_"
inst_name += str(self._arity)
Generate ( self._st_cell._buff, inst_name, param = { 'nbit' : self._arity } )
Inst ( inst_name, map = buffMap )
return cell._TAB_NETS_OUT[num_net]
##### Boolean operators #####
def __and__ ( self, other_net ) : return self.bool ( other_net, self._st_cell._and )
def __or__ ( self, other_net ) : return self.bool ( other_net, self._st_cell._or )
def __xor__ ( self, other_net ) : return self.bool ( other_net, self._st_cell._xor )
def bool ( self, other_net, model ) :
global CELLS
from st_model import CELLS
cell = CELLS[-1]
if model == self._st_cell._and : f = "&"
elif model == self._st_cell._or : f = "|"
elif model == self._st_cell._xor : f = "^"
if self._arity - other_net._arity :
err = "\n[Stratus ERROR] " + f + " : the nets " + self._name + " and " + other_net._name + " must have the same lenght.\n"
raise Exception ( err )
# Creation of the output net with the right size
num_net = len ( cell._TAB_NETS_OUT )
cell._TAB_NETS_OUT += [Signal ( "bool_o%d" % num_net, self._arity )]
if not ( cell._st_vdds ) or not ( cell._st_vsss ) :
err = "\n[Stratus ERROR] : there is no alim.\n"
raise Exception ( err )
# if ( model in ( "A2", "O2", "Xr2" ) ) and ( self._arity == 1 ) and ( other_net._arity == 1 ) :
# inst_name = model.lower()
#
# else :
inst_name = model.lower()
inst_name = re.sub ( "\.", "_", inst_name )
inst_name += "_"
inst_name += str(self._arity)
Generate ( model, inst_name, param = { 'nbit' : self._arity } )
Inst ( inst_name
, map = { 'i0' : self
, 'i1' : other_net
, 'q' : cell._TAB_NETS_OUT[num_net]
, 'vdd' : cell._st_vdds[0]
, 'vss' : cell._st_vsss[0]
}
)
return cell._TAB_NETS_OUT[num_net]
def __invert__ ( self ) :
global CELLS
from st_model import CELLS
cell = CELLS[-1]
if not ( cell._st_vdds ) or not ( cell._st_vsss ) :
err = "\n[Stratus ERROR] : there is no alim.\n"
raise Exception ( err )
# Creation of the output net with the right size
num_net = len ( cell._TAB_NETS_OUT )
cell._TAB_NETS_OUT += [Signal ( "inv_o%d" % num_net, self._arity )]
invMap = { 'nq' : cell._TAB_NETS_OUT[num_net]
, 'vdd' : cell._st_vdds[0]
, 'vss' : cell._st_vsss[0]
}
if self._st_cell._not == 'DpgenInv' : invMap['i0'] = self
else : invMap['i'] = self
# if ( self._st_cell._not == "Inv" ) and ( self._arity == 1 ) :
# inst_name = self._st_cell._not.lower()
# else :
inst_name = self._st_cell._not.lower()
inst_name = re.sub ( "\.", "_", inst_name )
inst_name += "_"
inst_name += str(self._arity)
Generate ( self._st_cell._not, inst_name, param = { 'nbit' : self._arity } )
Inst ( inst_name, map = invMap )
return cell._TAB_NETS_OUT[num_net]
##### Arithmetic operators #####
def __add__ ( self, other_net ) : return self.arithgen ( other_net, self._st_cell._add, {'signed' : self._st_cell._signed, 'extended' : self._st_cell._extended} )
def __sub__ ( self, other_net ) : return self.arithgen ( other_net, self._st_cell._sub, {'signed' : self._st_cell._signed, 'extended' : self._st_cell._extended} )
def __mul__ ( self, other_net ) : return self.arithgen ( other_net, self._st_cell._mult, {'signed' : self._st_cell._signed} )
def __div__ ( self, other_net ) : return self.arithgen ( other_net, self._st_cell._div )
def arithgen ( self, other_net, function, parameter = {} ) :
global CELLS
from st_model import CELLS
cell = CELLS[-1]
if not function :
err = "\n[Stratus ERROR] / : to be done.\n"
raise Exception ( err )
if not ( cell._st_vdds ) or not ( cell._st_vsss ) :
err = "\n[Stratus ERROR] there is no alim in cell %s.\n" % str(cell._name)
raise Exception ( err )
# Creation of the output net with the right size
num_net = len ( cell._TAB_NETS_OUT )
if function == self._st_cell._add :
if self._st_cell._extended :
cell._TAB_NETS_OUT += [Signal ( "add_o%d" % num_net, max ( self._arity, other_net._arity )+1 )]
else:
cell._TAB_NETS_OUT += [Signal ( "add_o%d" % num_net, max ( self._arity, other_net._arity ) )]
elif function == self._st_cell._sub :
if self._st_cell._extended :
cell._TAB_NETS_OUT += [Signal ( "sub_o%d" % num_net, max ( self._arity, other_net._arity )+1 )]
else:
cell._TAB_NETS_OUT += [Signal ( "sub_o%d" % num_net, max ( self._arity, other_net._arity ) )]
elif function == self._st_cell._mult : cell._TAB_NETS_OUT += [Signal ( "mul_o%d" % num_net, self._arity+other_net._arity )]
arithParam = parameter
if not self._st_cell._signed and function == self._st_cell._mult :
name1 = re.sub(r"\[([0-9]+):([0-9]+)\]",r"\1\2", self._name) + "ext"
name2 = re.sub(r"\[([0-9]+):([0-9]+)\]",r"\1\2", other_net._name) + "ext"
i0ext = Signal(name1, self._arity+1)
i1ext = Signal(name2, other_net._arity+1)
i0ext <= self.Extend(self._arity+1, 'zero')
i1ext <= other_net.Extend(other_net._arity+1, 'zero')
arithParam['nbit0'] = self._arity+1
arithParam['nbit1'] = other_net._arity+1
arithMap = { 'i0' : i0ext
, 'i1' : i1ext
, 'o' : cell._TAB_NETS_OUT[num_net]
, 'vdd' : cell._st_vdds[0]
, 'vss' : cell._st_vsss[0]
}
else:
arithParam['nbit0'] = self._arity
arithParam['nbit1'] = other_net._arity
arithMap = { 'i0' : self
, 'i1' : other_net
, 'o' : cell._TAB_NETS_OUT[num_net]
, 'vdd' : cell._st_vdds[0]
, 'vss' : cell._st_vsss[0]
}
inst_name = function.lower()
inst_name = re.sub ( "\.", "_", inst_name )
for p in arithParam : inst_name += "_%s_%s" % ( str(p).lower(), str(arithParam[p]).lower() )
Generate ( function, inst_name, param = arithParam )
Inst ( inst_name, map = arithMap )
return cell._TAB_NETS_OUT[num_net]
##### Shifter #####
def Shift ( self, inputNet, direction, type ) :
global CELLS
from st_model import CELLS
cell = CELLS[-1]
if not inputNet._arity : raise Exception ( "\n[Stratus ERROR] Shift : The input net does not have a positive arity.\n" )
if not self._arity : raise Exception ( "\n[Stratus ERROR] Shift : The command net does not have a positive arity.\n" )
if not ( cell._st_vdds ) or not ( cell._st_vsss ) : raise Exception ( "\n[Stratus ERROR] there is no alim.\n" )
# Wrong parameters :
if direction not in ( "left", "right" ) : raise Exception ( "\n[Stratus ERROR] Shift : The direction parameter must be \"left\" or \"right\".\n" )
if type not in ( "logical", "arith", "circular" ) : raise Exception ( "\n[Stratus ERROR] Shift : The type parameter must be \"logical\" or \"arith\" or \"circular\".\n" )
# Creation of the output net with the right size
num_net = len ( cell._TAB_NETS_OUT )
cell._TAB_NETS_OUT += [Signal ( "sh_o%d" % num_net, inputNet._arity )]
# Initialisation of shiftType
if direction is "left" :
if type is "logical" : shiftType = 0x12
elif type is "arith" : shiftType = 0xa
else : shiftType = 0x6
else :
if type is "logical" : shiftType = 0x11
elif type is "arith" : shiftType = 0x9
else : shiftType = 0x5
inst_name = self._st_cell._shift.lower()
inst_name = re.sub ( "\.", "_", inst_name )
inst_name += "_"
inst_name += type
inst_name += "_"
inst_name += str(inputNet._arity)
Generate ( self._st_cell._shift, inst_name, param = { 'nbit' : inputNet._arity, 'type' : shiftType } )
Inst ( inst_name
, map = { 'cmd' : self
, 'i' : inputNet
, 's' : cell._TAB_NETS_OUT[num_net]
, 'vdd' : cell._st_vdds[0]
, 'vss' : cell._st_vsss[0]
}
)
return cell._TAB_NETS_OUT[num_net]
##### Register #####
def Reg ( self, inputNet ) :
global CELLS
from st_model import CELLS
cell = CELLS[-1]
if not inputNet._arity : raise Exception ( "\n[Stratus ERROR] Reg : The input net does not have a positive arity.\n" )
if not self._arity : raise Exception ( "\n[Stratus ERROR] Reg : The clock does not have a positive arity.\n" )
if not ( cell._st_vdds ) or not ( cell._st_vsss ) : raise Exception ( "\n[Stratus ERROR] there is no alim.\n" )
# Creation of the output net with the right size
num_net = len ( cell._TAB_NETS_OUT )
cell._TAB_NETS_OUT += [Signal ( "reg_o%d" % num_net, inputNet._arity )]
# if ( self._st_cell._reg == "Sff1" ) and ( inputNet._arity == 1 ) :
# inst_name = "sff1"
# else :
# inst_name = self._st_cell._reg.lower()
# inst_name = re.sub ( "\.", "_", inst_name )
# inst_name += "_"
# inst_name += str(inputNet._arity)
#
# Generate ( self._st_cell._reg, inst_name, param = { 'nbit' : inputNet._arity } )
inst_name = self._st_cell._reg.lower()
inst_name = re.sub ( "\.", "_", inst_name )
inst_name += "_"
inst_name += str(inputNet._arity)
Generate ( self._st_cell._reg, inst_name, param = { 'nbit' : inputNet._arity } )
Inst ( inst_name
, map = { 'i' : inputNet
, 'ck' : self
, 'q' : cell._TAB_NETS_OUT[num_net]
, 'vdd' : cell._st_vdds[0]
, 'vss' : cell._st_vsss[0]
}
)
return cell._TAB_NETS_OUT[num_net]
##### Multiplexor #####
def Mux ( self, nets ) :
maxPossibility = pow ( 2, self._arity ) - 1
### List ###
if type ( nets ) == types.ListType :
if len ( nets ) != ( maxPossibility + 1 ) :
raise Exception ( "\n[Stratus ERROR] Mux : when using a list, all the nets must be precised. Maybe one should use a dictionnary.\n" )
return self.muxList ( nets )
### Dictionnary : Creation of the corresponding list ###
elif type ( nets ) == types.DictType :
# Initialisation of the by default to 0 net if no default net given
if "default" not in nets : nets["default"] = 0
# Traitement of lists, intervals and numbers
for net in nets.keys () :
if re.search ( "-", net ) or re.search ( ",", net ) or re.search ( "#", net ) :
chaine = net
while chaine :
interval = re.search ( "^([0-9]+)-([0-9]+)", chaine )
chiffre = re.search ( "^([0-9]+)", chaine )
diese = re.search ( "^#([0-9\?]+)", chaine )
#############
if interval :
nb1 = int ( interval.group(1) )
nb2 = int ( interval.group(2) )
# Error : wrong interval
if nb1 >= nb2 :
raise Exception ( "\n[Stratus ERROR] Mux : when an interval is specified, the second number of the interval must be the greater one.\n" )
# Error : if the interval does not correspond to the lenght of the command
if ( nb1 > maxPossibility ) or ( nb2 > maxPossibility ) :
raise Exception ( "\n[Stratus ERROR] Mux : One key does not match with the arity of the input nets.\n" )
for i in range ( nb1, nb2+1 ) : nets[i] = nets[net]
# Next element
temp = re.search ( "^[0-9]+-[0-9]+,(.+)$", chaine )
if temp : chaine = str ( temp.group(1) )
else : chaine = None
##############
elif chiffre :
if int ( chiffre.group(0) ) > maxPossibility :
raise Exception ( "\n[Stratus ERROR] Mux : One key does not match with the arity of the input nets.\n" )
nets[int(chiffre.group(0))] = nets[net]
# Next element
temp = re.search ( "^[0-9]+,(.+)$", chaine )
if temp : chaine = str ( temp.group(1) )
else : chaine = None
############
elif diese :
binaire = diese.group ( 1 )
# Error : if the binary number does not correspond to the lenght of the command
if len ( binaire ) != self._arity :
err = "\n[Stratus ERROR] Mux : the binary number " + str(binaire) \
+ " does not match with the lenght of the command. It has to be a " + str(self._arity) + "bits number.\n"
raise Exception ( err )
# Error : if the number is not binary
for n in binaire :
if n not in ( "0", "1", "?", "#" ) :
err = "\n[Stratus ERROR] Mux : after #, the number has to be binary.\n"
raise Exception ( err )
nombrebit = self._arity
nb = 0
for i in range ( -1, -nombrebit - 1, -1 ) :
if binaire[i] == "1" : nb += pow ( 2, -i - 1 )
nombres = []
premierpassage = 1
for i in range ( -1, -nombrebit - 1, -1 ) :
if binaire[i] == "?" :
if premierpassage :
nombres += [nb]
nombres += [nb + pow ( 2, -i - 1 )]
premierpassage = 0
else :
enplus = []
for chaquenombre in nombres : enplus += [chaquenombre + pow ( 2, -i - 1 )]
nombres += enplus
for chaquenombre in nombres : nets[chaquenombre] = nets[net]
# Next element
temp = re.search ( "^#.*,(.+)$", chaine )
if temp : chaine = str ( temp.group (1) )
else : chaine = None
else :
err = "\n[Stratus ERROR] Mux : wrong key.\n"
raise Exception ( err )
del nets[net]
# Otherwise it must be a number :
elif re.search ( "^[0-9]+$", net ) :
chaine = re.search ( "^([0-9]+)$", net )
chiffre = str ( chaine.group ( 1 ) )
if int ( chiffre ) > maxPossibility :
err = "\n[Stratus ERROR] Mux : One key does not match with the arity of the input nets.\n"
raise Exception ( err )
nets[int(chiffre)] = nets[chiffre]
del nets[chiffre]
else :
if net != "default" :
err = "\n[Stratus ERROR] Mux : wrong key.\n"
raise Exception ( err )
clefs = nets.keys ()
clefs.sort ()
# Covering of the keys wich are not default
lenClefs = 0
for c in clefs :
if c != "default" : lenClefs += 1
liste = []
decalage = 0
for i in range ( lenClefs ) :
nb = clefs[i]
nb2 = i + decalage
if nb2 < nb :
while nb2 < nb :
liste.append ( nets["default"] )
nb2 += 1
decalage += 1
liste.append ( nets[clefs[i]] ) # it is the right one
else :
liste.append ( nets[clefs[i]] )
# Number of wanted nets :
lenList = pow ( 2, self._arity )
# If nets are missing theu are default nets
while len ( liste ) < lenList : liste.append ( nets["default"] )
# Creation of the list corresponding to the dictionnary
return self.muxList ( liste )
# Error : wrong argument
else :
err = "\n[Stratus ERROR] Mux : wrong argument type.\n"
raise Exception ( err )
### List ###
def muxList ( self, nets ) :
global CELLS
from st_model import CELLS
cell = CELLS[-1]
if not ( cell._st_vdds ) or not ( cell._st_vsss ) : raise Exception ( "\n[Stratus ERROR] : there is no alim.\n" )
long = 0
for i in range ( len ( nets ) ) :
if nets[i] : long = nets[i]._arity
# Error : if no input net
if not ( long ) : raise Exception ( "\n[Stratus ERROR] Mux : there are no input nets.\n" )
# Instanciation of a zero cell if needed
for net in nets :
if net == 0 :
from st_const import Zero
num_net = len ( cell._TAB_NETS_OUT )
cell._TAB_NETS_OUT += [Signal ( "sig0_%d" % num_net, long )]
cell._TAB_NETS_OUT[num_net] <= Zero ( long )
break
# Creation of the map
map_mux = { 'cmd' : self
, 'vdd' : cell._st_vdds[0]
, 'vss' : cell._st_vsss[0]
}
i = 0
for net in nets :
if net : map_mux['i%d' % i] = net
else : map_mux['i%d' % i] = cell._TAB_NETS_OUT[num_net]
i += 1
# Initialisation of the output net
num_net = len ( cell._TAB_NETS_OUT )
cell._TAB_NETS_OUT += [Signal ( "net_out_%d" % num_net, long )]
map_mux ['q'] = cell._TAB_NETS_OUT[num_net]
inst_name = self._st_cell._mux.lower()
inst_name = re.sub ( "\.", "_", inst_name )
inst_name += "_"
inst_name += str(long)
inst_name += "_"
inst_name += str(self._arity)
Generate ( self._st_cell._mux, inst_name, param = { 'nbit' : long, 'nbit_cmd' : self._arity } )
Inst ( inst_name, map = map_mux )
return cell._TAB_NETS_OUT[num_net]
##### Comparison functions #####
def Eq ( self, nb ) : return self.comparaison ( nb, True )
def Ne ( self, nb ) : return self.comparaison ( nb, False )
# TODO : it could work with un string representing binary, decimal, or hexadecimal
def comparaison ( self, nb, egal ) :
global CELLS
from st_model import CELLS
cell = CELLS[-1]
if not ( cell._st_vdds ) or not ( cell._st_vsss ) : raise Exception ( "\n[Stratus ERROR] : threre is no alim.\n" )
# Initialisation of the output net
num_net = len ( cell._TAB_NETS_OUT )
cell._TAB_NETS_OUT += [Signal ( "net_out_%d" % num_net, 1 )]
inst_name = self._st_cell._comp.lower()
inst_name = re.sub ( "\.", "_", inst_name )
inst_name += "_"
inst_name += str(self._arity)
inst_name += "_"
inst_name += str(nb)
if egal : inst_name += "eq"
Generate ( self._st_cell._comp, inst_name, param = { 'nbit' : self._arity, 'nb' : nb, 'egal' : egal } )
Inst ( inst_name
, map = { "netin" : self
, "netout" : cell._TAB_NETS_OUT[num_net]
, 'vdd' : cell._st_vdds[0]
, 'vss' : cell._st_vsss[0]
}
)
return cell._TAB_NETS_OUT[num_net]
##### Method Alias #####
def Alias ( self, net ) :
# Error : if the net already has an alias
if net._alias :
err = "\n[Stratus ERROR] Alias : the net " + net._name + " is already an alias.\n"
raise Exception ( err )
# Resizement of the net if needed
if not ( net._arity ) : net.create_net ( net._name, self._arity )
# Error : if the nets don't have the same lenght
if self._arity != net._arity :
err = "\n[Stratus ERROR] Alias : the nets " + self._name + " and " + net._name + " must have the same lenght\n"
raise Exception ( err )
# If nets are virtual, let's work with the corresponding real nets
if net._real_net : realNet = net._real_net
else : realNet = net
if self._real_net : realSelf = self._real_net
else : realSelf = self
# Construction of the tab if needed
if not ( len ( realNet._alias ) ) :
for i in range ( realNet._arity ) : realNet._alias.append ( 0 )
# Initialisation of _alias
for i in range ( net._ind, net._ind + net._arity ) :
if not realSelf._alias :
realNet._alias[i] = {realSelf : i + self._ind - net._ind}
# Alias of an alias
else :
err = "\n[Stratus ERROR] Alias : 2 Alias in a row are not supported.\n"
raise Exception ( err )
# FIXME bug : for now, Alias of Alias are not permitted
# if realSelf._alias[i + self._ind - net._ind] :
# netAlias = realSelf._alias[i + self._ind - net._ind].keys()[0]
# bitAlias = realSelf._alias[i + self._ind - net._ind][netAlias]
# if netAlias._real_net : netAlias = netAlias._real_net
# realNet._alias[i] = {netAlias : bitAlias}
# # Error : more than 2 Alias in a row not supported
# if netAlias._alias :
# err = "\n[Stratus ERROR] Alias : more than 2 Alias in a row are not supported.\n"
# raise err
# else :
# realNet._alias[i] = {realSelf : i + self._ind - net._ind}
##### Method Extend #####
def Extend ( self, width, type ) :
global CELLS
from st_model import CELLS
from st_const import Zero, One
cell = CELLS[-1]
if self._arity >= width :
err = "\n[Stratus ERROR] Extend : the net " + self._name + \
" can not be extended to " + str(width) + " bits, it's arity is already " + str(self._arity) + ".\n"
raise Exception ( err )
num_net = len ( cell._TAB_NETS_OUT )
cell._TAB_NETS_OUT += [Signal ( "%s_ext_%d_%d" % ( self._name, width, num_net ), width )]
name = "extend_%d_%d_%s" % ( self._arity, width, type )
Generate ( "Extend", name, param = { 'nbit0' : self._arity, 'nbit1' : width, 'type' : type } )
Inst ( name
, map = { 'i' : self
, 'o' : cell._TAB_NETS_OUT[num_net]
, 'vdd' : cell._st_vdds[0]
, 'vss' : cell._st_vsss[0]
}
)
return cell._TAB_NETS_OUT[num_net]
##################################################################################################################################
##### Initialisation of nets #####
def create_net ( self, nom, nbit, indice = 0, extern = False, direction = None, hType = None ) :
global CELLS
from st_model import CELLS
cell = CELLS[-1]
# Error :
if re.search ( "[A-Z]", nom ) :
print "[Stratus Warning] : Upper case letters are not supported, the name", nom, "is lowered."
nom = nom.lower ()
if re.search ( " ", nom ) :
chaine = re.search ( "st_net\.(.*)", str ( self.__class__ ) )
classe = chaine.group(1)
err = "\n[Stratus ERROR] " + classe + " : \"" + nom + "\" the name of the net can not contain a space.\n"
raise Exception ( err )
self._st_cell = cell
self._name = nom
self._arity = nbit
self._ind = indice
self._hur_net = []
self._alias = []
self._to_merge = []
self._to_cat = []
self._real_net = None
self._ext = extern
self._h_type = hType
if extern : self._direct = direction
# Error :
if ( nbit == 1 ) and indice :
err = "\n[Stratus ERROR] " + str ( self.__class__ ) + " : " + self._name + " : one can not put an indice for a 1 bit net.\n"
raise Exception ( err )
if hType :
if hType == "POWER" : self._st_cell._st_vdds.append ( self )
elif hType == "GROUND" : self._st_cell._st_vsss.append ( self )
elif hType == "CLOCK" : self._st_cell._st_cks.append ( self )
# The net is put in the nets list of the cell
else :
if nbit :
if extern : self._st_cell._st_ports.append ( self )
else : self._st_cell._st_sigs.append ( self )
# Creation of the hurricane net if in hurricane mode
if self._st_cell._hur_cell : self.create_hur_net()
##### Initialisation of the hurricane nets for part nets #####
def create_part_hur_net ( self ) :
if self._ind2 < self._ind : pas = -1
else : pas = 1
if self._real_net._hur_net : # FIXME a priori pb du a l outil d optimisation
for i in range ( self._ind, self._ind2 + pas, pas ) : self._hur_net.append ( self._real_net._hur_net[i] )
##### Initialisation of the hurricane nets #####
def create_hur_net ( self ) :
if self._arity == 1 :
self.hur_net ( self._name, 0 )
else :
#for i in range ( self._ind+self._arity, self._ind, -1 ):
for i in range ( self._ind, self._ind+self._arity, 1 ):
#print 'create %s(%d)' % (self._name,i)
self.hur_net ( '%s(%d)' % (self._name,i), i )
##### hur_net one by one #####
def hur_net ( self, name, ind ) :
if ( self._alias ) and ( self._alias[ind] ) :
self._hur_net += [self._alias[ind].keys()[0]] # put the right hur_net
return
elif ( self._to_cat ) and ( self._to_cat[ind] ) :
cat = self._to_cat[ind]
self._hur_net += [cat[0]._hur_net[cat[1]]]
return
net = Net.create ( self._st_cell._hur_cell, name )
net.setType ( Net.Type.LOGICAL )
if self._ext : net.setExternal ( True )
else : net.setExternal ( False )
if self._ext :
if self._direct == "IN" : net.setDirection ( Net.Direction.IN )
elif self._direct == "OUT" : net.setDirection ( Net.Direction.OUT )
elif self._direct == "INOUT" : net.setDirection ( Net.Direction.INOUT )
elif self._direct == "TRISTATE" : net.setDirection ( Net.Direction.TRISTATE )
elif self._direct == "UNKNOWN" : net.setDirection ( Net.Direction.UNDEFINED )
if '_h_type' in self.__dict__ :
if self._h_type == "POWER" : net.setType ( Net.Type.POWER ); net.setGlobal( True )
elif self._h_type == "GROUND" : net.setType ( Net.Type.GROUND ); net.setGlobal( True )
elif self._h_type == "CLOCK" : net.setType ( Net.Type.CLOCK ); net.setGlobal( True )
self._hur_net += [net]
##### Hurricane merge #####
def hur_merge ( self ) :
if self._real_net : realNet = self._real_net
else : realNet = self
if self._to_cat :
err = "\n[Stratus ERROR] HurricanePlug <= : net " + self._name + " is a Cat net. Forbidden utilisation of <= and Cat.\n"
raise Exception ( err )
for i in range ( self._ind, self._arity + self._ind ) :
if realNet._to_merge[i] :
selfToMerge = realNet._to_merge[i][0]
bitToMerge = realNet._to_merge[i][1]
if selfToMerge._hur_net == [] :
print "[Stratus Warning] HurricanePlug <= : net", selfToMerge._name, "has no hurricane net."
return
if realNet._hur_net == [] :
err = "\n[Stratus ERROR] HurricanePlug <= : net " + realNet._name + " has no hurricane net.\n"
raise Exception ( err )
if bitToMerge > ( len ( selfToMerge._hur_net ) - 1 ) :
err = "\n[Stratus ERROR] HurricanePlug <= : net " + selfToMerge._name + " with hur_net : " + str(selfToMerge._hur_net) \
+ " with asked bit : " + str(bitToMerge) + ".\n"
raise Exception ( err )
if i > ( len ( realNet._hur_net ) - 1 ) :
err = "\n[Stratus ERROR] HurricanePlug <= : net " + realNet._name + " with hur_net : " + str(realNet._hur_net) \
+ " with asked bit : " + str(i) + ".\n"
raise Exception ( err )
selfToMerge._hur_net[bitToMerge].merge ( realNet._hur_net[i] )
# realNet._hur_net[i] = 0
# realNet.Delete()
# del realNet
##### Initialisation from a net hurricane #####
def create_from_hur ( self, hur_net ) :
global CELLS
from st_model import CELLS
cell = CELLS[-1]
self._st_cell = cell
self._alias = []
self._to_merge = []
self._to_cat = []
self._real_net = None
self._arity = 1
self._ind = 0
self._name = str ( hur_net.getName() )
if hur_net.isExternal() : self._ext = True
else : self._ext = False
if hur_net.isExternal() :
if hur_net.getDirection() == Net.Direction.IN : self._direct = "IN"
elif hur_net.getDirection() == Net.Direction.OUT : self._direct = "OUT"
elif hur_net.getDirection() == Net.Direction.INOUT : self._direct = "INOUT"
elif hur_net.getDirection() == Net.Direction.TRISTATE : self._direct = "TRISTATE"
elif hur_net.getDirection() == Net.Direction.UNDEFINED : self._direct = "UNDEFINED"
if hur_net.getType() == Net.Type.POWER : self._h_type = "POWER"
elif hur_net.getType() == Net.Type.GROUND : self._h_type = "GROUND"
elif hur_net.getType() == Net.Type.CLOCK : self._h_type = "CLOCK"
self._hur_net = [hur_net]
if ( self._ext ) and ( '_h_type' in self.__dict__ ) :
if self._h_type == "CLOCK" : cell._st_ports.append ( self ) # not alimentations
else :
cell._st_sigs.append ( self )
###########
# SignalIn #
###########
class SignalIn ( net ) :
def __init__ ( self, nom, nbit, indice = 0 ) :
if nbit < 1 : raise Exception ( "\n[Stratus ERROR] SignalIn : the lenght of the net must be a positive value\n" )
self.create_net ( nom, nbit, indice, True, "IN" )
class SignalInFromHur ( net ) :
def __init__ ( self, hur_net ) : self.create_from_hur ( hur_net )
############
# SignalOut #
############
class SignalOut ( net ) :
def __init__ ( self, nom, nbit, indice = 0 ) :
if nbit < 1 : raise Exception ( "\n[Stratus ERROR] SignalOut : the lenght of the net must be a positive value\n" )
self.create_net ( nom, nbit, indice, True, "OUT" )
class SignalOutFromHur ( net ) :
def __init__ ( self, hur_net ) : self.create_from_hur ( hur_net )
##############
# SignalInOut #
##############
class SignalInOut ( net ) :
def __init__ ( self, nom, nbit, indice = 0 ) :
if nbit < 1 : raise Exception ( "\n[Stratus ERROR] SignalInOut : the lenght of the net must be a positive value\n" )
self.create_net ( nom, nbit, indice, True, "INOUT" )
class SignalInOutFromHur ( net ) :
def __init__ ( self, hur_net ) : self.create_from_hur ( hur_net )
################
# SignalUnknown #
################
class SignalUnknown ( net ) :
def __init__ ( self, nom, nbit, indice = 0 ) :
if nbit < 1 : raise Exception ( "\n[Stratus ERROR] SignalUnknown : the lenght of the net must be a positive value\n" )
self.create_net ( nom, nbit, indice, True, "UNKNOWN" )
class SignalUnknownFromHur ( net ) :
def __init__ ( self, hur_net ) : self.create_from_hur ( hur_net )
############
# TriState #
############
class TriState ( net ) :
def __init__ ( self, nom, nbit, indice = 0 ) :
if nbit < 1 : raise Exception ( "\n[Stratus ERROR] TriState : the lenght of the net must be a positive value\n" )
self.create_net ( nom, nbit, indice, True, "TRISTATE" )
class SignalTriStateFromHur ( net ) :
def __init__ ( self, hur_net ) : self.create_from_hur ( hur_net )
#########
# Clock #
#########
class CkIn ( net ) :
def __init__ ( self, nom ) :
self.create_net ( nom, 1, extern = True, direction = "IN", hType = "CLOCK" )
class CkInFromHur ( net ) :
def __init__ ( self, hur_net ) : self.create_from_hur ( hur_net )
#########################
# Internal Clock Signal #
#########################
class SignalCk ( net ) :
def __init__ ( self, nom ) :
self.create_net ( nom, 1, direction = "IN", hType = "CLOCK" )
class SignalCkFromHur ( net ) :
def __init__ ( self, hur_net ) : self.create_from_hur ( hur_net )
###################
# Internal Signal #
###################
class Signal ( net ) :
def __init__ ( self, nom, nbit = 0, indice = 0 ) :
if nbit < 0 : raise Exception ( "\n[Stratus ERROR] Signal : the lenght of the net must be a positive value\n" )
self.create_net ( nom, nbit, indice )
class SignalFromHur ( net ) :
def __init__ ( self, hur_net ) : self.create_from_hur ( hur_net )
################
# Alimentation #
################
class VddIn ( net ) :
def __init__ ( self, nom ) : self.create_net ( nom, 1, extern = True, direction = "IN", hType = "POWER" )
class VssIn ( net ) :
def __init__ ( self, nom ) : self.create_net ( nom, 1, extern = True, direction = "IN", hType = "GROUND" )
class VddInFromHur ( net ) :
def __init__ ( self, hur_net ) : self.create_from_hur ( hur_net )
class VssInFromHur ( net ) :
def __init__ ( self, hur_net ) : self.create_from_hur ( hur_net )
class SignalVdd ( net ) :
def __init__ ( self, nom ) : self.create_net ( nom, 1, direction = "IN", hType = "POWER" )
class SignalVss ( net ) :
def __init__ ( self, nom ) : self.create_net ( nom, 1, direction = "IN", hType = "GROUND" )
class SignalVddFromHur ( net ) :
def __init__ ( self, hur_net ) : self.create_from_hur ( hur_net )
class SignalVssFromHur ( net ) :
def __init__ ( self, hur_net ) : self.create_from_hur ( hur_net )
##################
# Virtual signal #
##################
class Sig ( net ) :
def __init__ ( self, net, indiceFort, indiceFaible = -1 ) :
global CELLS
from st_model import CELLS
if indiceFaible == -1 : indiceFaible = indiceFort
self._st_cell = CELLS[-1]
self._ind = indiceFaible
self._ind2 = indiceFort
self._alias = []
self._to_merge = []
self._to_cat = []
self._real_net = net
self._ext = net._ext
self._arity = abs ( indiceFort - indiceFaible ) + 1
if indiceFort < indiceFaible : self._reverse = True
else : self._reverse = False
self._hur_net = []
self._st_cell._st_partsigs.append ( self )
# Initialisation of _hur_net if in hurricanePlug mode
# if CELLS[0]._hur_plug : self.create_part_hur_net()
if self._ext : self._direct = net._direct
if '_h_type' in net.__dict__ : self._h_type = net._h_type
if indiceFort == indiceFaible : self._name = net._name + "[" + str(indiceFaible) + "]"
else : self._name = net._name + "[" + str(indiceFort) + ":" + str(indiceFaible) + "]"