coriolis/stratus1/src/dpgen/dpgen_Shifter.py

264 lines
11 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 : "./dpgen_Shifter.py" |
# | *************************************************************** |
# | U p d a t e s |
# | |
# x-----------------------------------------------------------------x
from stratus import *
class DpgenShifter ( Model ) :
## Interface ##
###############
def Interface ( self ) :
global Slices
global BitIndex
self._nbit = self._param['nbit']
Slices = ln2p ( self._nbit )
self._op = SignalIn ( "op", 2 )
self._shamt = SignalIn ( "shamt", Slices )
self._i = SignalIn ( "i", self._nbit )
self._o = SignalOut ( "o", self._nbit )
self.vdd = VddIn ( "vdd" )
self.vss = VssIn ( "vss" )
## Netlist ##
#############
def Netlist ( self ) :
global SliceIndex
AndIndex = 0
# Signals
MuxOutput = Signal ( "muxoutput", self._nbit * Slices + self._nbit )
c0 = Signal ( "c0", Slices )
c1 = Signal ( "c1", Slices )
msb = Signal ( "msb", 1 )
# Arithmetic or input extension
self.A0 = Inst ( "a2_x2"
, "a_0"
, map = { 'i0' : self._i[self._nbit-1]
, 'i1' : self._op[1]
, 'q' : msb
, 'vdd' : self.vdd
, 'vss' : self.vss
}
)
# Normalizing the input signals names
for BitIndex in range ( self._nbit ) : self._i[BitIndex].Alias ( MuxOutput[BitIndex] )
self.M = {}
# Connecting the mux matrix
for SliceIndex in range ( Slices ) :
for BitIndex in range ( self._nbit ) :
LeftIndex = BitIndex - ( 1 << SliceIndex )
RightIndex = BitIndex + ( 1 << SliceIndex )
if LeftIndex >= 0 :
if RightIndex < self._nbit :
self.M[SliceIndex*self._nbit+BitIndex] = Inst ( "mx3_x2"
, "m_%d" % ( SliceIndex * self._nbit + BitIndex )
, map = { 'cmd0' : c0[SliceIndex]
, 'cmd1' : c1[SliceIndex]
, 'i0' : MuxOutput[SliceIndex * self._nbit + LeftIndex]
, 'i1' : MuxOutput[SliceIndex * self._nbit + BitIndex]
, 'i2' : MuxOutput[SliceIndex * self._nbit + RightIndex]
, 'q' : MuxOutput[( SliceIndex + 1 ) * self._nbit + BitIndex]
, 'vdd' : self.vdd
, 'vss' : self.vss
}
)
else :
self.M[SliceIndex*self._nbit+BitIndex] = Inst ( "mx3_x2"
, "m_%d" % ( SliceIndex * self._nbit + BitIndex )
, map = { 'cmd0' : c0[SliceIndex]
, 'cmd1' : c1[SliceIndex]
, 'i0' : MuxOutput[SliceIndex * self._nbit + LeftIndex]
, 'i1' : MuxOutput[SliceIndex * self._nbit + BitIndex]
, 'i2' : msb
, 'q' : MuxOutput[( SliceIndex + 1 ) * self._nbit + BitIndex]
, 'vdd' : self.vdd
, 'vss' : self.vss
}
)
else :
if RightIndex < self._nbit :
self.M[SliceIndex*self._nbit+BitIndex] = Inst ( "mx3_x2"
, "m_%d" % ( SliceIndex * self._nbit + BitIndex )
, map = { 'cmd0' : c0[SliceIndex]
, 'cmd1' : c1[SliceIndex]
, 'i0' : self._op[0]
, 'i1' : MuxOutput[SliceIndex * self._nbit + BitIndex]
, 'i2' : MuxOutput[SliceIndex * self._nbit + RightIndex]
, 'q' : MuxOutput[( SliceIndex + 1 ) * self._nbit + BitIndex]
, 'vdd' : self.vdd
, 'vss' : self.vss
}
)
else :
self.M[SliceIndex*self._nbit+BitIndex] = Inst ( "mx3_x2"
, "m_%d" % ( SliceIndex * self._nbit + BitIndex )
, map = { 'cmd0' : c0[SliceIndex]
, 'cmd1' : c1[SliceIndex]
, 'i0' : self._op[0]
, 'i1' : MuxOutput[SliceIndex * self._nbit + BitIndex]
, 'i2' : msb
, 'q' : MuxOutput[( SliceIndex + 1 ) * self._nbit + BitIndex]
, 'vdd' : self.vdd
, 'vss' : self.vss
}
)
# Normalizing the output signals names
for BitIndex in range ( self._nbit ) : self._o[BitIndex] <= MuxOutput[Slices * self._nbit + BitIndex]
# Building the control signals
if self._nbit < 16 : Model = "inv_x2"
elif self._nbit < 32 : Model = "inv_x4"
else : Model = "inv_x8"
self.I = {}
self.O = {}
for SliceIndex in range ( Slices ) :
self.I[SliceIndex] = Inst ( Model
, "i_%d" % SliceIndex
, map = { 'i' : self._shamt[SliceIndex]
, 'nq' : c1[SliceIndex]
, 'vdd' : self.vdd
, 'vss' : self.vss
}
)
self.O[SliceIndex] = Inst ( "o2_x2"
, "o_%d" % SliceIndex
, map = { 'i0' : c1[SliceIndex]
, 'i1' : self._op[0]
, 'q' : c0[SliceIndex]
, 'vdd' : self.vdd
, 'vss' : self.vss
}
)
########## Layout ##########
############################
def Layout ( self ) :
global SliceIndex
global BitIndex
Slices = ln2p ( self._nbit )
if self._nbit & 1 :
sym = SYM_Y
mys = NOSYM
else :
sym = NOSYM
mys = SYM_Y
BitIndex = self._nbit - 1
SliceIndex = 0
Place ( self.M[SliceIndex * self._nbit + BitIndex]
, SYM ( BitIndex, sym, mys )
, XY ( 0, 0 )
)
for SliceIndex in range ( 1, Slices ) :
PlaceRight ( self.M[SliceIndex * self._nbit + BitIndex]
, SYM ( BitIndex, sym, mys )
)
for SliceIndex in range ( Slices ) :
SetRefIns ( self.M[SliceIndex * self._nbit + self._nbit - 1] )
for BitIndex in range ( self._nbit - 2, -1, -1 ) :
PlaceBottom ( self.M[SliceIndex * self._nbit + BitIndex]
, SYM ( BitIndex, sym, mys )
)
BitIndex = self._nbit # Upper line, this is necessary for the computation of the symetry
SliceIndex = 0
SetRefIns ( self.M[SliceIndex * self._nbit + self._nbit - 1] )
PlaceTop ( self.A0
, SYM ( BitIndex, sym, mys )
)
for SliceIndex in range ( Slices ) :
if SliceIndex == 0 : SetRefIns ( self.A0 )
PlaceRight ( self.I[SliceIndex]
, SYM ( BitIndex, sym, mys )
)
PlaceRight ( self.O[SliceIndex]
, SYM ( BitIndex, sym, mys )
)
## VBE ##
#########
def Vbe ( self ) :
print "vbe of DpgenShifter not implemented"