- This topic has 3 replies, 2 voices, and was last updated 4 years, 7 months ago by Ronald.
-
AuthorPosts
-
24 February 2020 at 15:36 #6016CecilMember
Hello Nazca team,
I am trying to use the replaceCells function using the PcellFunctionMap argument to convert blackboxes into pcells with the desired parameters.
It looks like this:
def blackbox(width_wg, offset, radius): with nd.Cell(name='blackbox', cnt=True) as C: length = some_calculation(offset, radius) nd.Pin('a0').put(0,0,180) nd.Pin('b0').put(length, offset) nd.put_stub() nd.put_boundingbox(length, offset, (0,0,0)) return C def white_pcell(width_wg=2, offset=100, radius=500, layer=1): with nd.Cell(name='white_pcell', cnt=True) as C: length = some_calculation(offset, radius) # do some stuff to create the pattern # same pin placement as above return C nd.strt(width=2, length=200, layer=1).put(0) blackbox(width_wg=2, offset=150, radius=1000).put() blackbox(width_wg=2, offset=20, radius=500).put() nd.export_gds('test') # Import and conversion black to white: d = {'blackbox': white_pcell} nd.replaceCells(gdsin='test.gds', gdsout='testwhite', PcellFunctionMap=d)
The replacement of the cell in the gds file works, however only default parameters are used for white_pcell generation. I haven’t found a way to pass down custom parameters to the replaceCells function to use for the white_pcell function. Is there a way to do it ?
Best regards,
Cecil
29 February 2020 at 18:50 #6025RonaldKeymasterDear Cecil,
Your approach is correct. What is missing is that you need to fill the cell’s ‘parameter’ attribute with a dict like {parametername : value}. The parametername is expressed as a string.
This parameter attribute is automatically filled by the @hashme decorator, which I added in the example below to your ‘blackbox’ in combination with an autobbox=True. To give the autobbox dimension in your case with only two pins, I added the userbbox. The autobbox finds the boundaries and calls the correct put_boundingbox() function internally, so that explicit call can be deleted.
In all it adds a boundingbox and all the blackbox function parameters as annotation to the gds. Those parameters are read back in during the pcell replacement to generate the parametric white cell. I also added some keywords to your calls to make the code more robust. Additionally, I added version info to your cell via the ‘version’ attribute of the cell, which adds a extra information to the black cell, again as annotation.
This pcell flow can be used for IP protection and there are several more elements to this flow to make this pcell IP-replacement work in basically any situation. If you know your pcell names you can simply look for them in the gds, but Nazca can also detect “unknown” pcells, as well as tempering with black boxes to make the whole process 100% reliable. All these features require a somewhat longer tutorial.
import nazca as nd version = {'owner': 'cecil'} def some_calculation(offset, radius): return 2.0 + offset + 0.5*radius @nd.bb_util.hashme('blackbox') def blackbox(width_wg, offset, radius): with nd.Cell() as C: C.version = version length = some_calculation(offset, radius) C.userbbox = [(0, -1.5*offset), (length, -1.5*offset), (length, 1.5*offset), (0, 1.5*offset)] C.autobbox = True nd.Pin('a0').put(0, 0, 180) nd.Pin('b0').put(length, offset) nd.put_stub() return C def white_pcell(width_wg=2, offset=100, radius=500, layer=1): with nd.Cell(name='white_pcell', cnt=True) as C: length = some_calculation(offset, radius) nd.strt(length=length, width=width_wg).put(0) # do some stuff to create the pattern # same pin placement as above return C nd.strt(width=2, length=200, layer=1).put(0) blackbox(width_wg=2, offset=150, radius=1000).put() blackbox(width_wg=2, offset=20, radius=500).put() nd.export_gds(filename='test') # Import and conversion black to white: d = {'blackbox': white_pcell} nd.replaceCells(gdsin='test.gds', gdsout='testwhite.gds', PcellFunctionMap=d)
Ronald
3 March 2020 at 12:44 #6031CecilMemberDear Ronald,
I found a similar solution in the meantime by manually adding an annotation using nd.Annotation and a formatted string, however your solution seems more robust and elegant.
I have one more question though, how would you pass down arguments that are not present in the blackbox (“hidden” from the user but necessary on my side), but needed in the pcell ? In the following example, I would like to pass down the “width_output” argument without the user having to interact with it :
def blackbox(width_wg, offset, radius): # do things def white_pcell(width_wg, offset, radius, width_output): # do other things
Thanks a lot for your answers,
Cecil
14 March 2020 at 17:30 #6042RonaldKeymasterDear Cecil,
If I understand your new question correctly you want to add an extra parameter, here width_output, on your side to the whitebox in addition to the blackbox parameters. Such a parameter should not affect any pin positions or bbox size. I can not image a direct use case, unless you do something like porting the same black box to two different processes internally. You can probably use the partial method from Pythons functools module. It basically applies, in the example below, the width_output parameter before feeding the white_pcell into the replacement dictionary. After partial(white_pcell, width_output) only the blackbox parameters are left. Referring to the example code in my reply above above this looks like
from functools import partial ... def white_pcell(width_wg, offset, radius, width_output): # do other things ... d = {'blackbox': partial(white_pcell, width_output)}
Ronald
-
AuthorPosts
- You must be logged in to reply to this topic.