It looks like you're new here. If you want to get involved, click one of these buttons!
Hello, I have a question regarding the TilingProcessor and expressions.
I have the following (shortened) setup:
tp = RBA::TilingProcessor::new
tp.frame = chip
tp.dbu = ly.dbu
tp.threads = threads
tp.tile_size(tile_size, tile_size)
tp.input("COMP", ly, top_cell.cell_index, COMP)
tp.input("Poly2", ly, top_cell.cell_index, Poly2)
tp.input("PMNDMY", ly, top_cell.cell_index, PMNDMY)
tp.var("space_to_COMP", 3.5 / ly.dbu)
tp.var("space_to_Poly2", 1.5 / ly.dbu)
tp.output("to_fill", TilingOperator::new(ly, top_cell, fill_cell.cell_index, fc_box_in_dbu, row_step_in_dbu, column_step_in_dbu, fc_origin_in_dbu))
tp.queue("
var COMP_20um_spacing = COMP.sized(20um).sized(-20um)
var fill_region = _tile & _frame - COMP_20um_spacing.sized(space_to_COMP) - Poly2.sized(space_to_Poly2) - PMNDMY;
_output(to_fill, fill_region)")
I get the following error:
ERROR: Worker thread: Length or area value with unit requires a layout context at line 3, position 36 (..20um).sized(-20um)
Which makes a lot of sense, however since the tiling processor has information about the dbu, shouldn't it be possible to convert the length value?
Or is there another way to supply the layout context?
As a workaround I can supply the constant as a variable like I did for the spacing:
tp.var("um20", 20 / ly.dbu)
Let me know if you need a full reproducible.
Thanks!
Comments
Hi Leo,
You're correct, the layout context is not there and it's not just the DBU, with a layout context for example you can obtain layer indexes using angle brackets (e.g. "<2/0>" turns into the layer index). Bottom line is: a "layout context" is really a layout and although the tiling process gets the DBU, the layout is a not readily accessible.
My recommendation was to turn the "20 µm" value into a variable like you suggested. I feel it's a good practice to define every physical value somewhere globally, so I would write:
(this is how I understand the intention of the code).
BTW: in case you're trying filling, have you seen this: https://www.klayout.de/forum/discussion/2620/fill-multiorigin-and-manufacturing-grid#latest ?
(and please use static origin, I am not happy with the auto_origin or multi_origin feature. Needs work
)
Best regards,
Matthias
Hi Matthias,
Thank you for the explanation! I will go with the variables
No, I haven't seen the latest update yet. Very cool!
Yes, I'm actually working on fill, but not for ihp-sg13g2
This is for gf180mcu, where the fill rules are much simpler. It's just a fixed shape with a fixed stagger.
However, I'm really looking forward to all the fill improvements! Having a reliable fill method for ihp-sg13g2, even for dense digital designs, would be absolutely great 🙌
One more question: Have you thought about variable-size fill shapes? Magic allows to specify a minimum and maximum length, and will then try to fit the largest fill shapes.
It is quite useful to get the to the last missing percent of density. However, I'm not sure how valuable this feature really is: whether modern process nodes allow arbitrary fill shapes, and whether it' actually needed (maybe not all processes are as picky as ihp-sg13g2).
Best,
Leo
Hi Leo,
The way I know variable fill is implemented is by placing some grating pattern over your layout, the subtract the non-fill regions with some sizing and then clean up the cut grating parts with a under/oversize to remove the pieces where the grating a partially clipped. Finally the lines could be cut into pieces with a maximum length using a polygon processor.
That should not be too difficult to implement, but from perspective of process isotropy and parasitic coupling, I think that the square fill pattern is easier to handle. I have seen line fill in advances nodes with a pronounced isotropic lithographic setup (dipole illumination) and multi-patterning. I think however, in these cases it's more common to include fill pattern in form of dummy gates for example.
Matthias
Thank you for all the information, Matthias!
Anyways, for now a simple fill is sufficient on gf180mcu
I have one more question about the filler generation:
I'm using
sized
to ensure the minimum spacing between the dummy comp and the other layers.However, for euclidean measurements the spacing (3.5um) is violated, as you can see:
(The filler cell is the red one.)
I don't quite understand why this is happening.
I could pass a different mode to
sized
, but this should only change how corners are handled.Does
fill_region
somehow need to use euclidian measurements?Leo
Hi Leo,
Basically the sizing implements an edge shift, so provided, the filler (red shape I assume) is outside the sized region, it should observe the Euclidian distance. I suspect the latter is not the case. First thing I'd try is to confirm that the fill shapes are inside the allowed area by dumping the sized layer. If that is not the case, then there is a problem with the fill shape definition I assume. Maybe you can share the current script, so I can take a look.
I also like to use this opportunity to advertise some new features of KLayout 0.30.4 - namely "margin" for the fill pattern (helps keeping a distance without need for "sized") and "fill_exclude" ("fill" method) which avoids having to do the boolean NOT for computing the area to fill.
Best regards,
Matthias
Hi Matthias,
As this is a Ruby script that uses the
TileOutputReceiver
, I'm not sure how easy it is to dump the sized layers.Perhaps you can take a quick look: https://github.com/wafer-space/gf180mcu/tree/ed1a3104ffe3dc387276e1bc9f031f6f5071092b/gf180mcuD/libs.tech/klayout/tech/drc/filler_generation
But maybe don't put too much time into this. I'll convert this to a DRC script soon, like you have done for Greyhound, as this seems to be the better way to do fill.
fill_exclude
sounds great! However, I don't think I can usemargin
on gf180mcu, since I need to keep different distances to different layers.See the Dummy COMP rules for example: https://gf180mcu-pdk.readthedocs.io/en/latest/physical_verification/design_manual/drm_13_1.html
Thanks a lot for your help!
Leo