• 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. Create custom ruler to report pre- or post-shrink value

Stats

  • Locked Locked
  • Replies 11
  • Subscribers 142
  • Views 6197
  • 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

Create custom ruler to report pre- or post-shrink value

Sheppie
Sheppie over 5 years ago

Hi,

We're working on a product in a technology which gets shrunk down. What we draw in the layout in a layout editor window, will be shrunk down by 0.855. So a drawn dimension of 1um (1000nm) becomes 0.855um (855nm). Currently we're in the floorplanning phase and in discussions about the final die-size. So every time I measure the new die-size (after more and more blocks report a more realistic area), I have to remember to apply this scaling factor before I report any new values.

With the bindkey <k>  the default ruler can be used to measure, and this ruler measures drawn dimensions. I'd like to have somehting like <shift.><k> to give me a ruler which applies the scaling factor to the measurement. Preferably in a different collor to be able to destinguish from one another.

Is this possible? Can I define my own ruler?

Thank you in advance.

With kind regards,

Sjoerd

  • Cancel
Parents
  • Andrew Beckett
    Andrew Beckett over 5 years ago

    Hi Sjoerd,

    I don't think this is possible currently, but I can see the utility of this. I would suggest you contact customer support and request this as an enhancement (I couldn't find a similar enhancement request so far, but I may not have searched sufficiently thoroughly).

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Sheppie
    Sheppie over 5 years ago in reply to Andrew Beckett

    Hi Andrew,

    Thanks for you initial response. I haven't looked at you second response yet, will do that after posting this response.

    Since you think it is not possible, I thought I might add something to the measurement function: redefinning the bindkey to my own procedure which post-processes the marker drawn. Please have a look at the code below.

    Fullscreen 0028.SCLLeHiCreateMeasurement.il.txt Download
    hiSetBindKey( "Layout" "<Key>K" "SCLLeHiCreateMeasurement( geGetEditCellView() 0.855 )" )
    
    procedure( SCLLeHiCreateMeasurement( cvId scaleFactor )
    	let( (	preMarkerList postMarkerList newMarkerList
    		points deltaX deltaY distance distanceScaled )
    
    		;;; First, before adding a new ruler, store the list of already present markers.
    		;;; The list after adding will be compared with this list, and the additions will be calculated and reported.
    		preMarkerList = cvId~>markers
    
    		;;; Call of the original procedure.
    		leHiCreateMeasurement()
    
    		;;; Now that the original procedure has finished, store a new list of Markers.
    		;;; Unfortunately, only after the measurement function has been escaped, this code will proceed.
    		postMarkerList = cvId~>markers
    
    		when( newMarkerList = car( last( SCLDiffOfLists( preMarkerList postMarkerList ) ) )
    			foreach( newMarker newMarkerList
    				points = newMarker~>points
    				deltaX = abs( difference( xCoord( car( points ) ) xCoord( cadr( points ) ) ) )
    				deltaY = abs( difference( yCoord( car( points ) ) yCoord( cadr( points ) ) ) )
    				distance = sqrt( plus( times( deltaX deltaX ) times( deltaY deltaY ) ) )
    				distanceScaled = times( distance scaleFactor )
    				printf( "%L %L\n" deltaX deltaY )
    				printf( "After scaling (%L * %L): %L\n" distance  scaleFactor distanceScaled )
    			) ;;; end of foreach newMarker
    		) ;;; end of when
    	) ;;; end of let
    ) ;;; end of procedure SCLLeHiCreateMeasurement
    
    /*
    This procedure performs a diff of two lists. It does not take order into account though.
    Please test the code to see what it does:
    SCLDiffOfLists( list( 1 2 3 4 1 2 3 4 ) list( 3 4 5 6 ) )
    The output should be:
    ((1 2 1 2 3 4) (3 4) (5 6))
    This means:
    (1 2 1 2 3 4) is in the first list, but not in the second.
    	As you can see, if a value appears more then once in list1, but only once in list2, it will report this too.
    	Since this functionality was needed, simply using somethink like setof(item list1 !member( item list2 )) wouldn't work.
    	With the setof implementation the output would be different: (1 2 1 2)
    (3 4) is in both lists.
    (5 6) is not in the first list, but it is in the second list.
    */
    procedure( SCLDiffOfLists( inList1 inList2 )
    	let( ()
    		unless( listp( inList1 )
    			error( "SCLDiffOfLists: argument #1 must be a list - %L" inList1 )
    		) ;;; end of unless
    		unless( listp( inList2 )
    			error( "SCLDiffOfLists: argument #2 must be a list - %L" inList2 )
    		) ;;; end of unless
    
    		list( SCLDiffOfListsCheck( inList1 inList2 ) SCLDiffOfListsCheck( inList1 inList2 "common" ) SCLDiffOfListsCheck( inList2 inList1 ) )
    	) ;;; end of let
    ) ;;; end of procedure SCLDiffOfLists
    
    
    procedure( SCLDiffOfListsCheck( inList1 inList2 @optional ( mode "diff" ) )
    	let( (	( outList nil )
    		( value1 nil ) ( check1 nil )
    		( check2 nil )
    		( occurrance1 nil ) ( occurrance2 nil ) )
    
    		unless( listp( inList1 )
    			error( "SCLDiffOfListsCheck: argument #1 must be a list - %L" inList1 )
    		) ;;; end of unless
    		unless( listp( inList2 )
    			error( "SCLDiffOfListsCheck: argument #2 must be a list - %L" inList2 )
    		) ;;; end of unless
    		unless( stringp( mode )
    			error( "SCLDiffOfListsCheck: argument #3 must be a string - %L" mode )
    		) ;;; end of unless
    		unless( mode == "diff" || mode == "common"
    			error( "SCLDiffOfListsCheck: argument #3 must either be \"diff\" or \"common\" - %L" mode )
    		) ;;; end of unless
    
    		for( i 1 length( inList1 )
    			occurrance1 = 1
    			value1 = nthelem( i inList1 )
    			check1 = member( value1 inList1 )
    			while( ( ( length( inList1 ) - length( check1 ) ) + 1 ) != i
    				check1 = member( value1 cdr( check1 ) )
    				occurrance1++
    			) ;;; end of while
    
    			occurrance2 = 1
    			check2 = member( value1 inList2 )
    			while( occurrance2 <= occurrance1
    				if( check2
    				then
    					when( equal( mode "common" ) && occurrance2 == occurrance1
    						outList = append( outList list( value1 ) )
    					) ;;; end of when
    					check2 = member( value1 cdr( check2 ) )
    					occurrance2++
    				else
    					when( equal( mode "diff" )
    						outList = append( outList list( value1 ) )
    					) ;;; end of when
    					occurrance2 = occurrance1 + 1
    				) ;;; end of if check2
    			) ;;; end of while
    		) ;;; end of for i
    
    		;;; Returning the output...
    		outList
    
    	) ;;; end of let
    ) ;;; end of procedure SCLDiffOfListsCheck
    

    This calculates of each created ruler (marker) the distance and then applies the scaling. This is reported in the CIW. In order for this to work, in the first line the bindkey has been assigned to the custom procedure. Some additional procedures are included in order to make this work right out of the box.

    Next I'll have a look at your code.

    With kind regards,

    Sjoerd

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 5 years ago in reply to Sheppie

    Hi Sjoerd,

    Yes, your approach could work too. 

    Another idea would be to create a label for each selected ruler. Using the code from before you could do something like:

    procedure(abAddLabelToMarkers(@optional (height 0.2) (selected geGetSelSet()) (cv geGetEditCellView()))
      let((label)
        foreach(ruler selected
          when(ruler~>objType=="ruler"
            label=dbCreateLabel(cv "text" car(ruler~>points) abScaledRulerDisplay(ruler) "lowerLeft" "R0" "stick" height)
            label~>parent=ruler
          )
        )
        t
      )
    )

    Something like that, anyway.

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Sheppie
    Sheppie over 5 years ago in reply to Andrew Beckett

    Hi Andrew,

    Great idea, and it works great, except: the label does not scale with soom-level of the editor. The text of the ruler always remains readable since it simply gets larger (relative to the design) when zooming-out and gets relatively smaller when zooming-in. When using a label created by dbCreateLabel, it s a fixed size, not relateive to zoom level. Is it possible to create a "smart" label, i.e.: a label that scales with zoom-level?

    Kind regards,

    Sjoerd

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 5 years ago in reply to Sheppie

    Hi Sjoerd,

    Unfortunately there's no "fixed point size" label; I meant to list this as a bit of a limitation...

    So overall my favourite solution of all of these is the dynamic display approach as that's the cleanest.

    Andrew

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Reply
  • Andrew Beckett
    Andrew Beckett over 5 years ago in reply to Sheppie

    Hi Sjoerd,

    Unfortunately there's no "fixed point size" label; I meant to list this as a bit of a limitation...

    So overall my favourite solution of all of these is the dynamic display approach as that's the cleanest.

    Andrew

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Children
  • Sheppie
    Sheppie over 5 years ago in reply to Andrew Beckett

    Hi Andrew,

    I've implemented both solutions, with a "switch" for the user to enable/disable independantly (using a global variable).

    Thanks again for all the time you spend on this.

    Kind regards,

    Sjoerd

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 5 years ago in reply to Sheppie

    Hi Sjoerd,

    I meant to also mention that you can cut out all that type checking code in your functions by using the type-checking string at the end of the argument list. For example:

    procedure( SCLDiffOfLists( inList1 inList2 "ll") ...)

    or

    procedure( SCLDiffOfListsCheck( inList1 inList2 @optional ( mode "diff" ) "llt" ) ...)

    Makes the code a bit cleaner and reduces the need for simple type checks.

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Sheppie
    Sheppie over 5 years ago in reply to Andrew Beckett

    Hi Andrew, This is code from many many years ago, before I learned that a procedure can do type-checking itself. It depends on what type of procedure I write, but if it is for common/general use, I do the type-checking like you proposed, otherwise I just skip it. And yes, it eliminates a lot of lines of code. Kind regards, Sjoerd

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel

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