Skip to content

Latest commit

 

History

History
182 lines (151 loc) · 9.14 KB

File metadata and controls

182 lines (151 loc) · 9.14 KB

Contributing

Hello and thanks for considering contributing to openPCells. This project is intended to be used and enhanced by many people, gathering different kinds of knowledge. It's target users are designers/layout engineers of integrated circuits, mostly on the analog/mixed-signal side.

How do I contribute?

All kinds of contributions are welcome, including (but not limited to) feature requests, bug fixes, cell defintions, documentation enhancements and technology definitions. Furthermore, the provided cells are currently not being tested in many technologies, as this needs access to those. If you are working with integrated circuits and have technology access, testing the generated layouts of various cells with different parameter values is very valuable for improving the code of the cells.

I try to add stuff that needs fixing or implementing to the todo file. There is of course also the issue list on github, but that's probably out-of-sync.

Development Overview

The main entry point (the main function) is in src/main.c.

Build and Development Process

The project follows a traditional ./configure.sh; make approach. The configure script does not check any platform dependencies: The code tries hard to avoid any issues that arise from platform dependencies. I tested this on various linux systems/compilers/compiler versions, but there will definitely be remaining issues. For the development this means in general:

  • target C versions is C99
  • standard adherence is aimed for, no compiler extensions should be employed
  • avoid C library functions that need specific feature macros set (e.g. _XOPEN_SOURCE ...). In my experience this complicates compilation with different compiler versions and systems

The main Makefile only hands the build jobs to Makefiles in subdirectories: src/Makefile and doc/Makefile. The main Makefile is generated from ./configure.sh, the others are hard-coded. The actual Makefiles don't try to be clever, dependencies are listed explicitly and periodically updated by calling gcc -MM -MG (...).

Dependencies

None. This project is meant to be installable by users of ancient CAD servers, that might run on a not-supported-anymore version of centOS or something. We can not assume that the user of this software has any install priviliges and there might also be no or not fast support from their IT team. Hence everything here is built from scratch. Additionally, the reason for the --all-load-paths-local configuration option also comes from the need for simple installation without priviliges.

Versioning

The opc version looks like semantic versioning, but it's not really. This is partly due to it begin pre-1.0, partly because I feel that semantic versioning can be too extreme. At the moment I am constantly breaking things in a non-compatible way, but I don't want to end up with opc-1523.0.0. I am not decided yet on this, as the trajectory of this project is still not quite clear. For now, the version is based on vibes: Does it feel like a significant change? Minor version update. Is it only a small fix? Revision update. Just a typo or similar? No change.

Goals for Version 1.0

Here is a list of goals that I want to implement before opc moves on to version 1.0. All things in this list are not finished and perhaps the best entry points for development support. Some of these things are also not particularly hard to do, they just require some work.

  • searchable HTML documentation
  • functioning digital place&route
  • up-to-date documentation
  • hand-holding tutorial with mature examples so that anyone can start to use opc
  • GUI (browser-based) configuration tool for cells
  • a collection of robust and mature cells with medium complexity:
    • ring oscillator
    • current mirror
    • OP-AMPs
    • LC oscillator
    • LDO
    • bandgap
    • digital cells (make stdcells.sh/stdcells.lua in wip work)
  • skeleton generation from netlist + configuration file
  • solid tech file assistant
  • technology files for: x skywater130 x IHP SG13G2 x freePDK45 x freePDK15 x open GF180 or generic 180 nm x generic finfet technology (if freePDK15 does not include that)
  • improve handling of error messages deep in a call stack
  • proper and thorough testing
  • pcell module implementation mostly in C, lua only as an interface
  • properly support pcells written in C (requires pcell module C implementation)
  • integer-based calculations and proper grid support (functions for 'breaking' grid in a defined way)
  • set up a nice-looking website for the project with
    • official documentation and guides
    • mailing list/forum/something else?
    • download
    • integrated layout viewer (a simplified version of the current browser-based viewer) with cell list

Important Types

There are a few types that are used throughout the project. Some are data structures (such as struct vector), some are structures representing layout elements.

  • vector (src/vector.c) The most important data structure, represents dynamic arrays for pointers. As the individual elements are allocated again, there is another level of indirection. Continuous arrays (such as int* or char*) are not used much, because they are often not needed. Where they are, thin macro wrappers to realloc offer convenience to manipulate these arrays. For now, this works well and does not seem to be a problem performance-wise. This means that a struct vector* can not be used to directly store primitive types. The typical use case of a vector looks like this:

     struct vector* vector = vector_create(8, foo_destroy); // vector_create takes a number for the initial capacitance and a destructor
                                                            // the destructor must have the signature void (*destructor) (void*)
     vector_append(vector, foo_create());
     vector_append(vector, foo_create());
     vector_append(vector, foo_create());
     for(size_t i = 0; i < vector_size(vector); ++i)
     {
         struct foo* foo = vector_get(vector, i);
         foo_do_something(foo);
     }
     vector_destroy(vector);
    

    The type genericity of the vector comes from storing only void pointers. This means that there are no type checks through the compiler (it is C after all).

  • object (src/object.c): An object represents a collection of layout primitives (such as shapes or ports) and is the essential building block for integrated layouts. In standard terminology an object is a cell, part of a cell hierarchy. As such objects can store shapes, ports, placement boundaries and anchors, references to other cells (to build hierarchies) and know about nets. Objects come in two flavors: full and proxy objects, implemented as a union. Full objects actually contain and own (memory-wise) the stores layout primitives. Proxy objects are lightweight pointers to full objects, which can be stored in full objects as cell references. These references are called children.

    Through this dualality of objects, most functions check the type of the object first. Many functions make sense for both full and proxy objects, some only for one or the other. For instance, both full objects and proxy objects can be rotated, translated etc., but one can not inherit anchors from a proxy object.

Lua Integration and Modules

The project includes a lua interpreter in source, which is almost identical to the official 5.4.4 source, with tiny changes. The functionality of openPCells is mainly implemented in C, lua is mostly used as a scripting API access. This is done for performance reasons, some less critical API functions are also implemented in lua. These lua modules can be found in src/modules. They are added to the binary by being compiled to bytecode which then is inserted into the main binary as char array.

Style Guide

Follow the [mention guide] in general. A few particularities are listed here:

  • curly braces for functions, conditionals etc. belong on their own line:

    if(condition) {

    } else {

    }

  • curly braces for initializers, structs, enums etc. belong on the same line as the preceeding code:

    struct foo {

    }; enum bar {

    }; int array[] = { 1, 2, 3 }; // this example could also be on one line

  • empty lines must be fully empty, they must match this expression: ^$ (rationale: I develop with vim and this allows for proper paragraph jumping with '{' and '})

  • similarily, white space at the end of the line is highly frowned upon. It shows up red in git diffs.

  • there is no hard limit on the line length, make it reasonable. Do not break at 80, that is too short.

  • prepend the namespace of a module:

    // in module foo.c int foo_create(void);

  • static functions don't prepend the module name and start with an underscore

  • Yes, I'm aware that identifiers starting with an underscore are reserved. I believe it is unlikely that this will be an issue at some point, but I will change this in the future. I'm still in search of a solution that allows easy spotting of private identifiers without clutter.

  • In geneneral (a few expections exist) structs and enums are not typedef'd. Use the full qualifier.