<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://community.cadence.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Callback Code Not Working as Intended</title><link>https://community.cadence.com/cadence_technology_forums/f/custom-ic-skill/51332/callback-code-not-working-as-intended</link><description>Hi, 
 I&amp;#39;ve been scratching my head over this for a little over a day and I can&amp;#39;t seem to explain the behavior I&amp;#39;m seeing. For some background, I&amp;#39;m fairly new to SKILL and I&amp;#39;ve been creating a pCell for a MIM. The pCell, callbacks, and CDF all seem to</description><dc:language>en-US</dc:language><generator>Telligent Community 12</generator><item><title>RE: Callback Code Not Working as Intended</title><link>https://community.cadence.com/thread/1382477?ContentTypeID=1</link><pubDate>Fri, 25 Mar 2022 21:32:25 GMT</pubDate><guid isPermaLink="false">75bcbcf9-38a3-4e2e-b84b-26c8c46a9500:7d59056a-18b1-4b2d-85af-a3d48768ba51</guid><dc:creator>Ynishant</dc:creator><description>&lt;p&gt;Brilliant! Yes, this actually makes sense to me and the reason why I changed the &amp;quot;&amp;gt;=&amp;quot; to &amp;quot;&amp;gt;&amp;quot; in the waffle callback check was precisely because that single change made the code work for the second case that was failing before - when the W = 30 um and L = 13 um. That should&amp;#39;ve nudged me to look at the difference between the evalstring and&amp;nbsp;&lt;span&gt;cdfParseFloatString&amp;nbsp;(and I suspected there might be a difference but I didn&amp;#39;t explore that). That should&amp;#39;ve also nudged me to look at any floating math issues! While debugging, I used the &amp;quot;%f&amp;quot; qualifier to print the W and L values so I didn&amp;#39;t notice the differences in the significant digits. Lesson learned...&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I think I&amp;#39;m all set and thank you for all your help!&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Callback Code Not Working as Intended</title><link>https://community.cadence.com/thread/1382475?ContentTypeID=1</link><pubDate>Fri, 25 Mar 2022 21:19:43 GMT</pubDate><guid isPermaLink="false">75bcbcf9-38a3-4e2e-b84b-26c8c46a9500:197f8dfa-7853-4393-95bd-a52a06a40661</guid><dc:creator>Andrew Beckett</dc:creator><description>&lt;p&gt;OK, this ended up being down to a couple of things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A difference in the condition in determining whether it was in &amp;quot;waffle mode&amp;quot; or not between the callback and the PCell code&lt;/li&gt;
&lt;li&gt;Floating point rounding errors - caused by a difference in using cdfParseFloatString (callbacks) and evalstring (PCell). Neither approach is really safe, as doing equality checks or &amp;gt;= checks is always dangerous with floating point numbers as I&amp;#39;ll show in a moment.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;First of all, the difference. The PCell code looks like this:&lt;/p&gt;
&lt;pre&gt;	&lt;strong&gt;cap_area = w*l
	if( (cap_area &amp;lt;= 400.0) then
&lt;span style="color:#ff0000;"&gt;		if( (w&amp;gt;=30 &amp;amp;&amp;amp; l&amp;gt;=12)||(l&amp;gt;=30 &amp;amp;&amp;amp; w&amp;gt;=12) then
&lt;/span&gt;			waffle = 1
		else
			waffle = 0
		) 
	else
		waffle = 1
	)	
	;warn(&amp;quot;waffle pCell %d&amp;quot; waffle)&lt;/strong&gt;&lt;/pre&gt;
&lt;p&gt;and the CDF callback like this:&lt;/p&gt;
&lt;pre&gt;    if(cap_area &amp;lt;= 400.0
        then
&lt;span style="color:#ff0000;"&gt;            if(((w_n &amp;gt; 30) &amp;amp;&amp;amp; (l_n &amp;gt; 12)) || ((l_n &amp;gt; 30) &amp;amp;&amp;amp; (w_n &amp;gt; 12))
&lt;/span&gt;                then
                    waffle = 1
                else
                    waffle = 0
               )
        else
            waffle = 1
       )
 &lt;/pre&gt;
&lt;p&gt;Notice that the red lines are different - the PCell code is using &amp;gt;= whereas the callback code is using &amp;gt;. However, that is not enough to fix it.. If you add some print statements (I tend to use fprintf to print to stderr as that then prints in the CIW for PCells, rather than adding a marker onto the PCell) - I added this to the PCell code (where y ou had the warn(&amp;quot;waffle pCell&amp;quot;... line above):&lt;/p&gt;
&lt;pre&gt;	fprintf(stderr &amp;quot;PC: waffle %d w %.18g l %.18g\n&amp;quot; waffle w l)
&lt;/pre&gt;
&lt;p&gt;and this to the callback code (just above the if statement I show above):&lt;/p&gt;
&lt;pre&gt;    fprintf(stderr &amp;quot;CB: cap_area %.18g w %.18g l %.18g\n&amp;quot; cap_area w_n l_n)
&lt;/pre&gt;
&lt;p&gt;Running this with w=30u and l=12u you see this in the CIW (note the difference in waffle value between callback and the pcell too):&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#ff0000;font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;CB: cap_area 359.999999999999943 w 29.9999999999999964 l 12&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;*WARNING* Waffle Status 0&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;*WARNING* Initial Values: w=3e-05 l=1.2e-05 c=6.13657e-13 ratio=2&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff0000;font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;PC: waffle 1 w 30 l 12&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Looking closely, it&amp;#39;s because there are small differences between cdfParseFloatString and evalstring. You might think &amp;quot;ah, I&amp;#39;ll just use evalstring in both places&amp;quot;, and that does fix it in this case, but I&amp;#39;d also suggest that there&amp;#39;s no guarantee that other numbers might similarly end up with small rounding errors when multiplied by the 1e6 scale). Also, I dislike using evalstring because I always think of the case &amp;quot;what if the user entered exit() in the field?&amp;quot; (your PCell might then cause Virtuoso to quit!).&lt;/p&gt;
&lt;p&gt;Instead, it&amp;#39;s better to do the comparison with some&amp;nbsp;&lt;em&gt;epsilon&lt;/em&gt; (or error) value which allows a safety margin for tiny rounding errors. A reasonable value for that might be around half a database unit. So maybe you could instead change the conditions to this for the PCel (note that the epsilon is either added or subtracted depending on the direction of the comparisonl:&lt;/p&gt;
&lt;pre&gt;	epsilon=0.0005
	if( (cap_area &amp;lt;= 400.0+epsilon) then
		if( (w&amp;gt;=30-epsilon &amp;amp;&amp;amp; l&amp;gt;=12-epsilon)||(l&amp;gt;=30-epsilon &amp;amp;&amp;amp; w&amp;gt;=12-epsilon) then
			waffle = 1
		else
			waffle = 0
		) 
	else
		waffle = 1
	)&lt;/pre&gt;
&lt;p&gt;and this for the callback:&lt;/p&gt;
&lt;pre&gt;    epsilon = 0.0005
    fprintf(stderr &amp;quot;CB: cap_area %.18g w %.18g l %.18g\n&amp;quot; cap_area w_n l_n)
    if(cap_area &amp;lt;= 400.0+epsilon
        then
            ;if(((w_n &amp;gt; 30) &amp;amp;&amp;amp; (l_n &amp;gt; 12)) || ((l_n &amp;gt; 30) &amp;amp;&amp;amp; (w_n &amp;gt; 12))
            if(((w_n &amp;gt;= 30-epsilon) &amp;amp;&amp;amp; (l_n &amp;gt;= 12-epsilon)) || ((l_n &amp;gt;= 30-epsilon) &amp;amp;&amp;amp; (w_n &amp;gt;= 12-epsilon))
                then
                    waffle = 1
                else
                    waffle = 0
               )
        else
            waffle = 1
       )
&lt;/pre&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;p&gt;With this, the resulting info with w=30u and l=12u:&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#ff0000;font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;CB: cap_area 359.999999999999943 w 29.9999999999999964 l 12&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;*WARNING* Waffle Status 1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;*WARNING* Initial Values: w=3e-05 l=1.2e-05 c=4.91743e-13 ratio=2.5&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff0000;font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;PC: waffle 1 w 30 l 12&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;See that the waffle status is now consistent. I didn&amp;#39;t fully check the behaviour of the PCell because I wasn&amp;#39;t entirely sure what you were expecting it to do, but I think that&amp;#39;s the part you had the concerns about. Be aware that floating point rounding errors happen in any programming language that uses IEEE floating point representation for numbers (so it affects C, Python, SKILL and many others) - you just have to be aware that a single bit error in the 53 bit mantissa can cause all sorts of problems and any equality check is dangerous because of tiny differences due to how you do the maths. A simple example I always like to give is that 0.1 in binary is a recurring fraction like 1/3 is in decimal - so you can easily imagine how you lose precision such as you do by representing 1/3 as 0.333 - for example, if you did (in pseudo code)&lt;/p&gt;
&lt;p&gt;third=0.333&lt;br /&gt;if third*3==1 then...&lt;/p&gt;
&lt;p&gt;well, surprise, surprise - it doesn&amp;#39;t equal 1 - the same thing is happening here but with a long binary mantissa.&lt;/p&gt;
&lt;p&gt;I haven&amp;#39;t reviewed all the code to give advice (to be honest, I don&amp;#39;t have time - explaining this took long enough having gradually collected all the data to reproduce it), but hopefully the above explanation will give you enough to review your code for other potential similar problems.&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;Andrew&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Callback Code Not Working as Intended</title><link>https://community.cadence.com/thread/1382466?ContentTypeID=1</link><pubDate>Fri, 25 Mar 2022 17:33:57 GMT</pubDate><guid isPermaLink="false">75bcbcf9-38a3-4e2e-b84b-26c8c46a9500:fe0f87c3-4439-41b4-b17e-194e8becbbdd</guid><dc:creator>Ynishant</dc:creator><description>&lt;p&gt;Sure, I&amp;#39;ve included it below. There are some lines that can be commented out without affecting functionality, especially the lines with &amp;quot;sbc18&amp;quot; or &amp;quot;jazzDisplayDeviceParams&amp;quot;. Please let me know if the overall SKILL code can be improved in any way, or if there&amp;#39;s a better way to do what I&amp;#39;m doing.&amp;nbsp;&lt;/p&gt;
&lt;pre&gt;/****************************************************/
 LIBRARY = &amp;quot;MIM_Pcell_Final&amp;quot;
 CELL    = &amp;quot;cmim1p35_2&amp;quot;
/****************************************************/


let( ( libId cellId cdfId )
    unless( cellId = ddGetObj( LIBRARY CELL )
    	error( &amp;quot;Could not get cell %s.&amp;quot; CELL )
    )
    when( cdfId = cdfGetBaseCellCDF( cellId )
        cdfDeleteCDF( cdfId )
    )
    cdfId  = cdfCreateBaseCellCDF( cellId )

    ;;; Parameters
    cdfCreateParam( cdfId
        ?name           &amp;quot;macro&amp;quot;
        ?prompt         &amp;quot;Subcircuit Filename&amp;quot;
        ?defValue       &amp;quot;c2t_mim1p35_cu&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?display        &amp;quot;jazzDisplayDevParams(\&amp;quot;cmim1p35_2\&amp;quot;)&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;
        ?storeDefault  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;m&amp;quot;
        ?prompt         &amp;quot;Multiplier&amp;quot;
        ?defValue       &amp;quot;1&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?callback       &amp;quot;mim_cb( &amp;#39;m )&amp;quot;
        ?storeDefault   &amp;quot;yes&amp;quot;   
        ?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;     
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;caprows&amp;quot;
        ?prompt         &amp;quot;Rows&amp;quot;
        ?defValue       &amp;quot;1&amp;quot;
        ?type           &amp;quot;string&amp;quot;
		;?display        &amp;quot;sbc18_capDisplay( &amp;#39;caprows ) &amp;amp;&amp;amp; jazzDisplayDevParams(\&amp;quot;cmim1p35_2\&amp;quot;)&amp;quot;
       	?display        &amp;quot;nil&amp;quot;
        ?editable       &amp;quot;t&amp;quot;
		;?callback       &amp;quot;sbc18_capCB( &amp;#39;caprows )&amp;quot;
        ?storeDefault  &amp;quot;yes&amp;quot;
        ?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;capcols&amp;quot;
        ?prompt         &amp;quot;Columns&amp;quot;
        ?defValue       &amp;quot;1&amp;quot;
        ?type           &amp;quot;string&amp;quot;
		;?display        &amp;quot;sbc18_capDisplay( &amp;#39;capcols ) &amp;amp;&amp;amp; jazzDisplayDevParams(\&amp;quot;cmim1p35_2\&amp;quot;)&amp;quot;
       	?display        &amp;quot;nil&amp;quot;
        ?editable       &amp;quot;t&amp;quot;
        ;?callback       &amp;quot;sbc18_capCB( &amp;#39;capcols )&amp;quot;
        ?storeDefault  &amp;quot;yes&amp;quot;
        ?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;Calculate&amp;quot;
        ?prompt         &amp;quot;Calculate&amp;quot;
        ?defValue       &amp;quot;C&amp;quot;
        ?choices        &amp;#39;(&amp;quot;C&amp;quot; &amp;quot;L&amp;quot; &amp;quot;W&amp;quot; &amp;quot;WL&amp;quot;)
        ?type           &amp;quot;radio&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;
		?storeDefault   &amp;quot;yes&amp;quot;        
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;c&amp;quot;
        ?prompt         &amp;quot;Capacitance&amp;quot;
        ?defValue       &amp;quot;309.8f&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?callback       &amp;quot;mim_cb( &amp;#39;c )&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;
        ?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;w&amp;quot;
        ?prompt         &amp;quot;Width&amp;quot;
        ?defValue       &amp;quot;15u&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?callback       &amp;quot;mim_cb( &amp;#39;Width )&amp;quot;
		?storeDefault   &amp;quot;yes&amp;quot;
		?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;        
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;l&amp;quot;
        ?prompt         &amp;quot;Length&amp;quot;
        ?defValue       &amp;quot;15u&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?callback       &amp;quot;mim_cb( &amp;#39;Length )&amp;quot;
		?storeDefault   &amp;quot;yes&amp;quot; 
		?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;       
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;aspect_ratio&amp;quot;
        ?prompt         &amp;quot;Aspect Ratio(w/l)&amp;quot;
        ?defValue       &amp;quot;1&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;
		?storeDefault   &amp;quot;yes&amp;quot;  
		?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;      
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;dx&amp;quot;
        ?prompt         &amp;quot;dx&amp;quot;
        ?defValue       &amp;quot;-120n&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;
        ?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;ablb&amp;quot;
        ?prompt         &amp;quot;Enable ABLB&amp;quot;
        ?defValue       t
        ?type           &amp;quot;boolean&amp;quot;
        ?editable       &amp;quot;t&amp;quot;
		?storeDefault   &amp;quot;yes&amp;quot;        
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;cmm&amp;quot;
        ?prompt         &amp;quot;Nominal Unit Area Capacitance&amp;quot;
        ?defValue       &amp;quot;1.35m&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;
        ?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;fringe&amp;quot;
        ?prompt         &amp;quot;Nominal Unit Fringe Capacitance&amp;quot;
        ?defValue       &amp;quot;150p&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;
	    ?storeDefault   &amp;quot;yes&amp;quot;
	    ?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;        
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;m3_density&amp;quot;
        ?prompt         &amp;quot;Density of the M3 layer on the Cap(%)&amp;quot;
        ?defValue       &amp;quot;73&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;       
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;n_horiz_strips&amp;quot;
        ?prompt         &amp;quot;Number of horizontal strips&amp;quot;
        ?defValue       &amp;quot;0&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?storeDefault   &amp;quot;yes&amp;quot;  
        ?editable       &amp;quot;nil&amp;quot;      
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;n_vertical_strips&amp;quot;
        ?prompt         &amp;quot;Number of vertical strips&amp;quot;
        ?defValue       &amp;quot;0&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?storeDefault   &amp;quot;yes&amp;quot;  
        ?editable       &amp;quot;nil&amp;quot;      
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;rem_h_strip&amp;quot;
        ?prompt         &amp;quot;Number of Horizontal Strips To Remove(Limit 2)&amp;quot;
        ?defValue       &amp;quot;0&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?storeDefault   &amp;quot;yes&amp;quot;        
    )    
    cdfCreateParam( cdfId
        ?name           &amp;quot;showSimParams&amp;quot;
        ?prompt         &amp;quot;Show Sim Parameters&amp;quot;
        ?type           &amp;quot;boolean&amp;quot;
        ?display        &amp;quot;sbc18_capDisplay(&amp;#39;showSimParams)&amp;quot;
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;cmima_max&amp;quot;
        ?prompt         &amp;quot;Max Unit Area Capacitance&amp;quot;
        ?defValue       &amp;quot;1.55m&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?display        &amp;quot;sbc18_capDisplay(&amp;#39;cmima_max) &amp;amp;&amp;amp; jazzDisplayDevParams(\&amp;quot;cmim1p35_2\&amp;quot;)&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;
        ?storeDefault  &amp;quot;yes&amp;quot;
        ?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;cmimp_max&amp;quot;
        ?prompt         &amp;quot;Max Unit Fringe Capacitance&amp;quot;
        ?defValue       &amp;quot;225p&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?display        &amp;quot;sbc18_capDisplay(&amp;#39;cmimp_max) &amp;amp;&amp;amp; jazzDisplayDevParams(\&amp;quot;cmim1p35_2\&amp;quot;)&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;
        ?storeDefault  &amp;quot;yes&amp;quot;
        ?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;coxa_nom&amp;quot;
        ?prompt         &amp;quot;coxa_nom&amp;quot;
        ?defValue       &amp;quot;15.1u&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?display        &amp;quot;sbc18_capDisplay(&amp;#39;coxa_nom) &amp;amp;&amp;amp; jazzDisplayDevParams(\&amp;quot;cmim1p35_2\&amp;quot;)&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;
        ?storeDefault  &amp;quot;yes&amp;quot;
        ?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;coxa_max&amp;quot;
        ?prompt         &amp;quot;coxa_max&amp;quot;
        ?defValue       &amp;quot;17.5u&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?display        &amp;quot;sbc18_capDisplay(&amp;#39;coxa_max) &amp;amp;&amp;amp; jazzDisplayDevParams(\&amp;quot;cmim1p35_2\&amp;quot;)&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;
        ?storeDefault  &amp;quot;yes&amp;quot;
        ?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;coxp_nom&amp;quot;
        ?prompt         &amp;quot;coxp_nom&amp;quot;
        ?defValue       &amp;quot;37.4p&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?display        &amp;quot;sbc18_capDisplay(&amp;#39;coxp_nom) &amp;amp;&amp;amp; jazzDisplayDevParams(\&amp;quot;cmim1p35_2\&amp;quot;)&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;
        ?storeDefault  &amp;quot;yes&amp;quot;
        ?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;coxp_max&amp;quot;
        ?prompt         &amp;quot;coxp_max&amp;quot;
        ?defValue       &amp;quot;38.7p&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?display        &amp;quot;sbc18_capDisplay(&amp;#39;coxp_max) &amp;amp;&amp;amp; jazzDisplayDevParams(\&amp;quot;cmim1p35_2\&amp;quot;)&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;
        ?storeDefault  &amp;quot;yes&amp;quot;
        ?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;rshbp_nom&amp;quot;
        ?prompt         &amp;quot;rshbp_nom&amp;quot;
        ?defValue       &amp;quot;66m&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?display        &amp;quot;sbc18_capDisplay(&amp;#39;rshbp_nom) &amp;amp;&amp;amp; jazzDisplayDevParams(\&amp;quot;cmim1p35_2\&amp;quot;)&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;
        ?storeDefault  &amp;quot;yes&amp;quot;
        ?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;rshbp_max&amp;quot;
        ?prompt         &amp;quot;rshbp_max&amp;quot;
        ?defValue       &amp;quot;86m&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?display        &amp;quot;sbc18_capDisplay(&amp;#39;rshbp_max) &amp;amp;&amp;amp; jazzDisplayDevParams(\&amp;quot;cmim1p35_2\&amp;quot;)&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;
        ?storeDefault  &amp;quot;yes&amp;quot;
        ?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;rshtp_nom&amp;quot;
        ?prompt         &amp;quot;rshtp_nom&amp;quot;
        ?defValue       &amp;quot;5.4m&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?display        &amp;quot;sbc18_capDisplay(&amp;#39;rshtp_nom) &amp;amp;&amp;amp; jazzDisplayDevParams(\&amp;quot;cmim1p35_2\&amp;quot;)&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;
        ?storeDefault  &amp;quot;yes&amp;quot;
        ?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;rshtp_max&amp;quot;
        ?prompt         &amp;quot;rshtp_max&amp;quot;
        ?defValue       &amp;quot;7m&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?display        &amp;quot;sbc18_capDisplay(&amp;#39;rshtp_max) &amp;amp;&amp;amp; jazzDisplayDevParams(\&amp;quot;cmim1p35_2\&amp;quot;)&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;
        ?storeDefault  &amp;quot;yes&amp;quot;
        ?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;tc&amp;quot;
        ?prompt         &amp;quot;tc&amp;quot;
        ?defValue       &amp;quot;20u&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?display        &amp;quot;sbc18_capDisplay(&amp;#39;tc) &amp;amp;&amp;amp; jazzDisplayDevParams(\&amp;quot;cmim1p35_2\&amp;quot;)&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;
        ?storeDefault  &amp;quot;yes&amp;quot;
        ?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;tbp&amp;quot;
        ?prompt         &amp;quot;tbp&amp;quot;
        ?defValue       &amp;quot;620n&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?display        &amp;quot;sbc18_capDisplay(&amp;#39;tbp) &amp;amp;&amp;amp; jazzDisplayDevParams(\&amp;quot;cmim1p35_2\&amp;quot;)&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;
        ?storeDefault  &amp;quot;yes&amp;quot;
        ?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;ttp&amp;quot;
        ?prompt         &amp;quot;ttp&amp;quot;
        ?defValue       &amp;quot;3.3u&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?display        &amp;quot;sbc18_capDisplay(&amp;#39;ttp) &amp;amp;&amp;amp; jazzDisplayDevParams(\&amp;quot;cmim1p35_2\&amp;quot;)&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;
        ?storeDefault  &amp;quot;yes&amp;quot;
        ?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;rvia&amp;quot;
        ?prompt         &amp;quot;rvia&amp;quot;
        ?defValue       &amp;quot;3.5&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?display        &amp;quot;sbc18_capDisplay(&amp;#39;rvia) &amp;amp;&amp;amp; jazzDisplayDevParams(\&amp;quot;cmim1p35_2\&amp;quot;)&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;
        ?storeDefault  &amp;quot;yes&amp;quot;
        ?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;
    )
    cdfCreateParam( cdfId
        ?name           &amp;quot;wvia&amp;quot;
        ?prompt         &amp;quot;wvia&amp;quot;
        ?defValue       &amp;quot;380n&amp;quot;
        ?type           &amp;quot;string&amp;quot;
        ?display        &amp;quot;sbc18_capDisplay(&amp;#39;wvia) &amp;amp;&amp;amp; jazzDisplayDevParams(\&amp;quot;cmim1p35_2\&amp;quot;)&amp;quot;
        ?editable       &amp;quot;nil&amp;quot;
        ?storeDefault  &amp;quot;yes&amp;quot;
        ?parseAsNumber  &amp;quot;yes&amp;quot;
        ?parseAsCEL     &amp;quot;yes&amp;quot;
    )
    
    ;;; Simulator Information
    cdfId-&amp;gt;simInfo = list( nil )
    cdfId-&amp;gt;simInfo-&amp;gt;ads = &amp;#39;( nil
        namePrefix        &amp;quot;&amp;quot;
        netlistProcedure  IdfCompPrim
        otherParameters   nil
        instParameters    (w l caprows capcols _M cmima_nom cmima_max cmimp_nom cmimp_max coxa_nom coxa_max coxp_nom coxp_max rshtp_nom rshtp_max rshbp_nom rshbp_max tc tbp ttp rvia wvia)
        propMapping       (nil _M m)
        typeMapping       nil
        uselib            nil
        termOrder         (PLUS MINUS)
        termMapping       (nil PLUS &amp;quot;:P1&amp;quot; MINUS &amp;quot;:P2&amp;quot;)
        componentName     &amp;quot;c2t_mim2_cu&amp;quot;
    )
    cdfId-&amp;gt;simInfo-&amp;gt;ams = &amp;#39;( nil
        componentName     &amp;quot;c2t_mim2_cu&amp;quot;
    )
    cdfId-&amp;gt;simInfo-&amp;gt;auCdl = &amp;#39;( nil
        propMapping       (nil C cvalCdl M simM L l W w sim_tc tc dspfsim macro)
        termOrder         (PLUS MINUS)
        netlistProcedure  jazzCdlSubcktCall
        instParameters    (C M L W dspfsim macro cmima_nom cmima_max cmimp_nom cmimp_max coxa_nom coxa_max coxp_nom coxp_max rshtp_nom rshtp_max rshbp_nom rshbp_max sim_tc tbp ttp rvia wvia)
        namePrefix        &amp;quot;X&amp;quot;
        modelName         &amp;quot;cmim1p35_2&amp;quot;
    )
    cdfId-&amp;gt;simInfo-&amp;gt;auLvs = &amp;#39;( nil
        propMapping       nil
        netlistProcedure  ansLvsCompPrim
        instParameters    (m capcols caprows c)
        parameters        (C)
        permuteRule       &amp;quot;(p PLUS MINUS)&amp;quot;
        namePrefix        &amp;quot;C&amp;quot;
        termOrder         (PLUS MINUS)
        deviceTerminals   &amp;quot;PLUS MINUS&amp;quot;
        componentName     &amp;quot;cmim1p35_2&amp;quot;
    )
    cdfId-&amp;gt;simInfo-&amp;gt;eldoD = &amp;#39;( nil
        netlistProcedure  nil
        propMapping       nil
        instParameters    (w l caprows capcols m cmima_nom cmima_max cmimp_nom cmimp_max coxa_nom coxa_max coxp_nom coxp_max rshtp_nom rshtp_max rshbp_nom rshbp_max tc tbp ttp rvia wvia)
        namePrefix        &amp;quot;X&amp;quot;
        current           port
        noPortDelimiter   t
        dcSens            t
        acSens            t
        termOrder         (PLUS MINUS)
        termMapping       (nil PLUS &amp;quot;(FUNCTION mappedRoot(\&amp;quot;^l1\&amp;quot;))&amp;quot; MINUS &amp;quot;(FUNCTION minus(mappedRoot(\&amp;quot;^l2\&amp;quot;)))&amp;quot;)
        componentName     &amp;quot;c2t_mim2_cu&amp;quot;
    )
    cdfId-&amp;gt;simInfo-&amp;gt;hspiceD = &amp;#39;( nil
        netlistProcedure  nil
        propMapping       nil
        instParameters    (w l caprows capcols m cmima_nom cmima_max cmimp_nom cmimp_max coxa_nom coxa_max coxp_nom coxp_max rshtp_nom rshtp_max rshbp_nom rshbp_max tc tbp ttp rvia wvia)
        namePrefix        &amp;quot;X&amp;quot;
        current           port
        noPortDelimiter   t
        dcSens            t
        acSens            t
        termOrder         (PLUS MINUS)
        termMapping       (nil PLUS &amp;quot;(FUNCTION mappedRoot(\&amp;quot;^l1\&amp;quot;))&amp;quot; MINUS &amp;quot;(FUNCTION minus(mappedRoot(\&amp;quot;^l2\&amp;quot;)))&amp;quot;)
        componentName     &amp;quot;c2t_mim2_cu&amp;quot;
    )
    cdfId-&amp;gt;simInfo-&amp;gt;spectre = &amp;#39;( nil
        propMapping       (nil model macro)
        instParameters    (w l caprows capcols m cmima_nom cmima_max cmimp_nom cmimp_max coxa_nom coxa_max coxp_nom coxp_max rshtp_nom rshtp_max rshbp_nom rshbp_max tc tbp ttp rvia wvia)
        netlistProcedure  nil
        termOrder         (PLUS MINUS)
        termMapping       (nil PLUS \:1 MINUS \:2)
        opParamExprList   ((&amp;quot;cval&amp;quot; &amp;quot;OP(mappedRoot(\&amp;quot;.c3\&amp;quot;) \&amp;quot;cap\&amp;quot;)&amp;quot;) (&amp;quot;cbot&amp;quot; &amp;quot;OP(mappedRoot(\&amp;quot;.c1\&amp;quot;) \&amp;quot;cap\&amp;quot;)+OP(mappedRoot(\&amp;quot;.c2\&amp;quot;) \&amp;quot;cap\&amp;quot;)&amp;quot;))
    )

    
    

    ;;; Properties
    cdfId-&amp;gt;formInitProc            = &amp;quot;mim_m2cs_init&amp;quot;
    cdfId-&amp;gt;doneProc                = &amp;quot;&amp;quot;
    cdfId-&amp;gt;buttonFieldWidth        = 340
    cdfId-&amp;gt;fieldHeight             = 35
    cdfId-&amp;gt;fieldWidth              = 350
    cdfId-&amp;gt;promptWidth             = 175
    cdfId-&amp;gt;paramLabelSet           = &amp;quot;w l c m caprows capcols&amp;quot;
    cdfId-&amp;gt;opPointLabelSet         = &amp;quot;cval cbot cfox&amp;quot;
    cdfId-&amp;gt;modelLabelSet           = &amp;quot;&amp;quot;
    cdfId-&amp;gt;paramDisplayMode        = &amp;quot;parameter&amp;quot;
    cdfId-&amp;gt;paramEvaluate           = &amp;quot;nil nil nil nil t&amp;quot;
    cdfId-&amp;gt;paramSimType            = &amp;quot;DC&amp;quot;
    cdfId-&amp;gt;termSimType             = &amp;quot;DC&amp;quot;
    cdfId-&amp;gt;instDisplayMode         = &amp;quot;instName&amp;quot;
    cdfId-&amp;gt;instNameType            = &amp;quot;schematic&amp;quot;
    
    cdfSaveCDF( cdfId )
)&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Callback Code Not Working as Intended</title><link>https://community.cadence.com/thread/1382459?ContentTypeID=1</link><pubDate>Fri, 25 Mar 2022 16:49:24 GMT</pubDate><guid isPermaLink="false">75bcbcf9-38a3-4e2e-b84b-26c8c46a9500:aa42c88e-cda7-4ad2-bac3-6d1877e2d4f6</guid><dc:creator>Andrew Beckett</dc:creator><description>&lt;p&gt;Could you also share the CDF for the cell? It&amp;#39;s possible that&amp;#39;s where the problem is (and it would be useful to know how the defaults and callbacks have been set up). If you don&amp;#39;t have it as a file, if you could use Tools-&amp;gt;CDF-&amp;gt;Edit in the CIW, pick &amp;quot;Base&amp;quot;, choose MIM_Pcell_Final and cmim1p35_2 as the cellView, and then use the &amp;quot;CDF Dump&amp;quot; button on the right side.&lt;/p&gt;
&lt;p&gt;I have the PCell running (I adjusted the layers for gpdk045) so should be able to fully test this.&lt;/p&gt;
&lt;p&gt;Thanks,&lt;/p&gt;
&lt;p&gt;Andrew&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Callback Code Not Working as Intended</title><link>https://community.cadence.com/thread/1382451?ContentTypeID=1</link><pubDate>Fri, 25 Mar 2022 14:46:32 GMT</pubDate><guid isPermaLink="false">75bcbcf9-38a3-4e2e-b84b-26c8c46a9500:048da453-ad7e-4249-91fe-e31473c62741</guid><dc:creator>Ynishant</dc:creator><description>&lt;p&gt;Hi Andrew,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Thanks for the code pasting tip! Looking at the formatted code you&amp;#39;ve pasted has also given me some ideas on how to format my code to make it more readable (adding a newline after each local parameter value after the &amp;quot;let&amp;quot; really helps). I realize that I mentioned the pCell code but didn&amp;#39;t include it. Fair enough. I didn&amp;#39;t do a good job explaining exactly why and how the code was failing and I agree that including just some code doesn&amp;#39;t help you help me. So, here&amp;#39;s a brief overview:&lt;/p&gt;
&lt;p&gt;* I created a pCell for a simple MM cap. The cap has two modes - for a total cap area below a certain value, the connecting metal layer is a solid block of metal, for cap areas above a certain value the top metal is waffled or broken into horizontal and vertical strips&lt;/p&gt;
&lt;p&gt;* In the callback code, I run some checks to see if the cap needs to be waffled (in the &amp;quot;waffle_yes_or_no&amp;quot; procedure). I&amp;#39;m doing this because I&amp;#39;m displaying metal density and the number of horizontal or vertical strips in the cap in the parameter display window. This is vital, as the end user may decide to reduce the number of horizontal strips to meet metal density rules.&lt;/p&gt;
&lt;p&gt;* I run the identical waffle check in the main pCell code as will become clear below. Now, I&amp;#39;m doing this because I don&amp;#39;t really want to create an extra cdf param or pass the waffle variable to the pCell. Since I&amp;#39;m very new to SKILL, I don&amp;#39;t want to mess with creating global variables and passing values between compiled and uncompiled SKILL files.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;* If I run the pCell code on it&amp;#39;s own, i.e. if I just load the pCell skill file through the CIW into a library (load &amp;quot;pCell_code.il&amp;quot;). Everything works fine and the cap gets waffled when specified and everything&amp;#39;s good with the world.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;* &lt;strong&gt;If I run the entire packaged pCell with the callbacks, the CDF, and the pCell code, two conditions cause the layout to draw but not as intended. When the W and L values are set to 30 and 12 respectively, the pCell draws the cap, but without the metal3 layer. I did some debugging by including some warn statements and it turns out that the waffle check in the callback says that the cap shouldn&amp;#39;t be waffled, while the check in the pCell says it should! The code is identical, so why is the same check giving me different results?&amp;nbsp;&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you&amp;#39;d like to run the entire pCell with the CDF I can include that too. But the pCell code is pasted below with the suspect section highlighted.&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;Nishant.&amp;nbsp;&lt;/p&gt;
&lt;pre&gt;;; Cap Waffle
;; Nishant V.01 03/07/2022

strLibName = &amp;quot;MIM_Pcell_Final&amp;quot;
strCellName = &amp;quot;cmim1p35_2&amp;quot;

pcDefinePCell(list(ddGetObj(strLibName), strCellName, &amp;quot;layout&amp;quot;),

;Define default pcell parameter values
(
(w &amp;quot;string&amp;quot; &amp;quot;15u&amp;quot;)
(l &amp;quot;string&amp;quot; &amp;quot;15u&amp;quot;)
(c &amp;quot;string&amp;quot; &amp;quot;1.620pF&amp;quot;)
(m &amp;quot;string&amp;quot;   &amp;quot;1&amp;quot;)
(n_horiz_strips	&amp;quot;string&amp;quot;  &amp;quot;0&amp;quot;)
(n_vertical_strips	&amp;quot;string&amp;quot;  &amp;quot;0&amp;quot;)
(ablb  &amp;quot;boolean&amp;quot; t)
;(s_via &amp;quot;string&amp;quot; &amp;quot;1.5u&amp;quot;)  ; Min spacing between vias, removing it for now because it&amp;#39;s calculated
);end of default values

let((scale 
	MBOT VIA VIA2 MTOP MTOP2 CTM DUM TEXT ABLB
	num_horiz_strips num_vertical_strips bar_w hole_x_min w_VIA sp_h sp_v
        enc_VIA_MTOP w_MTOP l_MTOP enc_VIA_CTM enc_CTM_DUM enc_CTM_MBOT enc_VIA2_MTOP2 enc_ABLB_MBOT
        R_tmp R_ref offset_var offset_base num_vertical_vias num_horiz_vias via_pitch_y R_tmp1 via_pitch_x
        x y bet_via_spacing bar_offset off_via_spacing waffle s_via cap_area
	)

	; Define the layers
	MBOT   = list(&amp;quot;metal2&amp;quot;   &amp;quot;drawing&amp;quot;)
	VIA    = list(&amp;quot;via2&amp;quot;     &amp;quot;drawing&amp;quot;)
	VIA2   = list(&amp;quot;via3&amp;quot;     &amp;quot;drawing&amp;quot;)
	MTOP   = list(&amp;quot;metal3&amp;quot;   &amp;quot;drawing&amp;quot;)
	MTOP2  = list(&amp;quot;metal4&amp;quot;   &amp;quot;drawing&amp;quot;)
	CTM    = list(&amp;quot;topmm&amp;quot;    &amp;quot;drawing&amp;quot;) 
	DUM    = list(&amp;quot;cap2fF&amp;quot;   &amp;quot;drawing&amp;quot;)
	TEXT   = list(&amp;quot;text&amp;quot;     &amp;quot;drawing&amp;quot;)
	ABLB   = list(&amp;quot;ablb&amp;quot;     &amp;quot;drawing&amp;quot;)
	
	
	enc_ABLB_MBOT = 2.0
	enc_CTM_MBOT = 1.0
	enc_CTM_DUM  = 0.1
        enc_VIA_MTOP = 1.06
        enc_VIA2_MTOP2 = 0.5
        enc_VIA_CTM  = 1.06 
	
	; parameters needed
	scale 		= 1e6
	l           = evalstring(l)*scale
	w           = evalstring(w)*scale
	num_horiz_strips = evalstring(n_horiz_strips)
	num_vertical_strips = evalstring(n_vertical_strips)
	
	s_via       = 1.5
	bar_w       = 2.5
	hole_x_min  = 3.0
	sp 	    = hole_x_min
	w_VIA 	    = 0.38
	
	; Figure out exact size of top-plate based on enclosures
	enc_VIA_MTOP = enc_VIA_CTM ; ceiling((_tp/*bar_w-w_VIA)/2)
	w_MTOP = ceiling(w + 2*(enc_VIA_MTOP - enc_VIA_CTM))
	l_MTOP = ceiling(l + 2*(enc_VIA_MTOP - enc_VIA_CTM))
	
	offset_base = enc_VIA_MTOP - enc_VIA_CTM
	offset_var = offset_base
	
	;create shapes
	R_ref = rodCreateRect(
		?name	      &amp;quot;mimwaffle_CTM&amp;quot;
		?layer        CTM
		?width        w
		?length       l
	)

	R_tmp = rodCreateRect(
		?layer        DUM
		?width        (w+2*enc_CTM_DUM)
		?length       (l+2*enc_CTM_DUM)
	)

	rodAlign(
		?alignObj     R_tmp
		?alignHandle  &amp;#39;centerCenter
		?refObj       R_ref
		?refHandle    &amp;#39;centerCenter
	)
	  
	R_tmp = rodCreateRect(
		?layer        MBOT
		?width        (w+enc_CTM_MBOT*2)
		?length       (l+enc_CTM_MBOT*2)
		?termName	  &amp;quot;MINUS&amp;quot;
	    ?termIOType	  &amp;quot;inputOutput&amp;quot;
		?pin		  t
		?pinLabel     t			
	)

	rodAlign(
		?alignObj     R_tmp
		?alignHandle  &amp;#39;centerCenter
		?refObj       R_ref
		?refHandle    &amp;#39;centerCenter
	)
	
	; only draw the ABLB layer if enabled
	if( ablb then
		R_tmp = rodCreateRect(
			?layer        ABLB
			?width        (w+enc_ABLB_MBOT*2)
			?length       (l+enc_ABLB_MBOT*2)					
		)

		rodAlign(
			?alignObj     R_tmp
			?alignHandle  &amp;#39;centerCenter
			?refObj       R_ref
			?refHandle    &amp;#39;centerCenter
		)
	)	
	
	; Checker to see if there&amp;#39;s a need to waffle. Takes into account all the SBC18 Metal density rules
		
	&lt;strong&gt;cap_area = w*l
	if( (cap_area &amp;lt;= 400.0) then
		if( (w&amp;gt;=30 &amp;amp;&amp;amp; l&amp;gt;=12)||(l&amp;gt;=30 &amp;amp;&amp;amp; w&amp;gt;=12) then
			waffle = 1
		else
			waffle = 0
		) 
	else
		waffle = 1
	)	
	;warn(&amp;quot;waffle pCell %d&amp;quot; waffle)&lt;/strong&gt;
    
&lt;strong&gt;	; you can safely ignore the code below this point if it helps
&lt;/strong&gt;		
	;Check if you need to waffle
	if( (waffle==0) then
		s_via     = 1.0  ; For CTM area &amp;lt; 400 um^2
		offset_var = offset_base
		R_tmp = rodCreateRect(
			?layer        MTOP
			?width        w_MTOP
			?length       l_MTOP
			?termName	  &amp;quot;PLUS&amp;quot;
	    	?termIOType	  &amp;quot;inputOutput&amp;quot;
			?pin		  t
			?pinLabel     t	
			?subRectArray list(
				list(
				    	?layer                VIA
			            ?length		           w_VIA
		        	    ?width  		       w_VIA
		        	    ?spaceX               s_via
		        	    ?spaceY               s_via
		        	    ?lowerLeftOffsetX     enc_VIA_MTOP
		        	    ?lowerLeftOffsetY     enc_VIA_MTOP
		        	    ?upperRightOffsetX   -enc_VIA_MTOP
		        	    ?upperRightOffsetY   -enc_VIA_MTOP
				)
			);subRect
		)
		rodAlign(
			?alignObj     R_tmp
			?alignHandle  &amp;#39;lowerLeft
			?refObj       R_ref
			?refHandle    &amp;#39;lowerLeft
			?xSep         offset_base
			?ySep         offset_var
			)
	else
	
		; calculate the number of horizontal and vertical strips - this is now done in the callback
		; Also calculate the horizontal and vertical spacing
		;n_horiz_strips = floor((l_MTOP + hole_x_min)/(bar_w + hole_x_min))
		sp_h = (float(l_MTOP) - bar_w*num_horiz_strips)/(num_horiz_strips - 1)
		
		;n_vertical_strips = floor((w_MTOP + hole_x_min)/(bar_w + hole_x_min))
		sp_v = (float(w_MTOP) - bar_w*num_vertical_strips)/(num_vertical_strips - 1)
		
	
		;Draw the horizontal bars
    	        ; calculate the number of horizontal vias
		; including two vias in the horizontal spacing for now
		x = bar_w - w_VIA + sp_v
		via_pitch_x = (x-2*w_VIA)/3.0
		;make sure we only use up to 2 significant digits
		via_pitch_x = round(via_pitch_x*100)/100.0
		;printf(&amp;quot;X Pitch %f\n&amp;quot; via_pitch_x)
		y = bar_w - w_VIA + sp_h
		via_pitch_y = (y - 2*w_VIA)/3.0
		via_pitch_y = round(via_pitch_y*100)/100.0
		;printf(&amp;quot;Y Pitch %f\n&amp;quot; via_pitch_y)
		
		; Determine the number of vias in the horizontal direction
	        num_horiz_vias = num_vertical_strips + (num_vertical_strips-1)*2
	        ; Some variables to help drawing	    
	        bet_via_spacing = 0.5*(bar_w - w_VIA)
		bar_offset = 0	    
		
		; start the loop to draw the horizontal strips 
	        ; There&amp;#39;s a nested loop within this to draw the vias
	        ; within the via drawing the nested loop, first draw the vias at the intersection
	        ; of the horizontal and vertical strips, then draw vias between them 
	        ; to avoid replicating data, the intersection vias are only drawn once
		
		for( i 0 (num_horiz_strips-1)
			; Draw the horizontal bars with the vias
			; Make sure you only draw one pin on M3
			R_tmp = rodCreateRect(
					?layer  	MTOP
					?length 	bar_w
					?width  	w_MTOP	
					?termName	  &amp;quot;PLUS&amp;quot;
	    			?termIOType	  &amp;quot;inputOutput&amp;quot;
					?pin		  t
					?pinLabel     t						
			)						
			rodAlign(
				?alignObj     R_tmp
				?alignHandle  &amp;#39;lowerLeft
				?refObj       R_ref
				?refHandle    &amp;#39;lowerLeft
				?ySep         bar_offset
				)
			for( j 0 (num_horiz_vias-1)
				if( (remainder(j,3)==0) then
					R_tmp1 = rodCreateRect(
							?layer  VIA
							?length w_VIA
							?width 	w_VIA
						)
					rodAlign(
							?alignObj     R_tmp1
							?alignHandle  &amp;#39;lowerLeft
							?refObj       R_tmp
							?refHandle    &amp;#39;lowerLeft
							?xSep         bet_via_spacing
							?ySep		  0.5*(bar_w - w_VIA)
						)
					off_via_spacing = bet_via_spacing + w_VIA + via_pitch_x
					bet_via_spacing = bet_via_spacing + bar_w + sp_v 													
				else
					R_tmp1 = rodCreateRect(
							?layer  VIA
							?length w_VIA
							?width 	w_VIA
						)
					rodAlign(
							?alignObj     R_tmp1
							?alignHandle  &amp;#39;lowerLeft
							?refObj       R_tmp
							?refHandle    &amp;#39;lowerLeft
							?xSep         off_via_spacing
							?ySep		  0.5*(bar_w - w_VIA)
						)
					; draw the two between intersection vias at the spacing specified
					off_via_spacing = off_via_spacing + w_VIA + via_pitch_x
					
				)					
				
			); end of via drawing inner loop
			
			bet_via_spacing = 0.5*(bar_w - w_VIA)
			bar_offset = bar_offset + bar_w + sp_h
				
		); end of horiz strips for	
		
		; starting point is the location of the first via
		; lowerLeft of the first via
		bet_via_spacing = 0.5*(bar_w - w_VIA)
		num_vertical_vias = num_horiz_strips + (num_horiz_strips-1)*2
		bar_offset = 0
		
		
		for( i 0 (num_vertical_strips-1)
			;Draw the vertical bars with the vias
			R_tmp = rodCreateRect(
				?layer 		MTOP
				?length 	l_MTOP
				?width 		bar_w	
				?termName	  &amp;quot;PLUS&amp;quot;
	    		?termIOType	  &amp;quot;inputOutput&amp;quot;
				?pin		  t
				?pinLabel     t				
			)
			rodAlign(
				?alignObj     R_tmp
				?alignHandle  &amp;#39;lowerLeft
				?refObj       R_ref
				?refHandle    &amp;#39;lowerLeft
				?xSep         bar_offset
			)
			for( j 0 (num_vertical_vias-1)
				if( (remainder(j,3)==0) then
					R_tmp1 = rodCreateRect(
							?layer  VIA
							?length w_VIA
							?width 	w_VIA
						)
					rodAlign(
							?alignObj     R_tmp1
							?alignHandle  &amp;#39;lowerLeft
							?refObj       R_tmp
							?refHandle    &amp;#39;lowerLeft
							?xSep         0.5*(bar_w - w_VIA)
							?ySep		  bet_via_spacing
						)
					off_via_spacing = bet_via_spacing + w_VIA + via_pitch_y
					bet_via_spacing = bet_via_spacing + bar_w + sp_h 													
				else
					R_tmp1 = rodCreateRect(
							?layer  VIA
							?length w_VIA
							?width 	w_VIA
						)
					rodAlign(
							?alignObj     R_tmp1
							?alignHandle  &amp;#39;lowerLeft
							?refObj       R_tmp
							?refHandle    &amp;#39;lowerLeft
							?xSep         0.5*(bar_w - w_VIA)
							?ySep		  off_via_spacing
						)
					; draw the two between intersection vias at the spacing specified
					off_via_spacing = off_via_spacing + w_VIA + via_pitch_y
					
				)					
				
			); end of via drawing inner loop
			bet_via_spacing = 0.5*(bar_w - w_VIA)
			bar_offset = bar_offset + bar_w + sp_v	
		); End of vertical strip drawing loop
	  			
	); end of else if
	
	
	
); end of let

); end of PCell definition


&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Callback Code Not Working as Intended</title><link>https://community.cadence.com/thread/1382450?ContentTypeID=1</link><pubDate>Fri, 25 Mar 2022 14:03:37 GMT</pubDate><guid isPermaLink="false">75bcbcf9-38a3-4e2e-b84b-26c8c46a9500:5eebb12e-493e-4824-be0d-42f8edacbe61</guid><dc:creator>Andrew Beckett</dc:creator><description>&lt;p&gt;I reformatted the code above (I have an internal tool that will reformat SKILL code to indent it somewhat sensibly). In general one approach I often use is put the code in a file with a &amp;quot;.txt&amp;quot; suffix and then open that file from a web browser and then copy and paste from there. That said, I&amp;#39;m on a Mac - so your mileage may vary - normally I don&amp;#39;t have too much trouble pasting code.&lt;/p&gt;
&lt;p&gt;Your description of the problem though isn&amp;#39;t really very clear. You&amp;#39;ve posted the callback code, but then said:&lt;/p&gt;
[quote userid="526540" url="~/cadence_technology_forums/f/custom-ic-skill/51332/callback-code-not-working-as-intended/1382430#1382430"]Oh, and to clarify what&amp;#39;s going wrong: When I enter W = 30u and L = 12u, the pCell code fails - i.e. It doesn&amp;#39;t draw what it&amp;#39;s supposed to draw. That&amp;#39;s the only condition it fails on![/quote]
&lt;p&gt;So you&amp;#39;ve said it&amp;#39;s failing in the&amp;nbsp;&lt;span style="text-decoration:underline;"&gt;pCell&lt;/span&gt; code, which you&amp;#39;ve not shared. Maybe you meant the callback code, but that doesn&amp;#39;t have anything to do with drawing. If it&amp;#39;s the callback that&amp;#39;s failing, please specify the values of the other CDF parameters that trigger the failure (rather than me trying to work out what you really meant) - there are values for c, ratio, m, rem_h_strip, n_horiz_strips and n_vertical_strips also involved as well as w and l.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If it&amp;#39;s a problem with the Pcell code, then I guess it would be necessary to see the Pcell code too.&lt;/p&gt;
&lt;p&gt;Andrew&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Callback Code Not Working as Intended</title><link>https://community.cadence.com/thread/1382430?ContentTypeID=1</link><pubDate>Thu, 24 Mar 2022 20:40:08 GMT</pubDate><guid isPermaLink="false">75bcbcf9-38a3-4e2e-b84b-26c8c46a9500:e060d325-4084-4069-a68c-973f0f670f8f</guid><dc:creator>Ynishant</dc:creator><description>&lt;p&gt;Hi Andrew,&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;The portion of the code I pasted in my original message is only a snippet. The callback code in its entirety is copy-pasted below. It&amp;#39;s an updated version that seems to work, but I just can&amp;#39;t figure out why it works and it&amp;#39;s driving me nuts. I can&amp;#39;t seem to find a way to attach a file or paste the code in a manner that makes it more readable. Perhaps you can recommend a better way to paste code here and I can give it another go.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;Oh, and to clarify what&amp;#39;s going wrong: When I enter W = 30u and L = 12u, the pCell code fails - i.e. It doesn&amp;#39;t draw what it&amp;#39;s supposed to draw. That&amp;#39;s the only condition it fails on!&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;Nishant.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Note from moderator: reformatted code to make it easier to read...&lt;/p&gt;
&lt;pre&gt;procedure(mim_m2cs_init(cdfgData)
  mim_cb(&amp;#39;Width)
 )

;; This is the common init/CB procedure used for the MIM caps
procedure(mim_cb(paramName)
  prog(value(w l c ratio area num_horiz_strips num_vertical_strips sp_h sp_v remove_horiz waffle)
       
       ; Load values
       l = cdfParseFloatString(cdfgData~&amp;gt;l~&amp;gt;value)
       w = cdfParseFloatString(cdfgData~&amp;gt;w~&amp;gt;value)
       c = cdfParseFloatString(cdfgData~&amp;gt;c~&amp;gt;value)
       ratio = cdfParseFloatString(cdfgData~&amp;gt;aspect_ratio~&amp;gt;value)
       m = cdfParseFloatString(cdfgData~&amp;gt;m~&amp;gt;value)
       remove_horiz = cdfParseFloatString(cdfgData~&amp;gt;rem_h_strip~&amp;gt;value)
       num_horiz_strips = cdfParseFloatString(cdfgData~&amp;gt;n_horiz_strips~&amp;gt;value)
       num_vertical_strips = cdfParseFloatString(cdfgData~&amp;gt;n_vertical_strips~&amp;gt;value
                                                )
       
       
       waffle = waffle_or_no(w l)
       ;warn(&amp;quot;Waffle Status %d&amp;quot; waffle)
       
       
       ;warn(sprintf( nil &amp;quot;Initial Values: w=%g l=%g c=%g ratio=%g&amp;quot; w l c ratio))
       ; Calculate the number of vertical and horizontal strips if the cap area is &amp;gt;= 400 um^2
       if(waffle == &amp;quot;no&amp;quot;
           then
               
               area = 100
               num_horiz_strips = 0
               num_vertical_strips = 0
               
           else
               num_horiz_strips = mim_calc_n_strips(l)
               num_vertical_strips = mim_calc_n_strips(w)
               
               ; Calculate the horizontal and vertical spacing
               sp_h = mim_calc_bar_spacing(l num_horiz_strips)
               sp_v = mim_calc_bar_spacing(w num_vertical_strips)
               
               ;Calculate the area
               area = mim_measure_m3_area(w l num_horiz_strips num_vertical_strips sp_h sp_v)
               
          )
        ; end of if 
       
       if(remove_horiz &amp;gt; 0
           then
               ; force the number of strips to be removed to be &amp;lt;=2 
               remove_horiz = mim_check_number_removals(remove_horiz)
               num_horiz_strips = num_horiz_strips - remove_horiz
               ; Calculate the horizontal and vertical spacing
               sp_h = mim_calc_bar_spacing(l num_horiz_strips)
               ;Re-Calculate the area
               area = mim_measure_m3_area(w l num_horiz_strips num_vertical_strips sp_h sp_v)
               
          )
       ; Do final value chacks
       l = mim_check_dim(l)
       w = mim_check_dim(w)
       ;adjust the ratio according to whichever dimension is bigger
       ratio = max(w l) / min(w l)
       ;warn(sprintf( nil &amp;quot;Initial Values: w=%g l=%g c=%g ratio=%g&amp;quot; w l c ratio))
       
       ; Do final capacitance calculation
       c = mim_calc_cap(w l m)
       
       ; Write back to form
       cdfgData~&amp;gt;l~&amp;gt;value = aelSuffixNotation(l)
       cdfgData~&amp;gt;w~&amp;gt;value = aelSuffixNotation(w)
       cdfgData~&amp;gt;c~&amp;gt;value = aelSuffixNotation(c)
       cdfgData~&amp;gt;aspect_ratio~&amp;gt;value = aelSuffixNotation(ratio)
       cdfgData~&amp;gt;m3_density~&amp;gt;value = aelSuffixNotation(area)
       cdfgData~&amp;gt;n_horiz_strips~&amp;gt;value = aelSuffixNotation(num_horiz_strips)
       cdfgData~&amp;gt;n_vertical_strips~&amp;gt;value = aelSuffixNotation(num_vertical_strips)
       cdfgData~&amp;gt;rem_h_strip~&amp;gt;value = aelSuffixNotation(remove_horiz)
      )
 )
procedure(waffle_or_no(w l)
  let((waffle
       cap_area
       scale
       w_n
       l_n
      )
    scale = 1000000.0
    cap_area = w * scale * (l * scale)
    w_n = w * scale
    l_n = l * scale
    if(cap_area &amp;lt;= 400.0
        then
            if(((w_n &amp;gt; 30) &amp;amp;&amp;amp; (l_n &amp;gt; 12)) || ((l_n &amp;gt; 30) &amp;amp;&amp;amp; (w_n &amp;gt; 12))
                then
                    waffle = 1
                else
                    waffle = 0
               )
        else
            waffle = 1
       )
    
    
    waffle ; return the waffle status
   )
 )

procedure(mim_check_number_removals(value)
  let((max_removals
      )
    max_removals = 1
    if(max(value max_removals) &amp;gt; 1
        then
            value = max_removals
       )
    
    value ; return value
   )
  
 )

;; Helper function to check W &amp;amp; L dimenstions
procedure(mim_check_dim(value)
  let((min_value
       max_value
      )
    ; setting the max width to 80 um and the min width to 5 um for now; Same for length
    min_value = 5e-06
    max_value = 8e-05
    if(max(value max_value) &amp;gt; max_value
        then
            warn(&amp;quot;Max dimension is 80um&amp;quot;)
            value = max_value
       )
    if(min(value min_value) &amp;lt; min_value
        then
            warn(&amp;quot;Min dimension is 5.0um&amp;quot;)
            value = min_value
       )
    
    ; finally force the value to a 0.1 um grid
    ;value = round(value*10)/10.0
    
    value ; return value for the procedure
   ) ;end of let
  
 )


; Procedure to calculate the number of horizontal or vertical strips in a MIM
procedure(mim_calc_n_strips(value)
  let((n_horiz_strips
       n_vertical_strips
       hole_x_min
       bar_w
      )
    ; This is the width of the strip 
    bar_w = 2.5
    scale = 1000000.0
    ; This is the minimum size of the hole
    hole_x_min = 3.0
    n_strips = floor(((value * scale) + hole_x_min) / (bar_w + hole_x_min))
    
    n_strips
   )
 )

; Procedure to calculate the bar-bar spacing
procedure(mim_calc_bar_spacing(dimension num_strips)
  let((spacing
       bar_w
      )
    bar_w = 2.5
    scale = 1000000.0
    spacing = (float(dimension * scale) - (bar_w * num_strips)) / (num_strips - 1)
    
    spacing
   )
 )

;; Helper function to calculate the M3 Density
procedure(mim_measure_m3_area(w l num_h_strips num_v_strips width_spacing length_spacing)
  let((top_m_area
       hole_area
       num_holes
       scale
       strip_width
       m3_area
       density
      )
    ; Factor to sure everything is not in microns for the area calculations 
    scale = 1000000.0
    ; The strip width in the layout is set to a standard 2.5 um
    strip_width = 2.5
    top_m_area = w * scale * (l * scale)
    num_holes = (num_h_strips - 1) * (num_v_strips - 1)
    hole_area = num_holes * width_spacing * length_spacing
    m3_area = top_m_area - hole_area
    density = (m3_area / top_m_area) * 100.0
    density ; return value
    
   )
 )

;; Helper function to calculate capacitance value
procedure(mim_calc_cap(w l m)
  let((area
       perim
       ca
       cp
       dx
       cap_ffmm
       perim_f
       total_cap_value
      )
    
    ;dx is the factor that accounts for the mask bias
    ;cap_ffmm is the ff/mm capacitance factor
    ;perim_f is the fringing capacitance parameter 
    dx = -1.2e-07
    cap_ffmm = 0.00135
    perim_f = 1.5e-10
    area = (w + dx) * (l + dx)
    perim = 2 * (w + dx + (l + dx))
    
    ca = area * cap_ffmm
    cp = perim * perim_f
    total_cap_value = m * (ca + cp)
    
    total_cap_value ; This is the return value for the procedure
   )
 )&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Callback Code Not Working as Intended</title><link>https://community.cadence.com/thread/1382429?ContentTypeID=1</link><pubDate>Thu, 24 Mar 2022 20:20:12 GMT</pubDate><guid isPermaLink="false">75bcbcf9-38a3-4e2e-b84b-26c8c46a9500:4ea0547b-18d3-4769-9e72-625e3456c8a0</guid><dc:creator>Andrew Beckett</dc:creator><description>&lt;p&gt;Your callback code doesn&amp;#39;t really do anything. It sets a variable called&amp;nbsp;&lt;em&gt;waffle&lt;/em&gt;&amp;nbsp;(and then doesn&amp;#39;t do anything with that) but I don&amp;#39;t see it updating any CDF parameters. What are you expecting it to do or what is going wrong?&lt;/p&gt;
&lt;p&gt;Andrew&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>