#!/usr/bin/python # This file is part of the Coriolis Project. # Copyright (C) Laboratoire LIP6 - Departement ASIM # Universite Pierre et Marie Curie # # Main contributors : # Christophe Alexandre # Sophie Belloeil # Hugo Clement # Jean-Paul Chaput # Damien Dupuis # Christian Masson # Marek Sroka # # The Coriolis Project is free software; you can redistribute it # and/or modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # The Coriolis Project is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with the Coriolis Project; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA # # License-Tag # Authors-Tag # =================================================================== # # x-----------------------------------------------------------------x # | | # | C O R I O L I S | # | S t r a t u s - Netlists/Layouts Description | # | | # | Author : Sophie BELLOEIL | # | E-mail : Sophie.Belloeil@asim.lip6.fr | # | =============================================================== | # | Py Module : "./dpgen_Nul.py" | # | *************************************************************** | # | U p d a t e s | # | | # x-----------------------------------------------------------------x from stratus import * class DpgenNul ( Model ) : ## Interface ## ############### def Interface ( self ) : self._nbit = self._param['nbit'] self._i0 = SignalIn ( "i0", self._nbit ) self._nul = SignalOut ( "nul", 1 ) self._vdd = VddIn ( "vdd" ) self._vss = VssIn ( "vss" ) ## Netlist ## ############# def Netlist ( self ) : global LV_prevTreeOut global LV_oneShift global nul LV_prevTreeOut = -1 LV_oneShift = 0 offset = 0 depthNext = get_depth ( self._nbit, 0 ) nul = [] for i in range ( self._nbit ) : nul += [Signal ( "nul_%d" % i, 1 )] self.Nul = {} while ( 1 ) : depth = depthNext depthNext = get_depth ( self._nbit, depth + 1 ) offset = self.create_Netlist_Tree ( offset, depth, depthNext ) if depthNext == 0 : break # Simulation d'une boucle do ... while ########## Layout ########## ############################ def Layout ( self ) : global LV_prevTreeOut global LV_oneShift mDepth = ilog2 ( self._nbit ) LV_prevTreeOut = -1 LV_oneShift = 0 offset = 0 depthNext = get_depth ( self._nbit, 0 ) while ( 1 ) : depth = depthNext depthNext = get_depth ( self._nbit, depth + 1 ) offset = self.create_Layout_Tree ( offset, depth, depthNext ) if depthNext == 0 : break ########## VBE ########## ######################### def Vbe ( self ) : flags = self._param['flags'] fileName = self._name + ".vbe" file = open ( fileName, "w+" ) sBusWide = VHDL_BUS_WIDE ( self._nbit - 1, 0, self._nbit, flags ) ## Entity description ## file.write ( "\nENTITY %s IS\n PORT (\n" % self._name ) file.write ( "%14s : in BIT_VECTOR %s;\n" % ( "i0", sBusWide ) ) file.write ( "%14s : out BIT;\n" % "nul" ) file.write ( "%14s : in BIT;\n" % "vdd" ) file.write ( "%14s : in BIT\n" % "vss" ) ## End of entity description ## file.write ( " );\nEND %s;\n\n\n" % self._name ) ## Architecture description ## file.write ( "ARCHITECTURE VBE OF %s IS\n\n" % self._name ) file.write ( "BEGIN\n\n" ) xl_zero = newxl () xl_zero._size = self._nbit file.write ( " nul <= \'1\' WHEN (i0 = %s)\n" % xl_zero.xltovhdl () ) file.write ( " ELSE \'0\';\n\n\n" ) ## Assert ## file.write ( " ASSERT (vdd = '1')\n" ) file.write ( " REPORT \"Power supply is missing on vdd of Model %s.\"\n" % self._name ) file.write ( " SEVERITY WARNING;\n\n" ) file.write ( " ASSERT (vss = '0')\n" ) file.write ( " REPORT \"Power supply is missing on vss of Model %s.\"\n" % self._name ) file.write ( " SEVERITY WARNING;\n\n" ) ## End of architecture description ## file.write ( "END VBE;\n" ) file.close () ########## create_Netlist_Tree ########## ######################################### def create_Netlist_Tree ( self, aOffset, amDepth, amDepthNext ) : global LV_prevTreeOut global LV_oneShift global nul if amDepthNext > 0 : polarity = amDepthNext % 2 else : polarity = amDepth % 2 if not ( amDepth ) : if not ( amDepthNext ) : # Pathological case : the zero detect is reduced to only one bit! This is only a inversor. self.Nul[aOffset] = Inst ( "inv_x4" , "nul_%ld" % aOffset , map = { 'i' : self._i0[aOffset] , 'nq' : self._nul , 'vdd' : self._vdd , 'vss' : self._vss } ) else : LV_prevTreeOut = aOffset if ( amDepth % 2 ) == polarity : # This branch will skip an even number of layer, we keep the same polarity. self._i0[aOffset].Alias ( nul[aOffset] ) else : # There is a polarity inversion. self.Nul[aOffset] = Inst ( "inv_x4" , "nul_%ld" % aOffset , map = { 'i' : self._i0[aOffset] , 'nq' : nul[aOffset] , 'vdd' : self._vdd , 'vss' : self._vss } ) LV_oneShift = 1 aOffset += 1 aOffset += 1 return aOffset # Build the tree. for depth in range ( amDepth ) : mk = iexp2 ( amDepth - depth - 1 ) for k in range ( mk ) : if depth : i_offset = iexp2 ( depth - 1 ) - 1 else : i_offset = 0 cell_index = iexp2 ( depth + 1 ) * k + iexp2 ( depth ) - 1 + aOffset i1_index = iexp2 ( depth + 1 ) * k + iexp2 ( depth ) + i_offset + aOffset i0_index = iexp2 ( depth + 1 ) * k + i_offset + aOffset if depth % 2 : sModel = "na2_x1" else : sModel = "no2_x1" thisMap = {} thisMap['nq'] = nul[cell_index] if depth : thisMap['i0'] = nul[i0_index] thisMap['i1'] = nul[i1_index] else : thisMap['i0'] = self._i0[i0_index - LV_oneShift] thisMap['i1'] = self._i0[i1_index - LV_oneShift] # Special case of the last layer. if mk == 1 and LV_prevTreeOut < 0 : if not ( amDepthNext ) : # This is the only tree in the operator. if depth % 2 : sModel = "a2_x4" thisMap['q'] = self._nul if thisMap.has_key('nq') : del thisMap['nq'] else : sModel = "no2_x4" thisMap['nq'] = self._nul else : if depth % 2 == polarity : # Only for the first tree : adjust the polarity. if depth % 2 : sModel = "a2_x2" else : sModel = "o2_x2" if thisMap.has_key('nq') : del thisMap['nq'] thisMap['q'] = nul[cell_index] thisMap['vdd'] = self._vdd thisMap['vss'] = self._vss self.Nul[cell_index] = Inst ( sModel , "nul_%ld" % cell_index , map = thisMap ) depth += 1 # Attention : difference entre les boucles en c et les boucles en python # Check if there is a ripple part. if LV_prevTreeOut < 0 : LV_prevTreeOut = cell_index return ( aOffset + iexp2 ( amDepth ) ) # Add the ripple part. cell_index = aOffset - 1 thisMap = {} if not ( amDepthNext ) : if depth % 2 : sModel = "a2_x4" thisMap['q'] = self._nul else : sModel = "no2_x4" thisMap['nq'] = self._nul else : if depth % 2 : sModel = "na2_x1" else : sModel = "no2_x1" if depth % 2 != polarity : thisMap['nq'] = nul[cell_index] else : thisMap['q'] = nul[cell_index] if depth % 2 == polarity : if depth % 2 : sModel = "a2_x2" else : sModel = "o2_x2" i1_index = iexp2 ( amDepth - 1 ) - 1 + aOffset i0_index = LV_prevTreeOut thisMap['i0'] = nul[i0_index] thisMap['i1'] = nul[i1_index] thisMap['vdd'] = self._vdd thisMap['vss'] = self._vss self.Nul[aOffset-1] = Inst ( sModel , "nul_%ld" % ( aOffset - 1 ) , map = thisMap ) LV_prevTreeOut = cell_index return ( aOffset + iexp2 ( amDepth ) ) ########## create_Layout_Tree ########## ######################################## def create_Layout_Tree ( self, aOffset, amDepth, amDepthNext ) : global LV_oneShift global LV_prevTreeOut if amDepthNext > 0 : polarity = amDepthNext % 2 else : polarity = amDepth % 2 if not ( amDepth ) : if not ( amDepthNext ) : # Cas pathologique : detection a un seul bit : c'est un inverseur dpgen_place ( self.Nul[aOffset], 0, aOffset * 50 ) else : LV_prevTreeOut = aOffset if ( amDepth % 2 ) != polarity : dpgen_place ( self.Nul[aOffset], 0, aOffset * 50 ) LV_oneShift = 1 aOffset += 1 aOffset += 1 return aOffset # Build the tree. for depth in range ( amDepth ) : mk = iexp2 ( amDepth - depth - 1 ) for k in range ( mk ) : cell_index = iexp2 ( depth + 1 ) * k + iexp2 ( depth ) - 1 + aOffset if depth % 2 : sModel = "na2_x1" else : sModel = "no2_x1" # Special case of the last layer. if mk == 1 and LV_prevTreeOut < 0 : if not ( amDepthNext ) : # This is the only tree in the operator. if depth % 2 : sModel = "a2_x4" else : sModel = "no2_x4" else : if depth % 2 == polarity : # Only for the first tree : adjust the polarity. if depth % 2 : sModel = "a2_x2" else : sModel = "o2_x2" dpgen_place ( self.Nul[cell_index], 0, cell_index * 50 ) if LV_prevTreeOut < 0 : LV_prevTreeOut = cell_index return ( aOffset + iexp2 ( amDepth ) ) if not ( amDepthNext ) : if depth % 2 : sModel = "a2_x4" else : sModel = "no2_x4" else : if depth % 2 : sModel = "na2_x1" else : sModel = "no2_x1" if depth % 2 == polarity : if depth % 2 : sModel = "a2_x2" else : sModel = "o2_x2" cell_index = aOffset - 1 dpgen_place ( self.Nul[aOffset-1], 0, ( aOffset - 1 ) * 50 ) LV_prevTreeOut = cell_index return ( aOffset + iexp2 ( amDepth ) )