Home > Community > Forums > Custom IC SKILL > Implementing flow control in rodCreatePath function

Email

* Required Fields

Recipients email * (separate multiple addresses with commas)

Your name *

Your email *

Message *

Contact Us

* Required Fields
First Name *

Last Name *

Email *

Company / Institution *

Comments: *

 Implementing flow control in rodCreatePath function 

Last post Fri, Apr 17 2009 2:52 AM by Infy1. 12 replies.
Started by infy 06 Apr 2009 10:01 PM. Topic has 12 replies and 4267 views
Page 1 of 1 (13 items)
Sort Posts:
  • Mon, Apr 6 2009 10:01 PM

    • infy
    • Not Ranked
    • Joined on Fri, Jul 18 2008
    • Posts 14
    • Points 250
    Implementing flow control in rodCreatePath function Reply

    Hi,

    Can we Implement flow control structures like if,while in rodCreatepath function to control the number of offset subpaths.

    Regards,

    Roy

    • Post Points: 20
  • Tue, Apr 7 2009 12:57 AM

    Re: Implementing flow control in rodCreatePath function Reply

    Here's an example - this uses various conditional statements around some of the arguments to rodCreatePath. I've done some more complex examples too, but this should be a simple enough illustration.

    ;
    ;  This pcell demonstrates the use of sub-rectangles and offset subpaths
    ;  in the multipart path transistor implementation.  The name of the master
    ;  view is:
    ;
    ;     pcells step8 layout
    ;
    ;  This pcell accepts these parameters:
    ;
    ;     width       Width of the transistor's active area (note: this is a
    ;                 distance measured in the Y-direction).
    ;                 (float, default = 3.0)
    ;
    ;     length      Length of the transistor's active area (note: this is a
    ;                 distance measured in the X-direction).
    ;                 (float, default = 0.6)
    ;
    ;     polyLayer   Name of the poly layer.
    ;                 (string, default = "poly")
    ;
    ;     diffLayer   Name of the diffusion layer.
    ;                 (string, default = "pdiff")
    ;
    ;     contLayer   Name of the contact layer.
    ;                 (string, default = "cont")
    ;
    ;     metalLayer  Name of the metal layer.
    ;                 (string, default = "metal1")
    ;
    ;     drainName   Name of the drain connection.
    ;                 (string, default = "D")
    ;
    ;     gateName    Name of the gate connection.
    ;                 (string, default = "G")
    ;
    ;     sourceName  Name of the source connection.
    ;                 (string, default = "S")
    ;
    ;     sourceContact Whether source contacts should be included
    ;                 (boolean, default = t)
    ;
    ;     drainContact Whether drain contacts should be included
    ;                 (boolean, default = t)
    ;
    pcDefinePCell(
       ;  Identify the target cellview.
       list(ddGetObj("pcells") "step8" "layout")
    
       ;  Define formal parameter name-value pairs.
       (
          (width 3.0)
          (length 0.6)
          (polyLayer "poly")
          (diffLayer "pdiff")
          (contLayer "cont")
          (metalLayer "metal1")
          (drainName "D")
          (gateName "G")
          (sourceName "S")
          (sourceContact t)
          (drainContact t)
       )
    
       ;  Define the contents of this cellview.
       let((tfId polyExtend contWidth polyContSep diffContEnclose
            metalContEnclose diffPolyEnclose pinEndOffset polySep transObj grid
    	polyDiffSep sdWidth)
    
          ; convert to proper booleans
          sourceContact=(sourceContact==t || sourceContact=="TRUE")
          drainContact=(drainContact==t || drainContact=="TRUE")
    
          ;  Get the technology information for this cell.
          tfId = techGetTechFile(ddGetObj("pcells"))
    
          ;  Get the minimum extension of poly beyond diffusion.
          polyExtend = techGetSpacingRule(tfId "minExtension" polyLayer)
    
          ;  Get the minimum contact width.
          contWidth = techGetSpacingRule(tfId "minWidth" contLayer)
    
          ;  Get the gate spacing
          polySep = techGetSpacingRule(tfId "minSpacing" polyLayer)
    
          ;  Get the minimum poly to contact spacing.
          polyContSep = techGetSpacingRule(tfId "minSpacing" polyLayer contLayer)
    
          ;  Get the minimum poly to diffusion spacing.
          polyDiffSep = techGetSpacingRule(tfId "minSpacing" polyLayer diffLayer)
    
          ;  Get the minimum diffusion enclosure of contact.
          diffContEnclose =
    	  techGetOrderedSpacingRule(tfId "minEnclosure" diffLayer contLayer)
    
          ;  Get the minimum diffusion enclosure of poly (used when metal contacts
          ;  not included)
          diffPolyEnclose =
    	  techGetOrderedSpacingRule(tfId "minEnclosure" diffLayer polyLayer)
    
          ;  Get the minimum metal enclosure of contact.
          metalContEnclose =
          techGetOrderedSpacingRule(tfId "minEnclosure" metalLayer contLayer)
    
          ;  pin end offset
          pinEndOffset = -(polyExtend + diffContEnclose - metalContEnclose)
    
          ;  source/drain width
          sdWidth = contWidth+polyContSep+diffContEnclose
    
          ;  Get the minimum resolution for this process.
          grid = techGetMfgGridResolution(tfId)
    
          ;------------------------------------------------------------------
          ; Create the gate and diffusion regions.
          ;------------------------------------------------------------------
          transObj = rodCreatePath(
             ?layer list(polyLayer "drawing")
             ?endType     "variable"
    	 ?width length
             ?pts list(0.0:0.0 0.0:width)
             ?beginExt polyExtend
             ?endExt  polyExtend
             ;  Define the diffusion region - just under the gate
             ?encSubPath
    	 setof(arg
    	     list(
    		list(
    		   ?layer list(diffLayer "drawing")
    		   ?enclosure 0.0
    		   ?beginOffset -polyExtend
    		   ?endOffset -polyExtend
    		)
    	     )
    	     arg
    	 )
             ?offsetSubPath
    	 setof(arg
    	     list(
    		;  Define the drain metal stripe.
    		when(drainContact
    		    list(
    		       ?layer list(metalLayer "drawing")
    		       ?pin t
    		       ?termName drainName
    		       ?justification "left"
    		       ?width contWidth + 2.0*metalContEnclose
    		       ?sep polyContSep - metalContEnclose
    		       ?beginOffset pinEndOffset
    		       ?endOffset pinEndOffset
    		    )
    		)
    		;  Define the source metal stripe.
    		when(sourceContact
    		    list(
    		       ?layer list(metalLayer "drawing")
    		       ?pin t
    		       ?termName sourceName
    		       ?justification "right"
    		       ?width contWidth + 2.0*metalContEnclose
    		       ?sep polyContSep - metalContEnclose
    		       ?beginOffset pinEndOffset
    		       ?endOffset pinEndOffset
    		    )
    		)
    		;  Define the diffusion source area
    		list(
    		    ?layer list(diffLayer "drawing")
    		    ; width depends on whether source contact included or not
    		    ?width if(sourceContact sdWidth diffPolyEnclose)
    		    ?justification "right"
    		    ?beginOffset -polyExtend
    		    ?endOffset -polyExtend
    		)
    		;  Define the diffusion drain area
    		list(
    		    ?layer list(diffLayer "drawing")
    		    ; width depends on whether drain contact included or not
    		    ?width if(drainContact sdWidth diffPolyEnclose)
    		    ?justification "left"
    		    ?beginOffset -polyExtend
    		    ?endOffset -polyExtend
    		)
    		;  Define the drain diffusion pin. For abut reasons the pin is
    		;  the same height that the metal pin is
    		;  NOTE - if the difference between diffPolyEnclose and polySep
    		;  is greater than the minimum gate length, then when abutted
    		;  the drain pin from one transistor can short out the
    		;  other transistor. This could be dealt with if necessary by
    		;  making the code a bit smarter
    		list(
    		   ?layer list(diffLayer "pin")
    		   ?pin t
    		   ?termName drainName
    		   ?justification "left"
    		   ; width adjusts to ensure that the diffusion pins will touch
    		   ; when the devices abut
    		   ?width if(drainContact sdWidth diffPolyEnclose)
    		   ?beginOffset pinEndOffset
    		   ?endOffset pinEndOffset
    		)
    		;  Define the source diffusion pin. For abut reasons the pin is
    		;  the same height that the metal pin is
    		list(
    		   ?layer list(diffLayer "pin")
    		   ?pin t
    		   ?termName sourceName
    		   ?justification "right"
    		   ?width if(sourceContact sdWidth diffPolyEnclose)
    		   ?beginOffset pinEndOffset
    		   ?endOffset pinEndOffset
    		)
    	     )
    	     arg
    	 )
             ?subRect
    	 setof(arg
    	     list(
    		;  Define the drain contact array.
    		when(drainContact
    		    list(
    		       ?layer       list(contLayer "drawing")
    		       ?justification "left"
    		       ?sep polyContSep
    		       ?beginOffset -(polyExtend + diffContEnclose)
    		       ?endOffset   -(polyExtend + diffContEnclose)
    		    )
    		)
    		;  Define the source contact array.
    		when(sourceContact
    		    list(
    		       ?layer       list(contLayer "drawing")
    		       ?justification "right"
    		       ?sep polyContSep
    		       ?beginOffset -(polyExtend + diffContEnclose)
    		       ?endOffset   -(polyExtend + diffContEnclose)
    		    )
    		)
    		;  Define the gate pins.
    		list(
    		   ?layer       list(polyLayer "pin")
    		   ?pin t
    		   ?termName gateName
    		   ?width length
    		   ?length grid
    		   ?space width - 2*grid
    		)
    	     )
    	     arg
    	 )
          )
          rodCreateRect(
    	?layer contLayer
    	?width 2.0
    	?length 3.0
    	)
    
          ;------------------------------------------------------------------
          ; Dimensions for auto-abutment 
          ; This is fairly simplistic, and in the case of different sized
          ; devices it can end up with the spacing between gates not quite
          ; as tight as possible in some cases. However, it demonstrates
          ; the principle.
          ; These dimensions are used in the abut function
          ;------------------------------------------------------------------
          pcCellView~>sameWidthDist=-diffPolyEnclose
          pcCellView~>diffWidthDist=polyDiffSep-diffPolyEnclose
    
          ;------------------------------------------------------------------
          ; Prevent overlap markers
          ;------------------------------------------------------------------
          pcCellView~>lxBlockOverlapCheck=t
    
          ;------------------------------------------------------------------
          ; Add auto-abutment properties
          ;------------------------------------------------------------------
          foreach(pin dbFindTermByName(pcCellView "S")~>pins
    	  pin~>fig~>abutFunction="abAbutFunction"
    	  pin~>fig~>abutAccessDir='("right")
          )
          foreach(pin dbFindTermByName(pcCellView "D")~>pins
    	  pin~>fig~>abutFunction="abAbutFunction"
    	  pin~>fig~>abutAccessDir='("left")
          )
    
       )
    )
    
    

    Best Regards,

    Andrew.

    • Post Points: 20
  • Wed, Apr 8 2009 5:12 AM

    • infy
    • Not Ranked
    • Joined on Fri, Jul 18 2008
    • Posts 14
    • Points 250
    Re: Implementing flow control in rodCreatePath function Reply

     hi,

    I am trying to implementing a bus structure with number of offset subpaths controlled by "number" variable in for loop .The program is as

    follows:

    procedure( bus(cv layer)
    (let (tfId layerWidth layerSpace number)
    tfId = techGetTechFile(cv)
    layerWidth = techGetSpacingRule(tfId "minWidth" layer)
    layerSpace = techGetSpacingRule(tfId "minSpacing" layer)
    rodCreatePath(
    ?name "bus"
    ?layer layer
    ?pts list(20:-20 40:-20 40:-30 80:-30)
    ?width layerWidth
    ?justification "center"
    ?cvId cv
    ?offsetSubPath

    list(

    for( i 0  (i<number)

    list(
    ?layer layer
    ?justification "left"
    ?sep (layerSpace * (i+1)) + (layerWidth * i)
    ) ;end subpath

    );for

    ) ;end list of lists
    ) ;end rodCreatePath
    ) ; end of let
    ) ; end of procedure

     when trying to execute the program, the following error is being reported.

    *ERROR* for: Final value must be integer - nil.

    so , please can you help me point the mistake in the code .

    Thanks & Regards,

    Infy

    • Post Points: 20
  • Wed, Apr 8 2009 7:14 AM

    • gsimard
    • Top 500 Contributor
    • Joined on Fri, Mar 20 2009
    • Posts 21
    • Points 465
    Re: Implementing flow control in rodCreatePath function Reply

     Cadence is complaining rightfully that the third parameter to for( is not an integer.

     You wrote: for( i 0 (i<number) ...

    Where it should read: for( i 0 number-1 ...

    In a for construct, the third parameter is the final value (an integer) for your variable i. You instead provided a test function which evaluates to nil.

     

    Guillaume

    • Post Points: 20
  • Wed, Apr 8 2009 3:10 PM

    Re: Implementing flow control in rodCreatePath function Reply

     And also even with the right syntax, doing:

    list(for(i 0 number-1 list(...)))

    is not going to generate a list of lists. for() returns t, not a list of the last values.

    If that's what  you want,  then use this macro:

    defmacro(CCSforMap (loop start stop @rest body)
      `let((_newList)
         for(,loop ,start ,stop
           _newList=tconc(_newList {,@body})
         )
         car(_newList)
       )
    )
    

    I put it in C-like syntax to avoid scaring anyone ;-)

    And then use CCSforMap instead of list(for(...)) in your code (using Guillaume's correction first, of course).

    The macro will do things like this:

    CCSforMap(i 0 10 list(i i*2))
    => ((0 0)
        (1 2)
        (2 4)
        (3 6)
        (4 8)
        (5 10)
        (6 12)
        (7 14)
        (8 16)
        (9 18)
        (10 20)
    )

    Or it might just be easier to build the list before you call rodCreatePath and pass it using a variable?

    Regards,

    Andrew.

     

    • Post Points: 35
  • Fri, Apr 10 2009 9:19 AM

    Re: Implementing flow control in rodCreatePath function Reply

     A macro, defined by defmacro, is a special form which replaces its call by the definition. The arguments to the definition are expanded in the macro. The backquote  {'} is a special template form which allows selective evaluation of variables which are preceded by the comma (,) so the variables ,loop ,start and ,stop contain the evaluated arguments in the expanded macro. The comma-at (,@) evaluates the variable and the result must be a list. The elements of the list (not the list) replace the original form.

    Macros are advanced stuff, very powerful when used correctly.  Use the command exandMacro during debugging. 

    • Post Points: 5
  • Sun, Apr 12 2009 11:25 PM

    • infy
    • Not Ranked
    • Joined on Fri, Jul 18 2008
    • Posts 14
    • Points 250
    Re: Implementing flow control in rodCreatePath function Reply

     Hi,

    Thanks for all your suggestions.Using macros seemed complicated to me.So I resolved to go with the process of  creation of lists outside rodCreatePath function and send, so created lists to Offset Subpath variable. By creating list variables outside the function and sending these fixed list variables has worked successfully.Now I am trying to send varible lists with the use of for loop and user input for controlling the list variables sent ,and hence the number of  wires in the bus structure. Please do send me some suggestions how well can we send this list variables.

    Regards,

    Infy

     

    • Post Points: 20
  • Wed, Apr 15 2009 2:01 AM

    Re: Implementing flow control in rodCreatePath function Reply

    Perhaps this example code will clarify things?

    Regards,

    /* abCreateBus.il
    
    Author     A.D.Beckett
    Group      Custom IC (UK), Cadence Design Systems Ltd.
    Language   SKILL
    Date       Mar 30, 1999 
    Modified   Mar 20, 2009 
    By         A.D.Beckett
    
    An example of creating a bus using ROD.
    
    The points could of course be specified by something like enterPath()
    in practice.
    
    Mar 20, 2009. Added new optional busPrefix to allow wires the be
    on named nets.
    
    ***************************************************
    
    SCCS Info: @(#) abCreateBus.il 03/20/09.12:59:54 1.2
    
    */
    
    /******************************************************************
    *                                                                 *
    *        abCreateBus(cv layer points numWires [busPrefix])        *
    *                                                                 *
    * Create a bus with given points, in the specified cellView, with *
    *                 the specified number of wires.                  *
    *                                                                 *
    ******************************************************************/
    
    procedure( abCreateBus(cv layer points numWires @optional busPrefix)
      let( (tfId layerWidth layerSpace offsetPaths)
        /* get technology file information */
        tfId = techGetTechFile(cv)
        layerWidth = techGetSpacingRule(tfId "minWidth" layer)
        layerSpace = techGetSpacingRule(tfId "minSpacing" layer)
        /* construct the list of sub paths */
        for(bit 1 numWires-1
          offsetPaths=tconc(offsetPaths
    	list(
    	  ?netName when(busPrefix sprintf(nil "%s<%d>" busPrefix bit))
    	  ?layer layer
    	  ?justification "left"
    	  ?sep layerSpace*bit + layerWidth*(bit-1)
    	  )
    	)
          )
        rodCreatePath(
    ;      ?name "bus"
          ?netName when(busPrefix sprintf(nil "%s<0>" busPrefix))
          ?layer layer
          ?pts points
          ?width layerWidth
          ?justification "center"
          ?cvId cv
          ?offsetSubPath car(offsetPaths)
          )
        ); let
      );
    

    Andrew.

    • Post Points: 20
  • Wed, Apr 15 2009 2:33 AM

    • Infy1
    • Not Ranked
    • Joined on Thu, Apr 9 2009
    • Posts 7
    • Points 95
    Re: Implementing flow control in rodCreatePath function Reply

    Hi Andrew ,

    I tried in the method suggested by you  to create a metal bus form which accepts width of wires in bus structure and no of wires from user ,the form also has layer and snap mode cyclic fields.I used mostly CCSslotMetal.il  pgm as blue print to accept width ,layer cyclic field and snap.In the main function which create a bus structure I wanted to control the number of wires to be accepted from user.So for this I tried sending that  through enterPath function.

    But  CCSmetBusCB function through which I was sending the number (variablefor controlling no of wires). There was an error i CIW stating that variable should be a list type template.So can u help me out.

    Below is my pgm ,which creates metalbus structure with 10 wires.

    *****************************************************************************************************************************************************

    procedure(CCSmetBus()
      let( (form)
     if(boundp('CCSmetBusForm) && CCSmetBusForm then
          form = CCSmetBusForm
        else
          form = CCScreateMetBusForm()
        ); if
        when(hiIsForm(form)
          enterPath(
            ?prompts        list("Enter points for Metal Bus path")
            ?form           form
            ?points         nil
            ?doneProc       "CCSmetBusDoneProc"
            ?addPointProc   "CCSmetBusPoints"
            ?delPointProc   "CCSmetBusPoints"
            ?pathWidth      form->width->value
           ;?acceptString  form->number->value
            ?alwaysMap      t
            ?cmdName        "CCSmetBus"
          ); enterPath
        ); when the form exists
      ); let
    ); procedure CCSmetBus

    procedure(CCScreateMetBusForm()
      let( (width number layer snap snapModes form cv techId)
        if(cv = geGetEditCellView(hiGetCurrentWindow()) then
          if(techId = techGetTechFile(cv) then
     width = hiCreateFloatField(
              ?name 'width
              ?prompt "Width"
              ?value 1.0
              ?range list(0.3 2.0)
              ?callback "CCSchangeMetBusWidth()"
              ); hiCreateFloatField
     number = hiCreateFloatField(
                ?name 'number
                ?prompt "Number"
                ?value 1.0
                ?range list(1.0 100.0)
                ?callback "CCSchangeMetBusNumber()"
                ); hiCreateFloatField
    snapModes = list("orthogonal" "L90XFirst" "L90YFirst")
            snap = hiCreateCyclicField(
              ?name 'snap
              ?choices      snapModes
              ?prompt       "Snap mode"
              ?value        car(member(envGetVal("layout" "snapMode")
                              snapModes)) || "orthogonal"
              ?callback     "CCSchangeMetBusSnap()"
            ); hiCreateCyclicField
    layer = hiCreateLayerCyclicField(
              techId
              "Layer"
              ""
              leGetValidLayerList(techId) || list(leGetEntryLayer(techId))
              leGetEntryLayer(techId)
              'layer
            ); hiCreateLayerCyclicField
     form = hiCreateAppForm(
              ?name 'CCSmetBusForm
              ?formTitle "Metal Bus"
              ?formType     'options
              ?buttonLayout 'HideCancelDef
              ?fields list( list(width 0:0 100:30 50)
                list(snap 120:0 100:30 70)
                list(number 0:30 200:30 50)
               list(layer 0:90 200:30 50))
            ); hiCreateAppForm
     leSetFormSnapMode(form->snap->value)
            CCSshieldMetalForm = form
          else
            error("Could not obtain technology information")
          ); if the technology information can be obtained
        else
          error("Shield metal functions require a cellview to be current")
        ); if a current cellview exists
      ); let
    ); procedure CCScreateMetBusForm

    procedure(CCSchangeMetBusWidth()
      let( (origWidth)
        when(boundp('CCSmetBusForm) && CCSmetBusForm
          origWidth = CCSmetBusForm->width->value
          CCSmetBusForm->width->value = origWidth
          unless(CCSmetBusForm->currentWidth == CCSmetBusForm->width->value
            CCSmetBusForm->currentWidth = CCSmetBusForm->width->value
          ); unless
          changeEnterFun(
            'enterPath
            ?pathWidth      CCSmetBusForm->width->value
            ;?acceptString     CCSmetBusForm->number->value
            ?doneProc       "CCSmetBusDoneProc"
            ?points         CCSmetBusForm->points
            ?addPointProc   "CCSmetBusPoints"
            ?delPointProc   "CCSmetBusPoints"
            ?prompts        list("Enter points for Metal Bus path")
            ?form           CCSmetBusForm
          ); changeEnterFun
        ); when the form exists
      ); let
    ); procedure CCSchangeMetBusWidth

    procedure(CCSchangeMetBusNumber()
      let( (defaultNumber)
        when(boundp('CCSmetBusForm) && CCSmetBusForm
          defaultNumber= CCSmetBusForm->number->value
          CCSmetBusForm->number->value = defaultNumber
          unless(CCSmetBusForm->currentNumber == CCSmetBusForm->number->value
            CCSmetBusForm->currentNumber = CCSmetBusForm->number->value
          ); unless
          changeEnterFun(
            'enterPath
            ?pathWidth      CCSmetBusForm->width->value
            ;?acceptString     CCSmetBusForm->number->value
            ?doneProc       "CCSmetBusDoneProc"
            ?points         CCSmetBusForm->points
            ?addPointProc   "CCSmetBusPoints"
            ?delPointProc   "CCSmetBusPoints"
            ?prompts        list("Enter points for Metal Bus path")
            ?form           CCSmetBusForm
          ); changeEnterFun
        ); when the form exists
      ); let
    ); procedure CCSchangeMetBusNumber

    procedure(CCSchangeMetBusSnap()
      when(boundp('CCSmetBusForm) && CCSmetBusForm
        CCSmetBusForm->origSnap =
          leSetFormSnapMode(CCSmetBusForm->snap->value)
      ); when the form exists
    ); procedure CCSchangeMetBusSnap

    procedure(CCSmetBusPoints(win points "wl")
      when(windowp(win)
        ;; keep track of the points for when the enterFunction is changed
        CCSmetBusForm->points = points
      )
    ); procedure CCSmetBusPoints

    procedure(CCSmetBusDoneProc(win done points "wgl")
      let( ( form )
        when(boundp('CCSmetBusForm) && CCSmetBusForm
          form   = CCSmetBusForm
          if(done then
            ;; reset the currentWidth variable stored on the form
            ;; and reset the points list stored on the form
            form->currentWidth = nil
            form->currentNumber = nil
            form->points = nil
            CCSmetBusCB(
              win->cellView
              form->width->value
    ;          form->number->value
              CCSgetLPPfromLayerCyclic(form->layer->value)
              points
            )
          else
            ;; put back the most recent previous snap mode
            when(CCSmetBusForm->origSnap
              leSetFormSnapMode(CCSmetBusForm->origSnap)
            ); when
          ); if done
        ); when form exists
      ); let
    ); procedure CCSmetBusDoneProc

    procedure(CCSmetBusCB(cv width  layer points  "dfll")
    if( (width >=  techGetSpacingRule(techGetTechFile(cv) "minWidth" layer)) then
    layerWidth = width
    );if
    layerSpace = techGetSpacingRule(techGetTechFile(cv) "minSpacing" layer)
    let((a b n)
    b = list()
    a = list()

    number = 10

    n = number
    for(i 0 n-2
    a= list(
                                ?layer      layer
                                ?justification "left"
                                ?width layerWidth
                                ?sep  ( layerSpace * (i+1)) + ( layerWidth * i)
                                ?choppable  t
                               )
    b = cons(a b)
    );for
    b = reverse(b)
    rodCreatePath(
          ?cvId             cv
          ?layer            layer
          ?width            layerWidth
          ?pts              points
          ?justification "center"
          ?choppable  t
          ?offsetSubPath    b
       ); rodCreatePath
      );let
    ); procedure CCSmetBusCB

    procedure(CCSgetLPPfromLayerCyclic(layCyc "l")
      parseString(
        buildString(
          parseString(cadddr(layCyc) "()")
          ""
        )
      )
    ); procedure CCSgetLPPfromLayerCyclic

    CCSmetBus()

    ************************************************************************************************************************************************

    Regards,

    Roy

    • Post Points: 20
  • Wed, Apr 15 2009 8:28 AM

    Re: Implementing flow control in rodCreatePath function Reply

           ?pathWidth      form->width->value
           ;?acceptString  form->number->value
    This is not how to use acceptString, this keyword is to allow you to enter a string in the CIW without terminating the enterFunction (EF). Even though this is commented out, you need to read the documentation on how to use the EF. This is in the Cadence User Interface SKILL Reference.

     You did not say what the line was which is causing the error. Set the variable _stacktrace = 5 then execute the code. Cut the error message out and paste it into your response and we can see what the problem really is.

     An aside: the let statement sets the variables a and b to the empty list (nil) so you do not have to do so again in your code: a = list()

    Ted

    • Post Points: 20
  • Thu, Apr 16 2009 9:12 PM

    • Infy1
    • Not Ranked
    • Joined on Thu, Apr 9 2009
    • Posts 7
    • Points 95
    Re: Implementing flow control in rodCreatePath function Reply

    hi,

    Thanks for correcting me.I 've executed the code by setting the variable _stacktrace = 5.

    The line that is causing error is :

     *Error* CCSmetBusCB: argument #3 should be a list (type template = "dfll") - 2.0.

    Thsnks & Regards,

    Roy

    • Post Points: 20
  • Fri, Apr 17 2009 1:42 AM

    Re: Implementing flow control in rodCreatePath function Reply

    Roy,

    You didn't give the stack trace output, but it's fairly obvious from looking at the code that the function:

    procedure(CCSmetBusCB(cv width  layer points  "dfll")

    is expecting the 3rd argument to a layer purpose pair. The code as you sent it does not give an error - so I assume this was because you were calling this function:

            CCSmetBusCB(
              win->cellView
              form->width->value
    ;          form->number->value
              CCSgetLPPfromLayerCyclic(form->layer->value)
              points
            )

    with the number argument not commented?

    Clearly you would have to pass number into the CCSmetBusCB function, and update the argument list appropriately. I also think that it makes more sense for the number field to be an integer rather than float field (since you can't draw 2.5 bus wires!).

    Overall I've changed the code below:

    procedure(CCSmetBus()
      let( (form)
     if(boundp('CCSmetBusForm) && CCSmetBusForm then
          form = CCSmetBusForm
        else
          form = CCScreateMetBusForm()
        ); if
        when(hiIsForm(form)
          enterPath(
            ?prompts        list("Enter points for Metal Bus path")
            ?form           form
            ?points         nil
            ?doneProc       "CCSmetBusDoneProc"
            ?addPointProc   "CCSmetBusPoints"
            ?delPointProc   "CCSmetBusPoints"
            ?pathWidth      form->width->value
           ;?acceptString  form->number->value
            ?alwaysMap      t
            ?cmdName        "CCSmetBus"
          ); enterPath
        ); when the form exists
      ); let
    ); procedure CCSmetBus
    
    procedure(CCScreateMetBusForm()
      let( (width number layer snap snapModes form cv techId)
        if(cv = geGetEditCellView(hiGetCurrentWindow()) then
          if(techId = techGetTechFile(cv) then
     width = hiCreateFloatField(
              ?name 'width
              ?prompt "Width"
              ?value 1.0
              ?range list(0.3 2.0)
              ?callback "CCSchangeMetBusWidth()"
              ); hiCreateFloatField
    ;; ADB changed to integer field
     number = hiCreateIntField(
                ?name 'number
                ?prompt "Number"
                ?value 1
                ?range list(1 100)
    ;; ADB - I don't think this is really needed, as it doesn't affect
    ;; anything. It's not like the width, where you want the ghost image of
    ;; the path to change.
                ?callback "CCSchangeMetBusNumber()"
                ); hiCreateFloatField
    snapModes = list("orthogonal" "L90XFirst" "L90YFirst")
            snap = hiCreateCyclicField(
              ?name 'snap
              ?choices      snapModes
              ?prompt       "Snap mode"
              ?value        car(member(envGetVal("layout" "snapMode")
                              snapModes)) || "orthogonal"
              ?callback     "CCSchangeMetBusSnap()"
            ); hiCreateCyclicField
    layer = hiCreateLayerCyclicField(
              techId
              "Layer"
              ""
              leGetValidLayerList(techId) || list(leGetEntryLayer(techId))
              leGetEntryLayer(techId)
              'layer
            ); hiCreateLayerCyclicField
     form = hiCreateAppForm(
              ?name 'CCSmetBusForm
              ?formTitle "Metal Bus"
              ?formType     'options
              ?buttonLayout 'HideCancelDef
              ?fields list( list(width 0:0 100:30 50)
                list(snap 120:0 100:30 70)
                list(number 0:30 200:30 50)
               list(layer 0:90 200:30 50))
            ); hiCreateAppForm
     leSetFormSnapMode(form->snap->value)
            CCSshieldMetalForm = form
          else
            error("Could not obtain technology information")
          ); if the technology information can be obtained
        else
          error("Shield metal functions require a cellview to be current")
        ); if a current cellview exists
      ); let
    ); procedure CCScreateMetBusForm
    
    procedure(CCSchangeMetBusWidth()
      let( (origWidth)
        when(boundp('CCSmetBusForm) && CCSmetBusForm
          origWidth = CCSmetBusForm->width->value
          CCSmetBusForm->width->value = origWidth
          unless(CCSmetBusForm->currentWidth == CCSmetBusForm->width->value
            CCSmetBusForm->currentWidth = CCSmetBusForm->width->value
          ); unless
          changeEnterFun(
            'enterPath
            ?pathWidth      CCSmetBusForm->width->value
            ;?acceptString     CCSmetBusForm->number->value
            ?doneProc       "CCSmetBusDoneProc"
            ?points         CCSmetBusForm->points
            ?addPointProc   "CCSmetBusPoints"
            ?delPointProc   "CCSmetBusPoints"
            ?prompts        list("Enter points for Metal Bus path")
            ?form           CCSmetBusForm
          ); changeEnterFun
        ); when the form exists
      ); let
    ); procedure CCSchangeMetBusWidth
    
    procedure(CCSchangeMetBusNumber()
      let( (defaultNumber)
        when(boundp('CCSmetBusForm) && CCSmetBusForm
          defaultNumber= CCSmetBusForm->number->value
          CCSmetBusForm->number->value = defaultNumber
          unless(CCSmetBusForm->currentNumber == CCSmetBusForm->number->value
            CCSmetBusForm->currentNumber = CCSmetBusForm->number->value
          ); unless
          changeEnterFun(
            'enterPath
            ?pathWidth      CCSmetBusForm->width->value
            ;?acceptString     CCSmetBusForm->number->value
            ?doneProc       "CCSmetBusDoneProc"
            ?points         CCSmetBusForm->points
            ?addPointProc   "CCSmetBusPoints"
            ?delPointProc   "CCSmetBusPoints"
            ?prompts        list("Enter points for Metal Bus path")
            ?form           CCSmetBusForm
          ); changeEnterFun
        ); when the form exists
      ); let
    ); procedure CCSchangeMetBusNumber
    
    procedure(CCSchangeMetBusSnap()
      when(boundp('CCSmetBusForm) && CCSmetBusForm
        CCSmetBusForm->origSnap =
          leSetFormSnapMode(CCSmetBusForm->snap->value)
      ); when the form exists
    ); procedure CCSchangeMetBusSnap
    
    procedure(CCSmetBusPoints(win points "wl")
      when(windowp(win)
        ;; keep track of the points for when the enterFunction is changed
        CCSmetBusForm->points = points
      )
    ); procedure CCSmetBusPoints
    
    procedure(CCSmetBusDoneProc(win done points "wgl")
      let( ( form )
        when(boundp('CCSmetBusForm) && CCSmetBusForm
          form   = CCSmetBusForm
          if(done then
            ;; reset the currentWidth variable stored on the form
            ;; and reset the points list stored on the form
            form->currentWidth = nil
            form->currentNumber = nil
            form->points = nil
            CCSmetBusCB(
              win->cellView
              form->width->value
    ;; ADB - removed comment so that number is now passed
              form->number->value
              CCSgetLPPfromLayerCyclic(form->layer->value)
              points
            )
          else
            ;; put back the most recent previous snap mode
            when(CCSmetBusForm->origSnap
              leSetFormSnapMode(CCSmetBusForm->origSnap)
            ); when
          ); if done
        ); when form exists
      ); let
    ); procedure CCSmetBusDoneProc
    
    ;; ADB - Added number as a formal argument (x in type template)
    procedure(CCSmetBusCB(cv width number layer points  "dfxll")
    ;; ADB - some local variables here wouldn't go amiss! Try running through
    ;; SKILL Lint to see what it says
    if( (width >=  techGetSpacingRule(techGetTechFile(cv) "minWidth" layer)) then
    layerWidth = width
    );if
    layerSpace = techGetSpacingRule(techGetTechFile(cv) "minSpacing" layer)
    let((a b n)
    b = list()
    a = list()
    
    ;; ADB - removed hard coding of number
    ; number = 10
    
    n = number
    for(i 0 n-2
    a= list(
                                ?layer      layer
                                ?justification "left"
                                ?width layerWidth
                                ?sep  ( layerSpace * (i+1)) + ( layerWidth * i)
                                ?choppable  t
                               )
    b = cons(a b)
    );for
    b = reverse(b)
    rodCreatePath(
          ?cvId             cv
          ?layer            layer
          ?width            layerWidth
          ?pts              points
          ?justification "center"
          ?choppable  t
          ?offsetSubPath    b
       ); rodCreatePath
      );let
    ); procedure CCSmetBusCB
    
    procedure(CCSgetLPPfromLayerCyclic(layCyc "l")
      parseString(
        buildString(
          parseString(cadddr(layCyc) "()")
          ""
        )
      )
    ); procedure CCSgetLPPfromLayerCyclic
    
    

    Regards,

    Andrew.

    • Post Points: 20
  • Fri, Apr 17 2009 2:52 AM

    • Infy1
    • Not Ranked
    • Joined on Thu, Apr 9 2009
    • Posts 7
    • Points 95
    Re: Implementing flow control in rodCreatePath function Reply

     hi,

    Thanks Andrew.It's working !!!!

    Regards,

    Roy

    • Post Points: 5
Page 1 of 1 (13 items)
Sort Posts:
Started by infy at 06 Apr 2009 10:01 PM. Topic has 12 replies.