wiki:ToolsCourseTp10

Version 19 (modified by anne, 17 years ago) (diff)

--

TP10 VLSI : Vue physique de l'AMD2901

Objectifs

  • Utiliser les outils de placement et routage.
  • Vérifier la validité du routage.

Exercice(s)

Exercice 1-Placement

La première étape consiste à générer le coeur du circuit en exécutant le fichier coeur.py

afin de prévoir un bon routage des alim il est nécessaire de prendre en compte ce qui suit dans l'écriture du fichier coeur.py

- dans la netlist (méthode Netlist) :


   def Netlist ( self ) :


   self.tie = Inst ("tie_x0",
                    "tie",
                    map = {'vdd'    : self.vdd,
                           'vss'    : self.vss
                          }
                   )


- dans la méthode Layout :


   def Layout ( self ):
       DefAb(XY(0,0),XY(1500,1500))
       Place(self.tie, NOSYM, XY(0,0))
       AlimConnectors()

Ensuite Le Placement du circuit est possible en éxecutant le script donné plus bas, on place les plots puis le coeur.

Question 1

Exécutez le script suivant amd_chip.py en ayant pris soin de comprendre le contenu de ce fichier

#!/usr/bin/python

from stratus import *

class amd_chip ( Model ) :

  def Interface ( self ) :

    self.cke     = CkIn       ( "cke")
    self.cin     = SignalIn  ( "cin",   1 )
    self.cout    = SignalOut  ( "cout",  1 )
    self.np      = SignalOut      ( "np",    1 )
    self.ng      = SignalOut      ( "ng",    1 )
    self.ovr     = SignalOut      ( "ovr",   1 )
    self.zero    = SignalOut      ( "zero",  1 )
    self.signe   = SignalOut  ( "signe", 1 )
    self.r0      = TriState  ( "r0",    1 )
    self.r3      = TriState  ( "r3",    1 )
    self.q0      = TriState  ( "q0",    1 )
    self.q3      = TriState  ( "q3",    1 )
    self.a       = SignalIn       ( "a",     4 )
    self.b       = SignalIn       ( "b",     4 )
    self.d       = SignalIn       ( "d",     4 )
    self.i       = SignalIn       ( "i",     9 )
    self.noe     = SignalIn       ( "noe",   1 )
    self.y       = TriState  ( "y",     4 )

    self.vddi     = VddIn ( "vddi"  )
    self.vssi     = VssIn ( "vssi"  )
    self.vdde    = VddIn ( "vdde" )
    self.vsse    = VssIn ( "vsse" )


  def Netlist ( self ) :

    cin_from_pads    = Signal ( "cin_from_pads",    1 )
    cout_to_pads     = Signal ( "cout_to_pads",     1 )
    np_to_pads       = Signal ( "np_to_pads",       1 )
    ng_to_pads       = Signal ( "ng_to_pads",       1 )
    ovr_to_pads      = Signal ( "ovr_to_pads",      1 )
    zero_to_pads     = Signal ( "zero_to_pads",     1 )
    shift_r          = Signal ( "shift_r",          1 )
    shift_l          = Signal ( "shift_l",          1 )
    signe_to_pads    = Signal ( "signe_to_pads",    1 )
    r0_to_pads       = Signal ( "r0_to_pads",       1 )
    r3_to_pads       = Signal ( "r3_to_pads",       1 )
    r0_from_pads     = Signal ( "r0_from_pads",     1 )
    r3_from_pads     = Signal ( "r3_from_pads",     1 )
    q0_to_pads       = Signal ( "q0_to_pads",       1 )
    q3_to_pads       = Signal ( "q3_to_pads",       1 )
    q0_from_pads     = Signal ( "q0_from_pads",     1 )
    q3_from_pads     = Signal ( "q3_from_pads",     1 )
    ck_ring          = Signal ( "ck_ring",          1 )
    a_from_pads      = Signal ( "a_from_pads",      4 )
    b_from_pads      = Signal ( "b_from_pads",      4 )
    d_from_pads      = Signal ( "d_from_pads",      4 )
    i_from_pads      = Signal ( "i_from_pads",      9 )
    y_to_pads        = Signal ( "y_to_pads",        4 )
    noe_from_pads    = Signal ( "noe_from_pads",    1 )
    y_oe             = Signal ( "y_oe",             1 )
    self.ckc         = Signal ( "ckc",              1 )


    self.coeur = Inst ( "coeur"
                     , "coeur"
                     , map = { 'cin_from_pads' : cin_from_pads
                             , 'cout_to_pads'  : cout_to_pads
                             , 'np_to_pads'    : np_to_pads
                             , 'ng_to_pads'    : ng_to_pads
                             , 'ovr_to_pads'   : ovr_to_pads
                             , 'signe_to_pads' : signe_to_pads
                             , 'zero_to_pads'  : zero_to_pads
                             , 'shift_r'       : shift_r
                             , 'shift_l'       : shift_l
                             , 'r0_to_pads'    : r0_to_pads
                             , 'r3_to_pads'    : r3_to_pads
                             , 'r0_from_pads'  : r0_from_pads
                             , 'r3_from_pads'  : r3_from_pads
                             , 'q0_to_pads'    : q0_to_pads
                             , 'q3_to_pads'    : q3_to_pads
                             , 'q0_from_pads'  : q0_from_pads
                             , 'q3_from_pads'  : q3_from_pads
                             , 'ck'            : self.ckc
                             , 'a_from_pads'   : a_from_pads
                             , 'b_from_pads'   : b_from_pads
                             , 'd_from_pads'   : d_from_pads
                             , 'i_from_pads'   : i_from_pads
                             , 'y_to_pads'     : y_to_pads
                             , 'noe_from_pads' : noe_from_pads
                             , 'y_oe'          : y_oe
                             , 'vdd'           : self.vdd
                             , 'vss'           : self.vss
                             }
                     )

    self.p_ck = Inst ( "pck_px", "p_ck"
         , map = { 'pad'  : self.cke
                 , 'ck'   : ck_ring
                 , 'vddi' : self.vdd
                 , 'vssi' : self.vss
                 , 'vdde' : self.vdde
                 , 'vsse' : self.vsse
                 }
         )

    self.p_cin = Inst ( "pi_px", "p_cin"
         , map = { 'pad'  : self.cin
                 , 't'    : cin_from_pads
                 , 'ck'   : ck_ring
                 , 'vddi' : self.vdd
                 , 'vssi' : self.vss
                 , 'vdde' : self.vdde
                 , 'vsse' : self.vsse
                 }
         )

    self.p_noe = Inst ( "pi_px", "p_noe"
         , map = { 'pad'  : self.noe
                 , 't'    : noe_from_pads
                 , 'ck'   : ck_ring
                 , 'vddi' : self.vdd
                 , 'vssi' : self.vss
                 , 'vdde' : self.vdde
                 , 'vsse' : self.vsse
                 }
         )

    self.p_a = {}
    self.p_b = {}
    self.p_d = {}
    for i in range ( 4 ) :
      self.p_a[i] = Inst ( "pi_px", "p_a%d" % i
           , map = { 'pad'  : self.a[i]
                   , 't'    : a_from_pads[i]
                   , 'ck'   : ck_ring
                   , 'vddi' : self.vdd
                   , 'vssi' : self.vss
                   , 'vdde' : self.vdde
                   , 'vsse' : self.vsse
                   }
           )

      self.p_b[i] = Inst ( "pi_px", "p_b%d" % i
           , map = { 'pad'  : self.b[i]
                   , 't'    : b_from_pads[i]
                   , 'ck'   : ck_ring
                   , 'vddi' : self.vdd
                   , 'vssi' : self.vss
                   , 'vdde' : self.vdde
                   , 'vsse' : self.vsse
                   }
           )

      self.p_d[i] = Inst ( "pi_px", "p_d%d" % i
           , map = { 'pad'  : self.d[i]
                   , 't'    : d_from_pads[i]
                   , 'ck'   : ck_ring
                   , 'vddi' : self.vdd
                   , 'vssi' : self.vss
                   , 'vdde' : self.vdde
                   , 'vsse' : self.vsse
                   }
           )

    self.p_i = {}
    for i in range ( 9 ) :
      self.p_i[i] = Inst ( "pi_px", "p_i%d" % i
           , map = { 'pad'  : self.i[i]
                   , 't'    : i_from_pads[i]
                   , 'ck'   : ck_ring
                   , 'vddi' : self.vdd
                   , 'vssi' : self.vss
                   , 'vdde' : self.vdde
                   , 'vsse' : self.vsse
                   }
           )

    self.p_cout = Inst ( "po_px", "p_cout"
         , map = { 'i'    : cout_to_pads
                 , 'pad'  : self.cout
                 , 'ck'   : ck_ring
                 , 'vddi' : self.vdd
                 , 'vssi' : self.vss
                 , 'vdde' : self.vdde
                 , 'vsse' : self.vsse
                 }
         )

    self.p_np = Inst ( "po_px", "p_np"
         , map = { 'i'    : np_to_pads
                 , 'pad'  : self.np
                 , 'ck'   : ck_ring
                 , 'vddi' : self.vdd
                 , 'vssi' : self.vss
                 , 'vdde' : self.vdde
                 , 'vsse' : self.vsse
                 }
         )

    self.p_ng = Inst ( "po_px", "p_ng"
         , map = { 'i'    : ng_to_pads
                 , 'pad'  : self.ng
                 , 'ck'   : ck_ring
                 , 'vddi' : self.vdd
                 , 'vssi' : self.vss
                 , 'vdde' : self.vdde
                 , 'vsse' : self.vsse
                 }
         )

    self.p_ovr = Inst ( "po_px", "p_ovr"
         , map = { 'i'    : ovr_to_pads
                 , 'pad'  : self.ovr
                 , 'ck'   : ck_ring
                 , 'vddi' : self.vdd
                 , 'vssi' : self.vss
                 , 'vdde' : self.vdde
                 , 'vsse' : self.vsse
                 }
         )

    self.p_zero = Inst ( "po_px", "p_zero"
         , map = { 'i'    : zero_to_pads
                 , 'pad'  : self.zero
                 , 'ck'   : ck_ring
                 , 'vddi' : self.vdd
                 , 'vssi' : self.vss
                 , 'vdde' : self.vdde
                 , 'vsse' : self.vsse
                 }
         )

    self.p_signe = Inst ( "po_px", "p_signe"
         , map = { 'i'    : signe_to_pads
                 , 'pad'  : self.signe
                 , 'ck'   : ck_ring
                 , 'vddi' : self.vdd
                 , 'vssi' : self.vss
                  , 'vdde' : self.vdde
                  , 'vsse' : self.vsse
                  }
         )

    self.p_y = {}
    for i in range ( 4 ) :
      self.p_y[i] = Inst ( "pot_px", "p_y%d" % i
           , map = { 'i'    : y_to_pads[i]
                   , 'b'    : y_oe
                   , 'pad'  : self.y[i]
                   , 'ck'   : ck_ring
                   , 'vddi' : self.vdd
                   , 'vssi' : self.vss
                   , 'vdde' : self.vdde
                   , 'vsse' : self.vsse
                   }
           )

    self.p_q0 = Inst ( "piot_px", "p_q0"
         , map = { 'i'    : q0_to_pads
                 , 'b'    : shift_r
                 , 't'    : q0_from_pads
                 , 'pad'  : self.q0
                 , 'ck'   : ck_ring
                 , 'vddi' : self.vdd
                 , 'vssi' : self.vss
                 , 'vdde' : self.vdde
                 , 'vsse' : self.vsse
                 }
         )

    self.p_q3 = Inst ( "piot_px", "p_q3"
         , map = { 'i'    : q3_to_pads
                 , 'b'    : shift_l
                 , 't'    : q3_from_pads
                 , 'pad'  : self.q3
                 , 'ck'   : ck_ring
                 , 'vddi' : self.vdd
                 , 'vssi' : self.vss
                 , 'vdde' : self.vdde
                 , 'vsse' : self.vsse
                 }
         )

    self.p_r0 = Inst ( "piot_px", "p_r0"
         , map = { 'i'    : r0_to_pads
                 , 'b'    : shift_r
                 , 't'    : r0_from_pads
                 , 'pad'  : self.r0
                 , 'ck'   : ck_ring
                 , 'vddi' : self.vdd
                 , 'vssi' : self.vss
                 , 'vdde' : self.vdde
                 , 'vsse' : self.vsse
                 }
         )

    self.p_r3 = Inst ( "piot_px", "p_r3"
         , map = { 'i'    : r3_to_pads
                 , 'b'    : shift_l
                 , 't'    : r3_from_pads
                 , 'pad'  : self.r3
                 , 'ck'   : ck_ring
                 , 'vddi' : self.vdd
                 , 'vssi' : self.vss
                 , 'vdde' : self.vdde
                 , 'vsse' : self.vsse
                 }
         )

    self.p_vddick0 = Inst ( "pvddick_px", "p_vddick0"
         , map = { 'cko'  : self.ckc
                 , 'ck'   : ck_ring
                 , 'vddi' : self.vdd
                 , 'vssi' : self.vss
                  , 'vdde' : self.vdde
                  , 'vsse' : self.vsse
                  }
         )

    self.p_vssick0 = Inst ( "pvssick_px", "p_vssick0"
         , map = { 'cko'  : self.ckc
                 , 'ck'   : ck_ring
                 , 'vddi' : self.vdd
                 , 'vssi' : self.vss
                 , 'vdde' : self.vdde
                 , 'vsse' : self.vsse
                 }
         )

    self.p_vddeck0 = Inst ( "pvddeck_px", "p_vddeck0"
         , map = { 'cko'  : self.ckc
                 , 'ck'   : ck_ring
                 , 'vddi' : self.vdd
                 , 'vssi' : self.vss
                 , 'vdde' : self.vdde
                 , 'vsse' : self.vsse
                 }
         )

    self.p_vddeck1 = Inst ( "pvddeck_px", "p_vddeck1"
         , map = { 'cko'  : self.ckc
                 , 'ck'   : ck_ring
                 , 'vddi' : self.vdd
                 , 'vssi' : self.vss
                 , 'vdde' : self.vdde
                 , 'vsse' : self.vsse
                 }
         )

    self.p_vsseck0 = Inst ( "pvsseck_px", "p_vsseck0"
         , map = { 'cko'  : self.ckc
                 , 'ck'   : ck_ring
                 , 'vddi' : self.vdd
                 , 'vssi' : self.vss
                  , 'vdde' : self.vdde
                  , 'vsse' : self.vsse
                  }
         )

    self.p_vsseck1 = Inst ( "pvsseck_px", "p_vsseck1"
         , map = { 'cko'  : self.ckc
                 , 'ck'   : ck_ring
                 , 'vddi' : self.vdd
                 , 'vssi' : self.vss
                 , 'vdde' : self.vdde
                 , 'vsse' : self.vsse
                 }
         )


  def Layout ( self ) :

    ##### A COMPLETER #####
    DefAb(XY(0,0),XY(3000,3000))

    PlaceCentric(self.coeur)

    PadNorth(self.p_i[3],self.p_i[4],self.p_i[5],self.p_b[0],self.p_b[1],self.p_b[2],self.p_b[3]
                ,self.p_q0,self.p_q3,self.p_i[6],self.p_i[7])


    PadWest(self.p_ck,self.p_d[0],self.p_d[1],self.p_d[2],self.p_zero,self.p_vsseck0,self.p_ovr
                ,self.p_d[3],self.p_i[0],self.p_i[1],self.p_i[2])


    PadSouth(self.p_cin,self.p_np,self.p_ng,self.p_vssick0,self.p_vddeck0,self.p_vsseck1,self.p_vddeck1
                ,self.p_cout,self.p_y[0],self.p_y[1],self.p_y[2])


    PadEast(self.p_y[3],self.p_signe,self.p_noe,self.p_a[0],self.p_a[1],self.p_vddick0
                ,self.p_a[2],self.p_a[3],self.p_r0,self.p_r3,self.p_i[8])





    PowerRing(3)

    PlaceGlue(self.coeur)

    FillCell(self.coeur)

    RouteCk(self.ckc)


mon_chip = amd_chip ( "amd_2901_dpt" )

mon_chip.Interface ()
mon_chip.Netlist ()
#mon_chip.Layout ()
mon_chip.View ()
mon_chip.Save (LAYOUT)

Quels sont les fichiers obtenus? regardez en utilisant graal le résultat du placement.

Question 2

Faites varier la taille de la boite d'aboutement, qu'observez-vous ? Avez vous rencontré une limite ? peut-on en déduire la largeur des plots.

Exercice 2-Routage

Cette seconde étape consiste à relier les cellules du coeur entre elles pour former le coeur et relier les connecteurs du coeur aux plots. Vous allez pour cela utiliser l'outil nero . Consultez le man de nero

>nero -v -3 -p amd_chip_pl amd amd_route

visualiser le résultat obtenu à l'aide de graal.

Question 1

A quoi correspondent les options utilisées dans la commande ci-dessus? Faites varier le nombre de couches de métal utilisés pour le routage.

Exercice 3-Validation du routage

Cette étape consiste à vérifier que le routage a été effectué sans erreur. Il y a deux types de vérifications à réaliser

  • Vérifier le respect des règles de dessin
  • Vérifier les interconnexions réalisées

Question 1

Vérifiez le respect des règles de dessin en utilisant Druc en dehors de graal

> druc amd_route

. Vous aurez pris soin au préalable de vérifier que vous utilisez la technologie symbolique

Question 2

Utilisez l'outil cougar pour extraire la netlist de votre circuit au niveau "cellules de base ". Vous aurez au préalable pris soin de positionner la variable d'environnement MBK_OUT_LO au format al.

Question 3

Comparez la netlist extraite à celle d'origine (avnt routage) en utilisant l'outil lvx