Forum Replies Created
-
AuthorPosts
-
Ronald
KeymasterDear Rastko,
That sounds like an interesting workaround for a circuit description. You may get into trouble though for identifying connectivity for components like MMIs, having >2 circuit pins. That said, circuit connectivity is already (being) moved into higher-lever Nazca functionality for cases as you describe. That concept also allows you to add your circuit/functional information to existing Nazca cells and parse that via the circuit netlist into your circuit simulator. In that way you can use Nazca more or less as a Python-based parser for your simulation set-up. An added value is that you describe an accurate mask layout at the same time.
Ronald
Ronald
KeymasterDear Rastko,
To reproduce a circuit netlist the following steps are needed for each cell in a design:
– find the instances in the cell that represent a “circuit element”
– find the (circuit relevant) pin connections between these instances
– find the original cell of each instance needed to recreate the instance
– export the connectivity something like “cell_1.pin_a, cell_2.pin_b, parameters”The above is expected to be part of the next Nazca release (0.4.4).
Note that the circuit netlist is not the same as the layout netlist to generate gds.In Nazca 0.4.3 your example method ‘get_cells’ can be implemented as follows.
def get_cells(top): tree = nd.cell_iter(top) cells = [] for params in tree: if params.cell_start and params.level == 0: for inode, xya, flip in params.iters['instance']: cells.append(inode.cell.cell_name) return cells print(get_cells(tc))The output shows the (parent cell) names of all instances. In your example:
['SOA', 'Phase modulator']The following example shows how to read the cell objects into a dict and reuse them:
def get_cells(top): tree = nd.cell_iter(top) cells = {} for params in tree: if params.cell_start and params.level == 0: for inode, xya, flip in params.iters['instance']: cells[inode.cell.cell_name] = inode.cell return cells cells = get_cells(tc) print(cells)After that you can put cells via the dict into a layout:
cells['SOA'].put()In your external simulator case you may want to extract different or more information/parameters from the cell such as component length, waveguide width, compact model, etc.
Ronald
Ronald
KeymasterDear Alvin,
The trace has moved to its own module.
Traces are registered for mask_elements and their derived elements like interconnects.
Below an example to get the geometrical length of some interconnects put or for a specific element by reference:import nazca as nd import nazca.trace as trc import nazca.demofab as demo trc.trace_start() E1 = demo.deep.bend(angle=45).put() E2 = demo.deep.strt(length=100).put() trc.trace_stop() print(trc.trace_length(), E2.length_geo)output
158.904862255 100Ronald
Ronald
KeymasterDear alvin,
Thank you for your interesting question. First the solution:
A = cellA.put() cellB.put(A.pin['lb'].move(0, -50))Hence, simply use the pin (Node) methods: move, rot, skip, offset.
It works as as follows:A = cellA.put() # place cellA in cell 'nazca' as instance variable A cellB.put(A.pin['lb'].move(0, -50)) # connect cellB relative to pin['lb'] of instance AIt is best to avoid the cp syntax. The preferred syntax is simpler and more intuitive and lets Nazca do the thinking.
What happens in your first example is several things:
nd.cp.goto_pin(cellA.pin['lb'])
moves the “current pin” cp to a pin inside cellA. I assume here cellA is a Cell object and not an Instance.
nd.cp.move(0, -50)
generates a new pin (Node object) w.r.t. cp and places it in the present (active) Cell, i.e. cell ‘nazca’. However, this new pin is higher up in the hierarchy than cellA. It is not possible to connect pins between cell hierarchies. It violates (gds) hierarchy, hence the Exception.
If you insist on cp syntax, below is how do it right, i.e. connect to an instance of cellA, not to cellA directly:
A = cellA.put() nd.cp.goto_pin(A.pin['lb']) nd.cp.move(0, -50) cellB.put()The take away is that the pins inside a “closed” or “finished” cell are not allowed for direct connection (the cell is closed). Instantiating the closed cell in the cell under construction, the active cell, however, creates new pins in the active cell, which can be connected to. Nazca will check for consistency to avoid topological errors in your gds.
In the second case:
nd.cp.goto_pin(cellA.pin['lb']) xya = nd.cp.here()
nothing new happens, xya is the same Node as after cp.goto_pin()
nd.cp.goto(xya.x,xya.y)
creates a new pin in cell ‘nazca’ based on the floats in (xya.x, xya.y), which are coordinates w.r.t. cellA!
nd.cp.move(0, -50)
this time over the connections are all inside cell ‘nazca’ and all seems well, but …, there is a catch from the previous lines of code: position (0, 50) is measured from the origin of cellA but applied w.r.t. origin of cell ‘nazca’.
An other case:
Note that in a similar way it is not allowed to connect cellB inside cellA after cellA was created:
cellB.put(cellA.pin['lb']) Exception: You are trying to connect to a closed Cell object
If you need cellB inside cellA simply put cellB there during the definition of cellA.
Ronald
Ronald
KeymasterDear Alvin,
There is a pandas DataFrame with the xsection(s) definition(s):
import nazca as nd # your code ... # print the xsection definitions: nd.show_xsection_layer_map() # work with the underlying DataFrame: df = nd.cfg.xsection_layer_map print(df[df['xsection']=='sifab'][['layer', 'growx']])Maybe a DataFrame is a little laborious to obtain the grow number. Alternatively, store the growx in a variable first and use it later where needed.
Ronald
KeymasterDear risenandshine,
The offset is correct (intended). The warning is an unrelated warning of the pandas module in newer versions, without any consequences.
The offset is to create an optically smooth transition between the straight and bent waveguides. It is based on mode solver calculations in the waveguides on either side of the junction. You only would need to change the offset if you define your own technology from scratch.
Ronald
Ronald
KeymasterDear Alvin,
A good way forward is to look into the demofab implementation, which you can find in the installer .zip file:
Open the zip and navigate to the nazca/demofab/ directory. Copy the files as a start for your own implementation.To find/see attributes of an object in a typical Python development environment you can use tab completion:
xs1.<press tab>You can print attribute values that may or may not be defined like:
try: print(xs1.os) except: print("no os attribute defined")Alternatively, Python lets you query the available attributes and methods like
import nazca.demofab as demo dir(demo.xsShallow)Also, an official Nazca PDK comes with a dedicated manual. The website will be extended for this soon.
Hope this helps.Ronald
Ronald
KeymasterIn addition to Xaveer’s answer, the below examples show how to define a xsection and offset from scratch, i.e. without importing demofab. The first example uses the generic ‘strt’ and ‘bend’ functions to draw the waveguides.
import nazca as nd xs1 = nd.add_xsection(name='new_xs') xs1.os = 0.5 nd.strt(length=10, xs='new_xs').put() nd.bend(angle=10, xs='new_xs').put() nd.export_gds()It can be convenient to work with ‘interconnects’ that remember their xs, width, radius, etc.
See the example below and the interconnect tutorial on how to use them.import nazca as nd xs1 = nd.add_xsection(name='new_xs') xs1.os = 0.5 waveguide = nd.interconnects.Interconnect(width=2, radius=20, xs='new_xs') waveguide.strt(length=10).put() waveguide.bend(angle=10).put() nd.export_gds()Ronald
Ronald
KeymasterHi Kristif,
You are probably referring to a PDK or library building block type cell. You would have to apply whatever layout rules are defined by the maker or provider of the block. If the cell’s content is replaced at the foundry, then you very typically should not cross the bounding box, as what looks empty in your view, may have (unexpected) content after replacement.
Ronald
Ronald
KeymasterHi layouteng,
Yes this is possible with the load_gds method.
In short:cellA = nd.load_gds(filename='library.gds', cellname='A') cellA.put(0, 20, 20, flip=True)A more extended copy-paste example:
import nazca as nd # Create a GDS library to use in the load_gds example: with nd.Cell('A') as A: nd.Polygon(points=[(0, 0), (10, 0), (0, 5)]).put(0) with nd.Cell('B') as B: nd.Polygon(points=[(0, 0), (-5, 5), (0, 1)]).put(0) nd.export_gds([A, B], filename='library') # and the actual load_gds example: cellA = nd.load_gds(filename='library.gds', cellname='A') cellB = nd.load_gds(filename='library.gds', cellname='B', scale=5.0) cellA.put(0) cellA.put(10, 20, 45) cellB.put(20, flip=True) cellB.put(20, flop=True) nd.export_gds(filename='use_a_gds_library')See the load_gds docstring for more options.
Ronald
Ronald
KeymasterHi Kyung Hun Yoon,
Assuming you go the gds format in the end, the polygon should not have crossing lines and should have a “direction” such that if you travel along your polygon, the right hand side of your line always “points” to the area between your rectangle and hexagon. Here some ways to subtract a shape inside another shape:
1. Place the rectangle and hexagon in different mask layers and consider subtraction in a post-processing step on your mask. In KLayout for example you can perform boolean operations fast and efficiently (Edit/Layer/Boolean Operations).
2. Construct your polygon by adding the hexagon points to the rectangle points while taking into account the direction and the closure of the polygons (end-point = start-point), for example:
import nazca as nd square1 = [(0, -5), (5, 0), (0, 5), (-5, 0), (0, -5)] square2 = [(-10, -10), (10, -10), (10, 10), (-10, 10), (-10,-10)] diff = square2 + square1[::-1] # reverse direction of inner shape square1 nd.Polygon(layer=1, points=square1).put() nd.Polygon(layer=3, points=square2).put() nd.Polygon(layer=5, points=diff).put(30) nd.export_gds()3. Use the pyclipper module in Nazca (nazca.clipper), however, this will not work well for a subtraction of shapes fully inside another shape, because pyclipper is not restricted to gds type of polygon concepts.
Ronald
Ronald
KeymasterHi Kristif,
The pins in a cell (“component”) reside in a Python dictionary attribute named ‘pin’.
Hence, if you have cell named C then you can print all pins with
print(C.pin)The method xya() of a pin gives you the coordinates (x, y, a), but the pin also stores attributes like the xsection (xs) and width. To print specific info on all pins in a cell you can use the following loop over the pin dict:
for name, pin in C.pin.items(): print("pin '{}'\n position: {}\n xs: {}\n width: {}".\ format(name, pin.xya(), pin.xs, pin.width))Similarly, if cell C has a pin named ‘a0’, you can get the coordinates as
x, y, a = C.pin['a0'].xya()Ronald
Ronald
KeymasterHi CDaunt,
I agree with your observations on user and technical level.
Conversion between a Nazca cell and a KLayout cell should do the trick. Nazca internally has a detailed hierarchical representation of a layout and/or circuit, which can be exported modularly to various output formats like gds, svg, png, netlist, nazca-script, etc., while collapsing (part of) the hierarchy where desired or required. I haven’t studied the KLayout elements in great detail, but my impression is that the structure is very similar. For an exchange back and forward (one way is very restrictive and frustrating in a design flow) a superset of attributes is required. I am not to worried about types for PCells, as these can be stored as attributes in an exchange/conversion. In Nazca we can keep track of parameter types and range checking. It adds some book-keeping regarding parameter type-casting and units, but that is not bad from an engineering perspective. I do not see great technical issues and think it is less of a software challenge than the right design-interface/flow choices from a designer’s perspective.Ronald
KeymasterHi CDaunt,
The short answer is: yes.
The longer answer is that PCell integration and libraries in a drag & drop environment for mask layout, e.g. in KLayout, can be very useful for beginning designers to navigate through BBs and options. Also, such environment is useful to accomplish, or experiment with, the coarse layout floor plan for any level designer. However, with a growing number of components, or with more experience with Nazca script, the scripting environment tends to become (much) more efficient than clicking your way through drag & drop menu’s. A smooth integration between both worlds is the ideal case. PCell integration in KLayout in this context is therefore a noble goal. It is within reach. The SiEPIC project, for example, already provides PCells integration in KLayout. Underpinning such concepts with Nazca netlisting and scripting capabilities will, I believe, provide an even more flexible and powerful design environment for any PIC designer.
Ronald
-
AuthorPosts