User Guide
Basic Operation
CharLib runs analog simulation of the configured cells to determine their electrical properties. The overal flow is shown in the figure below.
To run characterization, you must provide:
SPICE netlists of the cells to be characterized (ideally with extracted parasistics)
Analog transistor models from your PDK
A YAML configuration file
Typically the first two items are provided by your foundry as part of the PDK. The third item tells CharLib how to process the SPICE netlists and transistor models. Using CharLib basically boils down to constructing a YAML file detailing your cells and characterization conditions.
Note
See YAML configuration examples for more information on configuring CharLib.
We have also created a video guide that walks through the process of installing CharLib, creating a configuration file, and characterizing a cell. You can watch that video here on YouTube.
Running CharLib
To interact with CharLib’s command line interface, execute:
charlib <command>
CharLib supports the following commands:
run: characterize cells using an existing configuration filecompare: (experimental) compare a liberty file against a benchmark “golden” liberty filegenerate_functions: (experimental) generate test vectors for a particular function
Note
Commands marked with (experimental) may or may not be functional in any given release of CharLib.
Usage
charlib --help
will display lots of useful information. You can also run charlib <command> --help to show
usage information for a particular command.
Running characterization
To characterize a standard cell library with CharLib, execute:
charlib run <path_to_library_config>
<path_to_library_config> may be either a path directly to the YAML configuration file, or to
a directory containing a configuration file. If <path_to_library_config> is a directory,
CharLib recursively searches the specified directory for a YAML file containing a valid cell
library configuration. Once a configuration is identified, CharLib characterizes each cell included
in the configuration file.
Optional arguments for charlib run include:
--output <output>: place characterization results in the specified<output>directory.--jobs <jobs>: specify the maximum number of threads to use for characterization.--filter <filters>: only characterize cells whose names match the regex pattern given in<filters>.
More information about optional arguments can be found by running charlib run --help.
YAML configuration examples
The examples in this section can be run after installing CharLib and downloading the corresponding standard cells.
To download the OSU350 cells and models:
1#! /usr/bin/env bash
2
3export OSU035_COMMIT="b36db529c2dff117e1fbead561bf792ec866e1cb"
4mkdir -p osu350/spice
5mkdir -p osu350/models
6curl -fsSL --retry 3 https://raw.githubusercontent.com/stineje/MOSIS_SCMOS/$OSU035_COMMIT/latest/cadence/lib/ami035/signalstorm/osu035_stdcells.sp > osu350/spice/osu035_stdcells.sp
7curl -fsSL --retry 3 https://raw.githubusercontent.com/stineje/MOSIS_SCMOS/$OSU035_COMMIT/latest/cadence/lib/ami035/lib/ami035.m > osu350/models/ami035.m
8curl -fsSL --retry 3 https://raw.githubusercontent.com/stineje/CharLib/refs/heads/main/test/pdks/osu350/fix_hspice_models.patch > osu350/fix_hspice_models.patch
9patch -s osu350/models/ami035.m osu350/fix_hspice_models.patch
To download the gf180mcu OSU 9t cells and models:
1#! /usr/bin/env bash
2
3export GF180MCU_OSU_SC_COMMIT="8a2f58f283a2eaa725314c9e1b8b7d1d343f23a3"
4export GF180MCU_FD_PR_COMMIT="4adc3a4704fbe722bdf2145341a409b6419788fd"
5mkdir -p gf180mcu/spice
6mkdir -p gf180mcu/models
7curl -fsSL --retry 3 https://raw.githubusercontent.com/stineje/globalfoundries-pdk-libs-gf180mcu_osu_sc/$GF180MCU_OSU_SC_COMMIT/gf180mcu_osu_sc_gp9t3v3/spice/gf180mcu_osu_sc_gp9t3v3.spice > gf180mcu/spice/osu_sc_9t.spice
8curl -fsSL --retry 3 https://raw.githubusercontent.com/fossi-foundation/globalfoundries-pdk-libs-gf180mcu_fd_pr/$GF180MCU_FD_PR_COMMIT/models/ngspice/design.spice > gf180mcu/models/design.spice
9curl -fsSL --retry 3 https://raw.githubusercontent.com/fossi-foundation/globalfoundries-pdk-libs-gf180mcu_fd_pr/$GF180MCU_FD_PR_COMMIT/models/ngspice/sm141064.spice > gf180mcu/models/sm141064.spice
Example 1: OSU350 INVX1 Characterization
The example below is a configuration file for characterization of a single INVX1 inverter cell.
When run with this configuration file, CharLib will measure the properties of the inverter and
produce a liberty file called “osu350_inverter_example.lib”.
1settings:
2 lib_name: osu350_inverter_example
3 units:
4 # Specify all units for clarity, even though only resistance differs from the default
5 time: ns
6 voltage: V
7 current: uA
8 pulling_resistance: kOhm
9 leakage_power: nW
10 capacitive_load: pF
11 energy: fJ
12 named_nodes:
13 primary_ground: # Tell CharLib the ground node name is different from the default "VSS"
14 name: GND
15cells:
16 INVX1:
17 netlist: osu350/spice/osu035_stdcells.sp
18 models: [osu350/models/ami035.m]
19 area: 128
20 inputs: [A]
21 outputs: ['Y'] # Must be in quotes because YAML interprets Y as boolean True
22 functions: [Y=!A]
23 data_slews: [0.015, 0.04, 0.08, 0.2, 0.4]
24 loads: [0.06, 0.18, 0.42, 0.6, 1.2]
You can run this configuration by navigating to CharLib’s test/examples directory and executing
the following commands.
./get_osu350.sh # Download OSU350 cell spice & transistor models
charlib run ex_osu350_invx1.yaml
Example 2: Characterizing Multiple OSU350 Combinational Cells
The YAML below configures CharLib to perform characterization of full adder (FAX1) and half
adder (HAX1) cells. Notice the following changes from example 1:
Several cell parameters are moved into
settings.cell_defaultsto avoid repeating them for each cell.The
inputsandoutputskeys are omitted from cell configurations. CharLib infers these from the cells’ functions instead.
1settings:
2 lib_name: osu350_adder_example
3 units:
4 pulling_resistance: kOhm # This is the only unit that differs from the defaults
5 named_nodes:
6 primary_ground:
7 name: GND
8 cell_defaults: # The key-value pairs below get copied to all cell configurations
9 netlist: osu350/spice/osu035_stdcells.sp
10 models: [osu350/models/ami035.m]
11 data_slews: [0.015, 0.04, 0.08, 0.2, 0.4]
12 loads: [0.06, 0.18, 0.42, 0.6, 1.2]
13cells:
14 FAX1:
15 area: 480
16 functions:
17 - YC=(A&B)|(C&(A^B))
18 - YS=A^B^C
19 HAX1:
20 area: 320
21 functions:
22 - YC=A&B
23 - YS=A^B
24 loads: [0.012, 0.036, 0.06] # This overrides the value from cell_defaults
You can run this configuration by navigating to CharLib’s test/examples directory and executing
the following commands.
./get_osu350.sh # Download OSU350 cell spice & transistor models
charlib run ex_osu350_adders.yaml
Example 3: YAML-Free OSU350 DFFSR Characterization
CharLib may be used as a Python module without creating a separate YAML configuration file. The example below shows the characterization of an OSU350 sequential cell using this method. Note that this example will take quite a bit longer to run than the combinational examples above, as sequential cell characterization is much more complex than combinational.
Note
Using a CharLib Characterizer object directly (as shown below) bypasses all of the
validation checks built into CharLib’s command-line interface. While this method of using
CharLib can grant much finer control over the characterization process, we recommend the use of
YAML configuration files to help avoid configuration errors.
1from charlib.characterizer.characterizer import Characterizer
2
3if __name__ == "__main__":
4 characterizer = Characterizer(
5 lib_name='osu350_dffsr_example',
6 units={'pulling_resistance': 'kOhm'},
7 named_nodes={'primary_ground': {'name': 'GND'}})
8 characterizer.add_cell('DFFSR', {
9 'netlist': 'osu350/spice/osu035_stdcells.sp',
10 'models': ['osu350/models/ami035.m'],
11 'area': 704,
12 'clock': 'posedge CLK',
13 'set': 'negedge S',
14 'reset': 'negedge R',
15 'state': ['DS0000 = Q'],
16 'functions': ['Q <= D'],
17 'data_slews': [0.06, 0.18, 0.42, 0.6, 1.2],
18 'loads': [0.015, 0.04, 0.08, 0.2, 0.4],
19 'clock_slews': [0.06, 0.3, 0.6],
20 'metastability_constraint_search_tolerance': 0.01,
21 'metastability_constraint_search_timestep': 0.005,
22 'metastability_constraint_load': 0.24,
23 'metastability_constraint_sweep_samples': 40})
24 liberty = characterizer.characterize()
25 print(liberty)
Example 4: Characterizing Multiple gf180mcu Cells
The example below is a configuration file for characterization of several cells from the OSU 9-track standard cell library. This configuration includes a mix of combinational and sequential cells.
1settings:
2 lib_name: gf180mcu_osu_sc_9t_example
3 cell_defaults:
4 netlist: gf180mcu/spice/osu_sc_9t.spice
5 models:
6 - gf180mcu/models/sm141064.spice typical
7 - gf180mcu/models/design.spice
8 data_slews: [0.0706, 0.1903, 0.5123, 1.3794, 3.7140]
9 loads: [0.0013, 0.0048, 0.0172, 0.0616, 0.2206, 0.7901]
10 clock_slews: [0.0699991, 2.64574]
11 metastability_constraint_load: 0.24
12cells:
13 gf180mcu_osu_sc_gp9t3v3__aoi21_1:
14 inputs: [A0, A1, B]
15 outputs: ['Y']
16 functions: [Y=(!A0&!B) | (!A1&!B)]
17 gf180mcu_osu_sc_gp9t3v3__aoi22_1:
18 inputs: [A0, A1, B0, B1]
19 outputs: ['Y']
20 functions: [Y=(!A0&!B0) | (!A0&!B1) | (!A1&!B0) | (!A1&!B1)]
21 gf180mcu_osu_sc_gp9t3v3__buf_1:
22 inputs: [A]
23 outputs: ['Y']
24 functions: [Y=A]
25 gf180mcu_osu_sc_gp9t3v3__dff_1:
26 functions:
27 - Q <= D
28 - QN <= !D
29 clock: posedge clk
30 state:
31 - IQ = Q
32 - IQN = QN
33 pairs: [Q QN]
34 # Limit DFFS to 1 slew/load/clk_slew corner, as this takes a long time
35 data_slews: [0.0706]
36 loads: [0.2206]
37 clock_slews: [0.0699991]
38 gf180mcu_osu_sc_gp9t3v3__mux2_1:
39 inputs: [A, B, SEL]
40 outputs: ['Y']
41 functions: [Y=(A&!SEL) | (B&SEL)]
42 gf180mcu_osu_sc_gp9t3v3__nand2_1:
43 inputs: [A, B]
44 outputs: ['Y']
45 functions: [Y=!(A&B)]
46 gf180mcu_osu_sc_gp9t3v3__nor2_1:
47 inputs: [A, B]
48 outputs: ['Y']
49 functions: [Y=!(A|B)]
50 gf180mcu_osu_sc_gp9t3v3__oai21_1:
51 inputs: [A0, A1, B]
52 outputs: ['Y']
53 functions: [Y=(!A0&!A1) | (!B)]
54 gf180mcu_osu_sc_gp9t3v3__oai22_1:
55 inputs: [A0, A1, B0, B1]
56 outputs: ['Y']
57 functions: [Y=(!A0&!A1) | (!B0&!B1)]
58 gf180mcu_osu_sc_gp9t3v3__oai31_1:
59 inputs: [A0, A1, A2, B]
60 outputs: ['Y']
61 functions: [Y=(!A0&!A1&!A2)|(!B)]
62 gf180mcu_osu_sc_gp9t3v3__or2_1:
63 inputs: [A, B]
64 outputs: ['Y']
65 functions: [Y=A|B]
66 gf180mcu_osu_sc_gp9t3v3__xnor2_1:
67 inputs: [A, B]
68 outputs: ['Y']
69 functions: [Y=!(A^B)]
70 gf180mcu_osu_sc_gp9t3v3__xor2_1:
71 inputs: [A, B]
72 outputs: ['Y']
73 functions: [Y=A^B]