• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Community Forums
  2. Custom IC SKILL
  3. Issue in script to modify a routing blockage in Cadence...

Stats

  • Locked Locked
  • Replies 4
  • Subscribers 144
  • Views 13819
  • Members are here 0
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Issue in script to modify a routing blockage in Cadence SKILL

elgunidy91
elgunidy91 over 9 years ago

I created 2 procedures in SKILL 

The first takes 2 points "for ex: list(x:y)" and take a list of points returned by the command blockage_id~>points, and tries to find if those 2 points found on the returned list.. 
findPointsInList(pt1 pt2 ptList) .. returns 1 if successful or 0 otherwise 

The second procedure uses the first one in its "if" condition, but it doesn't work, which is illogical to me!! 

Hint: the many println() usages is for debugging. 

Code: 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 


;; Globals 
deltaX = 0.02 
deltaY = 0.02 
offset = 0.02 
cutWidth = 0.16 


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 

procedure( updateBlockage(id pts) 

prog( 
( 
list1 list2 list3 list4 x1 y1 x2 y2 x3 y3 x4 y4 rectId idBlkgMetal1 blkgPointList vartop varbottom 
x3TopBlkg y3TopBlkg x33TopBlkg y33TopBlkg x4TopBlkg y4TopBlkg x44TopBlkg y44TopBlkg 
) 

vartop = 0 
varbottom = 0 
list1 = list() 
list2 = list() 
list3 = list() 
list4 = list() 
blkgPointList = list() 

arr=listToVector(pts) 
list1 = arr[0] 
list2 = arr[1] 
list3 = arr[2] 
list4 = arr[3] 
pts=vectorToList(arr) 

x1 = car(list1) 
y1 = car(cdr(list1)) 
x2 = car(list2) 
y2 = car(cdr(list2)) 
x3 = car(list3) 
y3 = car(cdr(list3)) 
x4 = car(list4) 
y4 = car(cdr(list4)) 

idBlkgMetal1 = id 
blkgPointList = idBlkgMetal1~>points 




;;;;;;;;;;;;;; 
;Top blockage; 
;;;;;;;;;;;;;; 
x3TopBlkg = x3 + deltaX 
y3TopBlkg = y3 + deltaY 
x4TopBlkg = x4 - deltaX 
y4TopBlkg = y4 + deltaY 

x33TopBlkg = x3TopBlkg + offset 
y33TopBlkg = y3TopBlkg + cutWidth 
x44TopBlkg = x4TopBlkg - offset 
y44TopBlkg = y4TopBlkg + cutWidth 


;println("x3TopBlkg=") 
;println(x3TopBlkg) 
;println("y3TopBlkg=") 
;println(y3TopBlkg) 
;println("x4TopBlkg=") 
;println(x4TopBlkg) 
;println("y4TopBlkg=") 
;println(y4TopBlkg) 
;println("==========") 

  ;;Top Blockage 
  
  vartop = findPointsInList(list(x3TopBlkg y3TopBlkg) list(x4TopBlkg y4TopBlkg) blkgPointList) 
  println("vartop = ") 
  println(vartop) 

  when(  equal( vartop 1 )   

                println("Hi from top!") 

                leChopShape( idBlkgMetal1 list(x33TopBlkg:y2 x33TopBlkg:y33TopBlkg x44TopBlkg:y44TopBlkg x44TopBlkg:y1) t t 10 ) 

                procedure(myFilterProc(objId) 
                if(objId~>objType=="rect" t nil) 
                ) 
                rectId = gePointQuery( hiGetCurrentWindow() x3:y3 "myFilterProc") 
                leStretchShape( rectId list( 0 cutWidth ) 
                list(nil t t nil) t ) 

                leStretchShape( rectId list(offset 0) 
                list(nil nil t t) t ) 

                leStretchShape( rectId list(-offset 0) 
                list(t t nil nil) t ) 
                                                 
        );when 


);prog 
);proc 



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 

procedure( findPointsInList(pt1 pt2 ptList) 
        prog( (pt1found pt2found flag1 flag2 sum cond1 cond2 cond3 cond4 cond5 cond6) 

                sum = 0 
                pt1found = 0 
                pt2found = 0 
                flag1 = 1 
                flag2 = 1 
                cond1 = 0 
                cond2 = 0 
                cond3 = 0 
                cond4 = 0 
                cond5 = 0 
                cond6 = 0 
         
                ;println("pt1found =") 
                ;println(pt1found) 
                ;println("pt2found =") 
                ;println(pt2found) 
                ;println("sum =") 
                ;println(sum)         


                foreach( pt ptList 
                        ;println("pt =") 
                        ;println(pt) 
                        ;println("pt1") 
                        ;println(pt1) 
                         
                        cond1 = equal(flag1 1) 
                        cond2 = equal(float(car(pt)) float(car(pt1))) 
                        cond3 = equal(float(car(cdr(pt))) float(car(cdr(pt1)))) 

                        cond4 = equal(flag2 1) 
                        cond5 = equal(float(car(pt)) float(car(pt2))) 
                        cond6 = equal(float(car(cdr(pt))) float(car(cdr(pt2)))) 

                        ;println("Blkg pt") 
                        ;println(pt) 
                        ;println("pt1 ") 
                        ;println(pt1) 
                        ;println("pt2") 
                        ;println(pt2) 
                        ;println(cond1)                                                 
                        ;println(cond2)                                                 
                        ;println(cond3)                                                 
                        ;println(cond4)                                                 
                        ;println(cond5)                                                 
                        ;println(cond6) 
                        ;println("=========") 
                                                 
                         
                        when( cond1 && cond2 && cond3 
                                                ;println("I am section 1!") 
                                                pt1found = 1 
                                                flag1 = 0 
                        ); 
                         
                        when( cond4 && cond5 && cond6 
                                                ;println("I am section 2!") 
                                                pt2found = 1 
                                                flag2 = 0 
                        );when4 
                                                 
                                                 
                );foreach 

                sum = pt1found + pt2found 
         
                ;println("after evaluation:") 
                ;println("pt1found =") 
                ;println(pt1found) 
                ;println("pt2found =") 
                ;println(pt2found) 
                ;println("sum =") 
                ;println(sum)         

                 
                if( equal( sum 2) then 
                        return(1) 
                else 
                        return(0) 
                );if         

                 

        );prog 
);proc 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 

I hope someone helps me. 

Thank you! 
Abdullah 

  • Cancel
Parents
  • Sheppy
    Sheppy over 9 years ago

    Hi Abdullah,

    I think Lawrence is right. It has to do with comparing floating point numbers. On numerous occasions I have ran into this problem and my solution to solve this "once and for all" is that before I do anything with a value (either a given value or a calculated one) is to round it to the design/database grid. I wrote a procedure which allows me to do it easily and always in the same way. It gives me control over the rounding too: either up, down or automatic rounding. I can even specify the accuracy of the rounding (which is by default set to the value Lawrence suggested: 1e-6 -> what are the odds of that!). Please have a look below for my code:

    ;;; spdk = abbreviation of our PDK name
    procedure( spdkPutOnGrid( value grid direction @optional ( accuracy 1e-6 ) )
        let( (  ( onGrid nil )
            ( theTest 0.0 ) )
        
            unless( fixp( value ) || floatp( value )
                error( "spdkPutOnGrid: argument #1 should be a integer or float - %L" value )
            ) ;;; end of unless
            unless( fixp( grid ) || floatp( grid )
                error( "spdkPutOnGrid: argument #2 should be a integer or float - %L" grid )
            ) ;;; end of unless
            unless( equal( lowerCase( direction ) "up" ) || equal( lowerCase( direction ) "down" ) || equal( lowerCase( direction ) "auto" )
                error( "spdkPutOnGrid: argument #3 should be a string, possible input: \"up\" or \"down\" or \"auto\" - %L" direction )
            ) ;;; end of unless
            unless( accuracy < 1.0
                error( "spdkPutOnGrid: argument #4 should be smaller then 1 (argument 4 sets the accuracy) - %L" accuracy )
            ) ;;; end of unless
            
            if( !zerop( value )
            then
                case( lowerCase( direction )
                    ( "up"
                        onGrid = atoi( sprintf( nil "%f" float( value / grid ) ) ) * grid
                        unless( abs( ( value - onGrid ) / value ) < ( grid * accuracy )
                            if( negativep( value )
                            then
                                onGrid = onGrid
                            else
                                onGrid = onGrid + grid
                            ) ;;; end of if
                        ) ;;; end of unless
                    )
                    ( "down"
                        onGrid = atoi( sprintf( nil "%f" float( value / grid ) ) ) * grid
                        unless( abs( ( value - onGrid ) / value ) < ( grid * accuracy )
                            if( negativep( value )
                            then
                                onGrid = onGrid - grid
                            else
                                onGrid = onGrid
                            ) ;;; end of if
                        ) ;;; end of unless
                    )
                    ( "auto"
                        ;;; If value=12.75 and grid=0.1, the output should be 12.8
                        ;;; However, the output is 12.7. The calculation in the "theTest" statement
                        ;;; results in something slightly less than 0.5, so it would round-down...
                        ;;; Therefor, the third condition is added: if the difference is small relative
                        ;;; to the grid,
    the remainder is regarded as a half (0.5), thus round-up.
                        onGrid = atoi( sprintf( nil "%f" float( value / grid ) ) ) * grid
                        theTest = ( float( value ) - onGrid ) / grid
                        cond(
                            ( theTest == 0.0
                                onGrid = onGrid
                            )
                            ( theTest > 0.5
                                onGrid = onGrid + grid
                            )
                            ( abs( ( theTest - 0.5 ) / theTest ) < ( grid * accuracy )
                                onGrid = onGrid + grid
                            )
                            ( t
                                onGrid = onGrid
                            )
                        ) ;;; end of cond
                    )
                ) ;;; end of case
            else
                onGrid = 0
            ) ;;; end of if
            
            when( fixp( grid )
                onGrid = fix( onGrid )
            ) ;;; end of when
            when( floatp( grid )
                onGrid = float( onGrid )
            ) ;;; end of when
            
            ;;; Return the value...
            onGrid
            
        ) ;;; end let
    ) ;;; end of procedure spdkPutOnGrid

    This is how you use it:

    spdkPutOnGrid( 1.2345 0.01 "up" )
    -> 1.24

    spdkPutOnGrid( 1.2345 0.01 "down" )
    -> 1.23

    spdkPutOnGrid( 1.2345 0.01 "auto" )
    -> 1.23

    This is what you could do:

    ;;;;;;;;;;;;;; 
    ;Top blockage; 
    ;;;;;;;;;;;;;;
    dbGrid = 0.01
    rounding = "auto"

    x3TopBlkg = spdkPutOnGrid( ( x3 + deltaX ) dbGrid rounding )
    y3TopBlkg = spdkPutOnGrid( ( y3 + deltaY ) dbGrid rounding )
    x4TopBlkg = spdkPutOnGrid( ( x4 - deltaX ) dbGrid rounding )
    y4TopBlkg = spdkPutOnGrid( ( y4 + deltaY ) dbGrid rounding )

    Please try it, it will most likely solve your problem. It would also help to do the comparison like Lawrence suggests.

    With kind regards,

    Sjoerd

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Reply
  • Sheppy
    Sheppy over 9 years ago

    Hi Abdullah,

    I think Lawrence is right. It has to do with comparing floating point numbers. On numerous occasions I have ran into this problem and my solution to solve this "once and for all" is that before I do anything with a value (either a given value or a calculated one) is to round it to the design/database grid. I wrote a procedure which allows me to do it easily and always in the same way. It gives me control over the rounding too: either up, down or automatic rounding. I can even specify the accuracy of the rounding (which is by default set to the value Lawrence suggested: 1e-6 -> what are the odds of that!). Please have a look below for my code:

    ;;; spdk = abbreviation of our PDK name
    procedure( spdkPutOnGrid( value grid direction @optional ( accuracy 1e-6 ) )
        let( (  ( onGrid nil )
            ( theTest 0.0 ) )
        
            unless( fixp( value ) || floatp( value )
                error( "spdkPutOnGrid: argument #1 should be a integer or float - %L" value )
            ) ;;; end of unless
            unless( fixp( grid ) || floatp( grid )
                error( "spdkPutOnGrid: argument #2 should be a integer or float - %L" grid )
            ) ;;; end of unless
            unless( equal( lowerCase( direction ) "up" ) || equal( lowerCase( direction ) "down" ) || equal( lowerCase( direction ) "auto" )
                error( "spdkPutOnGrid: argument #3 should be a string, possible input: \"up\" or \"down\" or \"auto\" - %L" direction )
            ) ;;; end of unless
            unless( accuracy < 1.0
                error( "spdkPutOnGrid: argument #4 should be smaller then 1 (argument 4 sets the accuracy) - %L" accuracy )
            ) ;;; end of unless
            
            if( !zerop( value )
            then
                case( lowerCase( direction )
                    ( "up"
                        onGrid = atoi( sprintf( nil "%f" float( value / grid ) ) ) * grid
                        unless( abs( ( value - onGrid ) / value ) < ( grid * accuracy )
                            if( negativep( value )
                            then
                                onGrid = onGrid
                            else
                                onGrid = onGrid + grid
                            ) ;;; end of if
                        ) ;;; end of unless
                    )
                    ( "down"
                        onGrid = atoi( sprintf( nil "%f" float( value / grid ) ) ) * grid
                        unless( abs( ( value - onGrid ) / value ) < ( grid * accuracy )
                            if( negativep( value )
                            then
                                onGrid = onGrid - grid
                            else
                                onGrid = onGrid
                            ) ;;; end of if
                        ) ;;; end of unless
                    )
                    ( "auto"
                        ;;; If value=12.75 and grid=0.1, the output should be 12.8
                        ;;; However, the output is 12.7. The calculation in the "theTest" statement
                        ;;; results in something slightly less than 0.5, so it would round-down...
                        ;;; Therefor, the third condition is added: if the difference is small relative
                        ;;; to the grid,
    the remainder is regarded as a half (0.5), thus round-up.
                        onGrid = atoi( sprintf( nil "%f" float( value / grid ) ) ) * grid
                        theTest = ( float( value ) - onGrid ) / grid
                        cond(
                            ( theTest == 0.0
                                onGrid = onGrid
                            )
                            ( theTest > 0.5
                                onGrid = onGrid + grid
                            )
                            ( abs( ( theTest - 0.5 ) / theTest ) < ( grid * accuracy )
                                onGrid = onGrid + grid
                            )
                            ( t
                                onGrid = onGrid
                            )
                        ) ;;; end of cond
                    )
                ) ;;; end of case
            else
                onGrid = 0
            ) ;;; end of if
            
            when( fixp( grid )
                onGrid = fix( onGrid )
            ) ;;; end of when
            when( floatp( grid )
                onGrid = float( onGrid )
            ) ;;; end of when
            
            ;;; Return the value...
            onGrid
            
        ) ;;; end let
    ) ;;; end of procedure spdkPutOnGrid

    This is how you use it:

    spdkPutOnGrid( 1.2345 0.01 "up" )
    -> 1.24

    spdkPutOnGrid( 1.2345 0.01 "down" )
    -> 1.23

    spdkPutOnGrid( 1.2345 0.01 "auto" )
    -> 1.23

    This is what you could do:

    ;;;;;;;;;;;;;; 
    ;Top blockage; 
    ;;;;;;;;;;;;;;
    dbGrid = 0.01
    rounding = "auto"

    x3TopBlkg = spdkPutOnGrid( ( x3 + deltaX ) dbGrid rounding )
    y3TopBlkg = spdkPutOnGrid( ( y3 + deltaY ) dbGrid rounding )
    x4TopBlkg = spdkPutOnGrid( ( x4 - deltaX ) dbGrid rounding )
    y4TopBlkg = spdkPutOnGrid( ( y4 + deltaY ) dbGrid rounding )

    Please try it, it will most likely solve your problem. It would also help to do the comparison like Lawrence suggests.

    With kind regards,

    Sjoerd

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Children
No Data

Community Guidelines

The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information