├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── bag ├── LICENSE ├── __init__.py ├── concurrent │ ├── LICENSE │ ├── __init__.py │ └── core.py ├── core.py ├── data │ ├── LICENSE │ ├── __init__.py │ ├── core.py │ ├── dc.py │ ├── digital.py │ ├── lti.py │ ├── ltv.py │ ├── mos.py │ └── plot.py ├── design │ ├── LICENSE │ ├── __init__.py │ └── module.py ├── interface │ ├── LICENSE │ ├── __init__.py │ ├── base.py │ ├── database.py │ ├── ocean.py │ ├── server.py │ ├── simulator.py │ ├── skill.py │ ├── templates │ │ ├── LICENSE │ │ ├── Module.pyi │ │ ├── PrimModule.pyi │ │ ├── calibreview_setup.txt │ │ ├── load_results.ocn │ │ └── run_simulation.ocn │ └── zmqwrapper.py ├── io │ ├── LICENSE │ ├── __init__.py │ ├── common.py │ ├── file.py │ ├── gui.py │ ├── process.py │ ├── sim_data.py │ └── template.py ├── layout │ ├── LICENSE │ ├── __init__.py │ ├── core.py │ ├── digital.py │ ├── objects.py │ ├── routing │ │ ├── LICENSE │ │ ├── __init__.py │ │ ├── base.py │ │ ├── fill.py │ │ └── grid.py │ ├── tech.py │ ├── template.py │ └── util.py ├── math │ ├── LICENSE │ ├── __init__.py │ ├── dfun.py │ └── interpolate.py ├── mdao │ ├── LICENSE │ ├── __init__.py │ ├── components.py │ └── core.py ├── simulation │ ├── LICENSE │ ├── __init__.py │ ├── core.py │ └── core_v2.py ├── tech │ ├── LICENSE │ ├── __init__.py │ ├── core.py │ └── mos.py ├── util │ ├── LICENSE │ ├── __init__.py │ ├── cache.py │ ├── immutable.py │ ├── interval.py │ ├── parse.py │ └── search.py ├── verification │ ├── LICENSE │ ├── __init__.py │ ├── base.py │ ├── calibre.py │ ├── icv.py │ ├── pvs.py │ ├── templates │ │ ├── LICENSE │ │ ├── layout_export_config.txt │ │ └── si_env.txt │ └── virtuoso.py └── virtuoso.py ├── docs ├── .gitignore ├── LICENSE ├── Makefile ├── README ├── refresh_api.sh └── source │ ├── LICENSE │ ├── api │ ├── LICENSE │ ├── bag.data.rst │ ├── bag.design.rst │ ├── bag.interface.rst │ ├── bag.io.rst │ ├── bag.layout.routing.rst │ ├── bag.layout.rst │ ├── bag.math.rst │ ├── bag.mdao.rst │ ├── bag.rst │ ├── bag.tech.rst │ ├── bag.util.rst │ ├── bag.verification.rst │ └── modules.rst │ ├── conf.py │ ├── developer │ ├── LICENSE │ └── developer.rst │ ├── index.rst │ ├── overview │ ├── LICENSE │ ├── design.rst │ ├── figures │ │ ├── bag_flow.png │ │ ├── bag_prim_screenshot.png │ │ ├── gm_schematic.png │ │ └── inv_chain_schematic.png │ ├── overview.rst │ ├── schematic.rst │ └── testbench.rst │ ├── setup │ ├── LICENSE │ ├── bag_config │ │ ├── LICENSE │ │ ├── bag_config.rst │ │ ├── database │ │ │ └── database.rst │ │ ├── misc.rst │ │ ├── simulation │ │ │ └── simulation.rst │ │ └── socket │ │ │ └── socket.rst │ ├── config_summary.rst │ ├── install_python.rst │ ├── new_pdk.rst │ ├── pyoptsparse.rst │ ├── setup.rst │ └── tech_config │ │ ├── LICENSE │ │ ├── layout │ │ └── layout.rst │ │ ├── misc.rst │ │ ├── mos │ │ └── mos.rst │ │ └── tech_config.rst │ └── tutorial │ ├── LICENSE │ ├── figures │ ├── LICENSE │ ├── bag_server_start.png │ ├── bag_sim_server.png │ ├── gm_schematic.png │ ├── gm_testbench.png │ ├── testbench_dut.png │ ├── tran_prop.png │ └── tran_schematic.png │ └── tutorial.rst ├── run_scripts ├── LICENSE ├── clean_cds_lib.py ├── compile_verilog.il ├── gen_cell.py ├── generate_verilog.py ├── meas_cell.py ├── run_bag.sh ├── setup_submodules.py ├── sim_cell.py ├── start_bag.il ├── start_bag.sh ├── start_bag_ICADV12d3.il └── virt_server.sh ├── setup.py └── tests ├── LICENSE ├── __init__.py └── layout ├── LICENSE ├── __init__.py └── routing ├── LICENSE ├── __init__.py └── test_fill.py /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.pyc 3 | .idea 4 | build 5 | dist 6 | bag.egg-info 7 | __pycache__ 8 | *.swp 9 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "cybag_oa"] 2 | path = cybag_oa 3 | url = https://github.com/ucb-art/cybag_oa.git 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Berkeley Analog Generator (BAG) version 2.0 and later. 2 | 3 | BAG 2.0 is a complete rewrite of BAG 1.x (which is in pre-alpha stage and 4 | never released publicly). 5 | 6 | (Very outdated) Documentation and install instructions can be found at 7 | 8 | A tutorial setup is available at 9 | -------------------------------------------------------------------------------- /bag/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /bag/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This is the bag root package. 4 | """ 5 | 6 | import signal 7 | 8 | from . import math 9 | from .math import float_to_si_string, si_string_to_float 10 | from . import interface 11 | from . import design 12 | from . import data 13 | from . import tech 14 | from . import layout 15 | 16 | from .core import BagProject, create_tech_info 17 | 18 | __all__ = ['interface', 'design', 'data', 'math', 'tech', 'layout', 'BagProject', 19 | 'float_to_si_string', 'si_string_to_float', 'create_tech_info'] 20 | 21 | # make sure that SIGINT will always be catched by python. 22 | signal.signal(signal.SIGINT, signal.default_int_handler) 23 | -------------------------------------------------------------------------------- /bag/concurrent/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /bag/concurrent/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This package define helper classes used to perform concurrent operations. 4 | """ -------------------------------------------------------------------------------- /bag/data/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /bag/data/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This package defines methods and classes useful for data post-processing. 4 | """ 5 | 6 | # compatibility import. 7 | from ..io import load_sim_results, save_sim_results, load_sim_file 8 | from .core import Waveform 9 | 10 | __all__ = ['load_sim_results', 'save_sim_results', 'load_sim_file', 11 | 'Waveform', ] 12 | -------------------------------------------------------------------------------- /bag/data/mos.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This module defines classes for computing DC operating point. 4 | """ 5 | 6 | from typing import Dict 7 | 8 | import numpy as np 9 | 10 | 11 | def mos_y_to_ss(sim_data, char_freq, fg, ibias, cfit_method='average'): 12 | # type: (Dict[str, np.ndarray], float, int, np.ndarray, str) -> Dict[str, np.ndarray] 13 | """Convert transistor Y parameters to small-signal parameters. 14 | 15 | This function computes MOSFET small signal parameters from 3-port 16 | Y parameter measurements done on gate, drain and source, with body 17 | bias fixed. This functions fits the Y parameter to a capcitor-only 18 | small signal model using least-mean-square error. 19 | 20 | Parameters 21 | ---------- 22 | sim_data : Dict[str, np.ndarray] 23 | A dictionary of Y parameters values stored as complex numpy arrays. 24 | char_freq : float 25 | the frequency Y parameters are measured at. 26 | fg : int 27 | number of transistor fingers used for the Y parameter measurement. 28 | ibias : np.ndarray 29 | the DC bias current of the transistor. Always positive. 30 | cfit_method : str 31 | method used to extract capacitance from Y parameters. Currently 32 | supports 'average' or 'worst' 33 | 34 | Returns 35 | ------- 36 | ss_dict : Dict[str, np.ndarray] 37 | A dictionary of small signal parameter values stored as numpy 38 | arrays. These values are normalized to 1-finger transistor. 39 | """ 40 | w = 2 * np.pi * char_freq 41 | 42 | gm = (sim_data['y21'].real - sim_data['y31'].real) / 2.0 # type: np.ndarray 43 | gds = (sim_data['y22'].real - sim_data['y32'].real) / 2.0 # type: np.ndarray 44 | gb = (sim_data['y33'].real - sim_data['y23'].real) / 2.0 - gm - gds # type: np.ndarray 45 | 46 | cgd12 = -sim_data['y12'].imag / w 47 | cgd21 = -sim_data['y21'].imag / w 48 | cgs13 = -sim_data['y13'].imag / w 49 | cgs31 = -sim_data['y31'].imag / w 50 | cds23 = -sim_data['y23'].imag / w 51 | cds32 = -sim_data['y32'].imag / w 52 | cgg = sim_data['y11'].imag / w 53 | cdd = sim_data['y22'].imag / w 54 | css = sim_data['y33'].imag / w 55 | 56 | if cfit_method == 'average': 57 | cgd = (cgd12 + cgd21) / 2 # type: np.ndarray 58 | cgs = (cgs13 + cgs31) / 2 # type: np.ndarray 59 | cds = (cds23 + cds32) / 2 # type: np.ndarray 60 | elif cfit_method == 'worst': 61 | cgd = np.maximum(cgd12, cgd21) 62 | cgs = np.maximum(cgs13, cgs31) 63 | cds = np.maximum(cds23, cds32) 64 | else: 65 | raise ValueError('Unknown cfit_method = %s' % cfit_method) 66 | 67 | cgb = cgg - cgd - cgs # type: np.ndarray 68 | cdb = cdd - cds - cgd # type: np.ndarray 69 | csb = css - cgs - cds # type: np.ndarray 70 | 71 | ibias = ibias / fg 72 | gm = gm / fg 73 | gds = gds / fg 74 | gb = gb / fg 75 | cgd = cgd / fg 76 | cgs = cgs / fg 77 | cds = cds / fg 78 | cgb = cgb / fg 79 | cdb = cdb / fg 80 | csb = csb / fg 81 | 82 | return dict( 83 | ibias=ibias, 84 | gm=gm, 85 | gds=gds, 86 | gb=gb, 87 | cgd=cgd, 88 | cgs=cgs, 89 | cds=cds, 90 | cgb=cgb, 91 | cdb=cdb, 92 | csb=csb, 93 | ) 94 | -------------------------------------------------------------------------------- /bag/design/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /bag/design/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This package defines design template classes. 4 | """ 5 | 6 | from .module import Module, ModuleDB, SchInstance, MosModuleBase, ResPhysicalModuleBase, ResMetalModule 7 | 8 | __all__ = ['Module', 'ModuleDB', 'SchInstance', 'MosModuleBase', 'ResPhysicalModuleBase', 'ResMetalModule'] 9 | -------------------------------------------------------------------------------- /bag/interface/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /bag/interface/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This packages defines classes to interface with CAD database and circuit simulators. 4 | """ 5 | 6 | from .server import SkillServer 7 | from .zmqwrapper import ZMQRouter, ZMQDealer 8 | 9 | __all__ = ['SkillServer', 'ZMQRouter', 'ZMQDealer', ] 10 | -------------------------------------------------------------------------------- /bag/interface/base.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This module defines the base of all interface classes. 4 | """ 5 | 6 | from typing import Dict, Any 7 | 8 | from ..io.template import new_template_env 9 | 10 | 11 | class InterfaceBase: 12 | """The base class of all interfaces. 13 | 14 | Provides various helper methods common to all interfaces. 15 | """ 16 | def __init__(self): 17 | self._tmp_env = new_template_env('bag.interface', 'templates') 18 | 19 | def render_file_template(self, temp_name, params): 20 | # type: (str, Dict[str, Any]) -> str 21 | """Returns the rendered content from the given template file.""" 22 | template = self._tmp_env.get_template(temp_name) 23 | return template.render(**params) 24 | -------------------------------------------------------------------------------- /bag/interface/ocean.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This module implements bag's interaction with an ocean simulator. 4 | """ 5 | 6 | from typing import TYPE_CHECKING, Dict, Any, Optional 7 | 8 | import os 9 | 10 | import bag.io 11 | from .simulator import SimProcessManager 12 | 13 | if TYPE_CHECKING: 14 | from .simulator import ProcInfo 15 | 16 | 17 | class OceanInterface(SimProcessManager): 18 | """This class handles interaction with Ocean simulators. 19 | 20 | Parameters 21 | ---------- 22 | tmp_dir : str 23 | temporary file directory for SimAccess. 24 | sim_config : Dict[str, Any] 25 | the simulation configuration dictionary. 26 | """ 27 | 28 | def __init__(self, tmp_dir, sim_config): 29 | # type: (str, Dict[str, Any]) -> None 30 | """Initialize a new SkillInterface object. 31 | """ 32 | SimProcessManager.__init__(self, tmp_dir, sim_config) 33 | 34 | def format_parameter_value(self, param_config, precision): 35 | # type: (Dict[str, Any], int) -> str 36 | """Format the given parameter value as a string. 37 | 38 | To support both single value parameter and parameter sweeps, each parameter value is 39 | represented as a string instead of simple floats. This method will cast a parameter 40 | configuration (which can either be a single value or a sweep) to a 41 | simulator-specific string. 42 | 43 | Parameters 44 | ---------- 45 | param_config: Dict[str, Any] 46 | a dictionary that describes this parameter value. 47 | 48 | 4 formats are supported. This is best explained by example. 49 | 50 | single value: 51 | dict(type='single', value=1.0) 52 | 53 | sweep a given list of values: 54 | dict(type='list', values=[1.0, 2.0, 3.0]) 55 | 56 | linear sweep with inclusive start, inclusive stop, and step size: 57 | dict(type='linstep', start=1.0, stop=3.0, step=1.0) 58 | 59 | logarithmic sweep with given number of points per decade: 60 | dict(type='decade', start=1.0, stop=10.0, num=10) 61 | 62 | precision : int 63 | the parameter value precision. 64 | 65 | Returns 66 | ------- 67 | param_str : str 68 | a string representation of param_config 69 | """ 70 | 71 | fmt = '%.{}e'.format(precision) 72 | swp_type = param_config['type'] 73 | if swp_type == 'single': 74 | return fmt % param_config['value'] 75 | elif swp_type == 'list': 76 | return ' '.join((fmt % val for val in param_config['values'])) 77 | elif swp_type == 'linstep': 78 | syntax = '{From/To}Linear:%s:%s:%s{From/To}' % (fmt, fmt, fmt) 79 | return syntax % (param_config['start'], param_config['step'], param_config['stop']) 80 | elif swp_type == 'decade': 81 | syntax = '{From/To}Decade:%s:%s:%s{From/To}' % (fmt, '%d', fmt) 82 | return syntax % (param_config['start'], param_config['num'], param_config['stop']) 83 | else: 84 | raise Exception('Unsupported param_config: %s' % param_config) 85 | 86 | def _get_ocean_info(self, save_dir, script_fname, log_fname): 87 | """Private helper function that launches ocean process.""" 88 | # get the simulation command. 89 | sim_kwargs = self.sim_config['kwargs'] 90 | ocn_cmd = sim_kwargs['command'] 91 | env = sim_kwargs.get('env', None) 92 | cwd = sim_kwargs.get('cwd', None) 93 | sim_cmd = [ocn_cmd, '-nograph', '-replay', script_fname, '-log', log_fname] 94 | 95 | if cwd is None: 96 | # set working directory to BAG_WORK_DIR if None 97 | cwd = os.environ['BAG_WORK_DIR'] 98 | 99 | # create empty log file to make sure it exists. 100 | return sim_cmd, log_fname, env, cwd, save_dir 101 | 102 | def setup_sim_process(self, lib, cell, outputs, precision, sim_tag): 103 | # type: (str, str, Dict[str, str], int, Optional[str]) -> ProcInfo 104 | 105 | sim_tag = sim_tag or 'BagSim' 106 | job_options = self.sim_config['job_options'] 107 | init_file = self.sim_config['init_file'] 108 | view = self.sim_config['view'] 109 | state = self.sim_config['state'] 110 | 111 | # format job options as skill list of string 112 | job_opt_str = "'( " 113 | for key, val in job_options.items(): 114 | job_opt_str += '"%s" "%s" ' % (key, val) 115 | job_opt_str += " )" 116 | 117 | # create temporary save directory and log/script names 118 | save_dir = bag.io.make_temp_dir(prefix='%s_data' % sim_tag, parent_dir=self.tmp_dir) 119 | log_fname = os.path.join(save_dir, 'ocn_output.log') 120 | script_fname = os.path.join(save_dir, 'run.ocn') 121 | 122 | # setup ocean simulation script 123 | script = self.render_file_template('run_simulation.ocn', 124 | dict( 125 | lib=lib, 126 | cell=cell, 127 | view=view, 128 | state=state, 129 | init_file=init_file, 130 | save_dir=save_dir, 131 | precision=precision, 132 | sim_tag=sim_tag, 133 | outputs=outputs, 134 | job_opt_str=job_opt_str, 135 | )) 136 | bag.io.write_file(script_fname, script) 137 | 138 | return self._get_ocean_info(save_dir, script_fname, log_fname) 139 | 140 | def setup_load_process(self, lib, cell, hist_name, outputs, precision): 141 | # type: (str, str, str, Dict[str, str], int) -> ProcInfo 142 | 143 | init_file = self.sim_config['init_file'] 144 | view = self.sim_config['view'] 145 | 146 | # create temporary save directory and log/script names 147 | save_dir = bag.io.make_temp_dir(prefix='%s_data' % hist_name, parent_dir=self.tmp_dir) 148 | log_fname = os.path.join(save_dir, 'ocn_output.log') 149 | script_fname = os.path.join(save_dir, 'run.ocn') 150 | 151 | # setup ocean load script 152 | script = self.render_file_template('load_results.ocn', 153 | dict( 154 | lib=lib, 155 | cell=cell, 156 | view=view, 157 | init_file=init_file, 158 | save_dir=save_dir, 159 | precision=precision, 160 | hist_name=hist_name, 161 | outputs=outputs, 162 | )) 163 | bag.io.write_file(script_fname, script) 164 | 165 | # launch ocean 166 | return self._get_ocean_info(save_dir, script_fname, log_fname) 167 | -------------------------------------------------------------------------------- /bag/interface/simulator.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This module handles high level simulation routines. 4 | 5 | This module defines SimAccess, which provides methods to run simulations 6 | and retrieve results. 7 | """ 8 | 9 | from typing import Dict, Optional, Sequence, Any, Tuple, Union 10 | 11 | import abc 12 | 13 | from ..io import make_temp_dir 14 | from ..concurrent.core import SubProcessManager 15 | from .base import InterfaceBase 16 | 17 | 18 | class SimAccess(InterfaceBase, abc.ABC): 19 | """A class that interacts with a simulator. 20 | 21 | Parameters 22 | ---------- 23 | tmp_dir : str 24 | temporary file directory for SimAccess. 25 | sim_config : Dict[str, Any] 26 | the simulation configuration dictionary. 27 | """ 28 | 29 | def __init__(self, tmp_dir, sim_config): 30 | # type: (str, Dict[str, Any]) -> None 31 | InterfaceBase.__init__(self) 32 | 33 | self.sim_config = sim_config 34 | self.tmp_dir = make_temp_dir('simTmp', parent_dir=tmp_dir) 35 | 36 | @abc.abstractmethod 37 | def format_parameter_value(self, param_config, precision): 38 | # type: (Dict[str, Any], int) -> str 39 | """Format the given parameter value as a string. 40 | 41 | To support both single value parameter and parameter sweeps, each parameter value is represented 42 | as a string instead of simple floats. This method will cast a parameter configuration (which can 43 | either be a single value or a sweep) to a simulator-specific string. 44 | 45 | Parameters 46 | ---------- 47 | param_config: Dict[str, Any] 48 | a dictionary that describes this parameter value. 49 | 50 | 4 formats are supported. This is best explained by example. 51 | 52 | single value: 53 | dict(type='single', value=1.0) 54 | 55 | sweep a given list of values: 56 | dict(type='list', values=[1.0, 2.0, 3.0]) 57 | 58 | linear sweep with inclusive start, inclusive stop, and step size: 59 | dict(type='linstep', start=1.0, stop=3.0, step=1.0) 60 | 61 | logarithmic sweep with given number of points per decade: 62 | dict(type='decade', start=1.0, stop=10.0, num=10) 63 | 64 | precision : int 65 | the parameter value precision. 66 | 67 | Returns 68 | ------- 69 | param_str : str 70 | a string representation of param_config 71 | """ 72 | return "" 73 | 74 | @abc.abstractmethod 75 | async def async_run_simulation(self, tb_lib, tb_cell, outputs, precision=6, sim_tag=None): 76 | # type: (str, str, Dict[str, str], int, Optional[str]) -> str 77 | """A coroutine for simulation a testbench. 78 | 79 | Parameters 80 | ---------- 81 | tb_lib : str 82 | testbench library name. 83 | tb_cell : str 84 | testbench cell name. 85 | outputs : Dict[str, str] 86 | the variable-to-expression dictionary. 87 | precision : int 88 | precision of floating point results. 89 | sim_tag : Optional[str] 90 | a descriptive tag describing this simulation run. 91 | 92 | Returns 93 | ------- 94 | value : str 95 | the save directory path. 96 | """ 97 | pass 98 | 99 | @abc.abstractmethod 100 | async def async_load_results(self, lib, cell, hist_name, outputs, precision=6): 101 | # type: (str, str, str, Dict[str, str], int) -> str 102 | """A coroutine for loading simulation results. 103 | 104 | Parameters 105 | ---------- 106 | lib : str 107 | testbench library name. 108 | cell : str 109 | testbench cell name. 110 | hist_name : str 111 | simulation history name. 112 | outputs : Dict[str, str] 113 | the variable-to-expression dictionary. 114 | precision : int 115 | precision of floating point results. 116 | 117 | Returns 118 | ------- 119 | value : str 120 | the save directory path. 121 | """ 122 | pass 123 | 124 | 125 | ProcInfo = Tuple[Union[str, Sequence[str]], str, Optional[Dict[str, str]], Optional[str], str] 126 | 127 | 128 | class SimProcessManager(SimAccess, metaclass=abc.ABCMeta): 129 | """An implementation of :class:`SimAccess` using :class:`SubProcessManager`. 130 | 131 | Parameters 132 | ---------- 133 | tmp_dir : str 134 | temporary file directory for SimAccess. 135 | sim_config : Dict[str, Any] 136 | the simulation configuration dictionary. 137 | """ 138 | 139 | def __init__(self, tmp_dir, sim_config): 140 | # type: (str, Dict[str, Any]) -> None 141 | SimAccess.__init__(self, tmp_dir, sim_config) 142 | cancel_timeout = sim_config.get('cancel_timeout_ms', None) 143 | if cancel_timeout is not None: 144 | cancel_timeout /= 1e3 145 | self._manager = SubProcessManager(max_workers=sim_config.get('max_workers', None), 146 | cancel_timeout=cancel_timeout) 147 | 148 | @abc.abstractmethod 149 | def setup_sim_process(self, lib, cell, outputs, precision, sim_tag): 150 | # type: (str, str, Dict[str, str], int, Optional[str]) -> ProcInfo 151 | """This method performs any setup necessary to configure a simulation process. 152 | 153 | Parameters 154 | ---------- 155 | lib : str 156 | testbench library name. 157 | cell : str 158 | testbench cell name. 159 | outputs : Dict[str, str] 160 | the variable-to-expression dictionary. 161 | precision : int 162 | precision of floating point results. 163 | sim_tag : Optional[str] 164 | a descriptive tag describing this simulation run. 165 | 166 | Returns 167 | ------- 168 | args : Union[str, Sequence[str]] 169 | command to run, as string or list of string arguments. 170 | log : str 171 | log file name. 172 | env : Optional[Dict[str, str]] 173 | environment variable dictionary. None to inherit from parent. 174 | cwd : Optional[str] 175 | working directory path. None to inherit from parent. 176 | save_dir : str 177 | save directory path. 178 | """ 179 | return '', '', None, None, '' 180 | 181 | @abc.abstractmethod 182 | def setup_load_process(self, lib, cell, hist_name, outputs, precision): 183 | # type: (str, str, str, Dict[str, str], int) -> ProcInfo 184 | """This method performs any setup necessary to configure a result loading process. 185 | 186 | Parameters 187 | ---------- 188 | lib : str 189 | testbench library name. 190 | cell : str 191 | testbench cell name. 192 | hist_name : str 193 | simulation history name. 194 | outputs : Dict[str, str] 195 | the variable-to-expression dictionary. 196 | precision : int 197 | precision of floating point results. 198 | 199 | Returns 200 | ------- 201 | args : Union[str, Sequence[str]] 202 | command to run, as string or list of string arguments. 203 | log : str 204 | log file name. 205 | env : Optional[Dict[str, str]] 206 | environment variable dictionary. None to inherit from parent. 207 | cwd : Optional[str] 208 | working directory path. None to inherit from parent. 209 | save_dir : str 210 | save directory path. 211 | """ 212 | return '', '', None, None, '' 213 | 214 | async def async_run_simulation(self, tb_lib: str, tb_cell: str, 215 | outputs: Dict[str, str], 216 | precision: int = 6, 217 | sim_tag: Optional[str] = None) -> str: 218 | args, log, env, cwd, save_dir = self.setup_sim_process(tb_lib, tb_cell, outputs, precision, 219 | sim_tag) 220 | 221 | await self._manager.async_new_subprocess(args, log, env=env, cwd=cwd) 222 | return save_dir 223 | 224 | async def async_load_results(self, lib: str, cell: str, hist_name: str, 225 | outputs: Dict[str, str], 226 | precision: int = 6) -> str: 227 | args, log, env, cwd, save_dir = self.setup_load_process(lib, cell, hist_name, outputs, 228 | precision) 229 | 230 | await self._manager.async_new_subprocess(args, log, env=env, cwd=cwd) 231 | return save_dir 232 | -------------------------------------------------------------------------------- /bag/interface/templates/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /bag/interface/templates/Module.pyi: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from typing import Dict 4 | 5 | import os 6 | import pkg_resources 7 | 8 | from bag.design.module import Module 9 | 10 | 11 | # noinspection PyPep8Naming 12 | class {{ lib_name }}__{{ cell_name }}(Module): 13 | """Module for library {{ lib_name }} cell {{ cell_name }}. 14 | 15 | Fill in high level description here. 16 | """ 17 | yaml_file = pkg_resources.resource_filename(__name__, 18 | os.path.join('netlist_info', 19 | '{{ cell_name }}.yaml')) 20 | 21 | 22 | def __init__(self, database, parent=None, prj=None, **kwargs): 23 | Module.__init__(self, database, self.yaml_file, parent=parent, prj=prj, **kwargs) 24 | 25 | @classmethod 26 | def get_params_info(cls): 27 | # type: () -> Dict[str, str] 28 | """Returns a dictionary from parameter names to descriptions. 29 | 30 | Returns 31 | ------- 32 | param_info : Optional[Dict[str, str]] 33 | dictionary from parameter names to descriptions. 34 | """ 35 | return dict( 36 | ) 37 | 38 | def design(self): 39 | """To be overridden by subclasses to design this module. 40 | 41 | This method should fill in values for all parameters in 42 | self.parameters. To design instances of this module, you can 43 | call their design() method or any other ways you coded. 44 | 45 | To modify schematic structure, call: 46 | 47 | rename_pin() 48 | delete_instance() 49 | replace_instance_master() 50 | reconnect_instance_terminal() 51 | restore_instance() 52 | array_instance() 53 | """ 54 | pass 55 | -------------------------------------------------------------------------------- /bag/interface/templates/PrimModule.pyi: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import os 4 | import pkg_resources 5 | 6 | from bag.design.module import {{ module_name }} 7 | 8 | 9 | # noinspection PyPep8Naming 10 | class {{ lib_name }}__{{ cell_name }}({{ module_name }}): 11 | """design module for {{ lib_name }}__{{ cell_name }}. 12 | """ 13 | 14 | yaml_file = pkg_resources.resource_filename(__name__, 15 | os.path.join('netlist_info', 16 | '{{ cell_name }}.yaml')) 17 | 18 | def __init__(self, database, parent=None, prj=None, **kwargs): 19 | {{ module_name }}.__init__(self, database, self.yaml_file, parent=parent, prj=prj, **kwargs) 20 | -------------------------------------------------------------------------------- /bag/interface/templates/calibreview_setup.txt: -------------------------------------------------------------------------------- 1 | calibre_view_netlist_file : {{ netlist_file }} 2 | output_library : {{ lib_name }} 3 | schematic_library : {{ lib_name }} 4 | cell_name : {{ cell_name }} 5 | cellmap_file : {{ calibre_cellmap }} 6 | calibreview_log_file : ./calview.log 7 | calibreview_name : {{ view_name }} 8 | calibreview_type : schematic 9 | create_terminals : all 10 | preserve_device_case : on 11 | execute_callbacks : off 12 | reset_properties : (m=1) 13 | magnify_devices_by : 1 14 | magnify_parasitics_by : 1 15 | device_placement : arrayed 16 | parasitic_placement : arrayed 17 | show_parasitic_polygons : off 18 | open_calibreview : don't_open 19 | generate_spectre_netlist : off 20 | -------------------------------------------------------------------------------- /bag/interface/templates/load_results.ocn: -------------------------------------------------------------------------------- 1 | lib = "{{ lib }}" 2 | cell = "{{ cell }}" 3 | view = "{{ view }}" 4 | init_file = "{{ init_file }}" 5 | save_dir = "{{ save_dir }}" 6 | precision = {{ precision }} 7 | hist_name = "{{ hist_name }}" 8 | 9 | ; initialize environment variables 10 | when( strlen(init_file) > 0 11 | load(init_file) 12 | ) 13 | 14 | ; save parametric waveform values as a flattened list. 15 | procedure( save_param_wave_values(wave fmt line_fmt fhandle) 16 | let( (vec wave_cls tmp_val) 17 | if( drIsWaveform(wave) then 18 | ; 1D waveform, simply print all values 19 | vec = drGetWaveformYVec(wave) 20 | wave_cls = className(classOf(drGetElem(vec 0))) 21 | if( wave_cls == 'adtComplex then 22 | ; print complex 23 | for( i 0 drVectorLength(vec) - 1 24 | tmp_val = drGetElem(vec i) 25 | if( imag(tmp_val) < 0 then 26 | ; fix for negative imaginary part. 27 | sprintf(line_fmt "%s%sj\n" fmt fmt) 28 | else 29 | sprintf(line_fmt "%s+%sj\n" fmt fmt) 30 | ) 31 | fprintf(fhandle line_fmt real(tmp_val) imag(tmp_val)) 32 | ) 33 | else 34 | ; print real value 35 | for( i 0 drVectorLength(vec) - 1 36 | fprintf(fhandle line_fmt drGetElem(vec i)) 37 | ) 38 | ) 39 | else 40 | ; parametric waveform, recurse 41 | foreach(val sweepValues(wave) 42 | save_param_wave_values(famValue(wave val) fmt line_fmt fhandle) 43 | ) 44 | ) 45 | ) 46 | ) 47 | 48 | 49 | ; define save functions 50 | ; save a waveform to file. 51 | ; the given waveform will be saved to the file "/.data" as a flattened 1D array. 52 | ; the sweep parameter names of this waveform will be saved to the file "/.sweep", 53 | ; and the values of each parameter will be saved to the file "/.info". 54 | ; data_list_struct is a tconc struct of (waveform_name, waveform_data_file_handle) pairs. 55 | procedure( save_waveform(directory var_name wave precision data_list_struct) 56 | let( (fmt line_fmt wave_cls entry data_file sweep_file fhandle 57 | name_list val_list sweep_df iter_wave) 58 | sprintf(fmt "%%.%de" precision) 59 | sprintf(line_fmt "%s\n" fmt) 60 | wave_cls = className(classOf(wave)) 61 | 62 | if( not( entry = assoc( var_name cdar(data_list_struct) ) ) then 63 | ; first time saving this variable 64 | sprintf(data_file "%s/%s.data" directory var_name) 65 | sprintf(sweep_file "%s/%s.sweep" directory var_name) 66 | cond( 67 | ( or( drIsWaveform(wave) drIsParamWave(wave) ) 68 | ; save sweep names 69 | fhandle = outfile( sweep_file "w" ) 70 | name_list = sweepNames(wave) 71 | foreach(swp_name name_list 72 | fprintf(fhandle "%s\n" swp_name) 73 | ) 74 | close(fhandle) 75 | 76 | ; save sweep values 77 | iter_wave = wave 78 | foreach(swp_name name_list 79 | ; save output most sweep values 80 | val_list = sweepValues(iter_wave) 81 | sprintf(sweep_df "%s/%s.info" directory swp_name) 82 | unless( isFile(sweep_df) 83 | fhandle = outfile( sweep_df "w" ) 84 | foreach(val val_list 85 | fprintf(fhandle line_fmt val) 86 | ) 87 | close(fhandle) 88 | ) 89 | ; remove outer sweep 90 | when( drIsParamWave(iter_wave) 91 | iter_wave = famValue(iter_wave car(val_list)) 92 | ) 93 | ) 94 | 95 | fhandle = outfile( data_file "w" ) 96 | ) 97 | ( or( wave_cls == 'flonum wave_cls == 'fixnum wave_cls == 'adtComplex ) 98 | ; scalar data, make empty sweep file 99 | fhandle = outfile( sweep_file "w") 100 | close(fhandle) 101 | fhandle = outfile( data_file "w" ) 102 | ) 103 | ( t 104 | ; unsupported type 105 | error("Unsupported data for output %s: %A\n" var_name wave) 106 | ) 107 | ) 108 | tconc( data_list_struct list(var_name fhandle) ) 109 | else 110 | fhandle = cadr(entry) 111 | ) 112 | 113 | ; append data to file 114 | if( or( drIsWaveform(wave) drIsParamWave(wave) ) then 115 | save_param_wave_values(wave fmt line_fmt fhandle) 116 | else 117 | ; print single point value 118 | if( wave_cls == 'adtComplex then 119 | ; print complex 120 | if( imag(wave) < 0 then 121 | ; fix for negative imaginary part. 122 | sprintf(line_fmt "%s%sj\n" fmt fmt) 123 | else 124 | sprintf(line_fmt "%s+%sj\n" fmt fmt) 125 | ) 126 | fprintf(fhandle line_fmt real(wave) imag(wave)) 127 | else 128 | fprintf(fhandle line_fmt wave) 129 | ) 130 | ) 131 | 't 132 | ) 133 | ) 134 | 135 | ocnSetXLMode() 136 | ocnxlTargetCellView(lib cell view) 137 | 138 | ; load result database 139 | rdb = axlReadHistoryResDB(hist_name) 140 | unless( rdb 141 | error("Cannot find database associated with name %s" hist_name) 142 | ) 143 | point_list = rdb->points() 144 | 145 | sprintf(sweep_fname "%s/sweep.info" save_dir) 146 | sweep_f = outfile( sweep_fname "w" ) 147 | 148 | ; write sweep parameters title 149 | when( point_list 150 | point = car(point_list) 151 | test_list = point->tests() 152 | when( test_list 153 | corner = car(test_list)->cornerName 154 | par_names = setof( name point->params(?corner corner ?sortBy 'name)~>name 155 | and( (name != "corModelSpec") (name != "temperature") ) ) 156 | 157 | fprintf(sweep_f "corner ") 158 | fprintf(sweep_f "%s\n" buildString( par_names " " )) 159 | ) 160 | ) 161 | 162 | ; iterate through each design point and save data. 163 | data_list_struct = tconc(nil 0) 164 | total_points = length(point_list) 165 | cur_idx = 1 166 | foreach(point point_list 167 | printf("*Info* saving process: %d/%d\n" cur_idx total_points) 168 | cur_idx = cur_idx + 1 169 | foreach(test point->tests() 170 | ; write param values to file. 171 | corner = test->cornerName 172 | params = setof(par point->params(?corner corner ?sortBy 'name) 173 | and( (par->name != "corModelSpec") (par->name != "temperature") ) ) 174 | param_vals = mapcar( lambda( (par) par->valueAsString(?digits precision ?notation 'eng) ) params ) 175 | fprintf(sweep_f "%s " corner) 176 | fprintf(sweep_f "%s\n" buildString( param_vals " " )) 177 | 178 | ; open results 179 | openResults(test->resultsDir) 180 | 181 | {% for var, expr in outputs.items() %} 182 | tmp = {{ expr }} 183 | save_waveform( save_dir "{{ var }}" tmp precision data_list_struct ) 184 | {% endfor %} 185 | 186 | ) 187 | ) 188 | 189 | ; close opened files 190 | close(sweep_f) 191 | foreach( entry cdar(data_list_struct) 192 | close(cadr(entry)) 193 | ) 194 | 195 | ocnxlEndXLMode() 196 | 197 | exit() 198 | -------------------------------------------------------------------------------- /bag/interface/templates/run_simulation.ocn: -------------------------------------------------------------------------------- 1 | lib = "{{ lib }}" 2 | cell = "{{ cell }}" 3 | view = "{{ view }}" 4 | state = "{{ state }}" 5 | init_file = "{{ init_file }}" 6 | save_dir = "{{ save_dir }}" 7 | precision = {{ precision }} 8 | sim_tag = "{{ sim_tag }}" 9 | job_opt_list = {{ job_opt_str }} 10 | 11 | ; initialize environment variables 12 | when( strlen(init_file) > 0 13 | load(init_file) 14 | ) 15 | 16 | ; save parametric waveform values as a flattened list. 17 | procedure( save_param_wave_values(wave fmt line_fmt fhandle) 18 | let( (vec wave_cls tmp_val) 19 | if( drIsWaveform(wave) then 20 | ; 1D waveform, simply print all values 21 | vec = drGetWaveformYVec(wave) 22 | wave_cls = className(classOf(drGetElem(vec 0))) 23 | if( wave_cls == 'adtComplex then 24 | ; print complex 25 | for( i 0 drVectorLength(vec) - 1 26 | tmp_val = drGetElem(vec i) 27 | if( imag(tmp_val) < 0 then 28 | ; fix for negative imaginary part. 29 | sprintf(line_fmt "%s%sj\n" fmt fmt) 30 | else 31 | sprintf(line_fmt "%s+%sj\n" fmt fmt) 32 | ) 33 | fprintf(fhandle line_fmt real(tmp_val) imag(tmp_val)) 34 | ) 35 | else 36 | ; print real value 37 | for( i 0 drVectorLength(vec) - 1 38 | fprintf(fhandle line_fmt drGetElem(vec i)) 39 | ) 40 | ) 41 | else 42 | ; parametric waveform, recurse 43 | foreach(val sweepValues(wave) 44 | save_param_wave_values(famValue(wave val) fmt line_fmt fhandle) 45 | ) 46 | ) 47 | ) 48 | ) 49 | 50 | 51 | ; define save functions 52 | ; save a waveform to file. 53 | ; the given waveform will be saved to the file "/.data" as a flattened 1D array. 54 | ; the sweep parameter names of this waveform will be saved to the file "/.sweep", 55 | ; and the values of each parameter will be saved to the file "/.info". 56 | ; data_list_struct is a tconc struct of (waveform_name, waveform_data_file_handle) pairs. 57 | procedure( save_waveform(directory var_name wave precision data_list_struct) 58 | let( (fmt line_fmt wave_cls entry data_file sweep_file fhandle 59 | name_list val_list sweep_df iter_wave) 60 | sprintf(fmt "%%.%de" precision) 61 | sprintf(line_fmt "%s\n" fmt) 62 | wave_cls = className(classOf(wave)) 63 | 64 | if( not( entry = assoc( var_name cdar(data_list_struct) ) ) then 65 | ; first time saving this variable 66 | sprintf(data_file "%s/%s.data" directory var_name) 67 | sprintf(sweep_file "%s/%s.sweep" directory var_name) 68 | cond( 69 | ( or( drIsWaveform(wave) drIsParamWave(wave) ) 70 | ; save sweep names 71 | fhandle = outfile( sweep_file "w" ) 72 | name_list = sweepNames(wave) 73 | foreach(swp_name name_list 74 | fprintf(fhandle "%s\n" swp_name) 75 | ) 76 | close(fhandle) 77 | 78 | ; save sweep values 79 | iter_wave = wave 80 | foreach(swp_name name_list 81 | ; save output most sweep values 82 | val_list = sweepValues(iter_wave) 83 | sprintf(sweep_df "%s/%s.info" directory swp_name) 84 | unless( isFile(sweep_df) 85 | fhandle = outfile( sweep_df "w" ) 86 | foreach(val val_list 87 | fprintf(fhandle line_fmt val) 88 | ) 89 | close(fhandle) 90 | ) 91 | ; remove outer sweep 92 | when( drIsParamWave(iter_wave) 93 | iter_wave = famValue(iter_wave car(val_list)) 94 | ) 95 | ) 96 | 97 | fhandle = outfile( data_file "w" ) 98 | ) 99 | ( or( wave_cls == 'flonum wave_cls == 'fixnum wave_cls == 'adtComplex ) 100 | ; scalar data, make empty sweep file 101 | fhandle = outfile( sweep_file "w") 102 | close(fhandle) 103 | fhandle = outfile( data_file "w" ) 104 | ) 105 | ( t 106 | ; unsupported type 107 | error("Unsupported data for output %s: %A\n" var_name wave) 108 | ) 109 | ) 110 | tconc( data_list_struct list(var_name fhandle) ) 111 | else 112 | fhandle = cadr(entry) 113 | ) 114 | 115 | ; append data to file 116 | if( or( drIsWaveform(wave) drIsParamWave(wave) ) then 117 | save_param_wave_values(wave fmt line_fmt fhandle) 118 | else 119 | ; print single point value 120 | if( wave_cls == 'adtComplex then 121 | ; print complex 122 | if( imag(wave) < 0 then 123 | ; fix for negative imaginary part. 124 | sprintf(line_fmt "%s%sj\n" fmt fmt) 125 | else 126 | sprintf(line_fmt "%s+%sj\n" fmt fmt) 127 | ) 128 | fprintf(fhandle line_fmt real(wave) imag(wave)) 129 | else 130 | fprintf(fhandle line_fmt wave) 131 | ) 132 | ) 133 | 't 134 | ) 135 | ) 136 | 137 | ocnSetXLMode() 138 | ocnxlTargetCellView(lib cell view) 139 | ocnxlLoadSetupState(state 'overwrite) 140 | ocnxlHistoryPrefix(sim_tag) 141 | ocnxlJobSetup(job_opt_list) 142 | printf("*Info* Creating netlist...\n") 143 | createNetlist( ?recreateAll t ?display nil ) 144 | printf("*Info* Starting simulation...\n") 145 | ocnxlRun(?mode 'sweepAndCorners ?nominalCornerEnabled nil ?allCornersEnabled 't 146 | ?allSweepsEnabled 't) 147 | 148 | ; load result database 149 | hist_name = ocnxlGetCurrentHistory() 150 | rdb = axlReadHistoryResDB(hist_name) 151 | point_list = rdb->points() 152 | 153 | sprintf(sweep_fname "%s/sweep.info" save_dir) 154 | sweep_f = outfile( sweep_fname "w" ) 155 | 156 | ; write sweep parameters title 157 | when( point_list 158 | point = car(point_list) 159 | test_list = point->tests() 160 | when( test_list 161 | corner = car(test_list)->cornerName 162 | par_names = setof( name point->params(?corner corner ?sortBy 'name)~>name 163 | and( (name != "corModelSpec") (name != "temperature") ) ) 164 | 165 | fprintf(sweep_f "corner ") 166 | fprintf(sweep_f "%s\n" buildString( par_names " " )) 167 | ) 168 | ) 169 | 170 | ; iterate through each design point and save data. 171 | data_list_struct = tconc(nil 0) 172 | total_points = length(point_list) 173 | cur_idx = 1 174 | foreach(point point_list 175 | printf("*Info* saving process: %d/%d\n" cur_idx total_points) 176 | cur_idx = cur_idx + 1 177 | foreach(test point->tests() 178 | ; write param values to file. 179 | corner = test->cornerName 180 | params = setof(par point->params(?corner corner ?sortBy 'name) 181 | and( (par->name != "corModelSpec") (par->name != "temperature") ) ) 182 | param_vals = mapcar( lambda( (par) par->valueAsString(?digits precision ?notation 'eng) ) params ) 183 | fprintf(sweep_f "%s " corner) 184 | fprintf(sweep_f "%s\n" buildString( param_vals " " )) 185 | 186 | ; open results 187 | openResults(test->resultsDir) 188 | 189 | {% for var, expr in outputs.items() %} 190 | tmp = {{ expr }} 191 | save_waveform( save_dir "{{ var }}" tmp precision data_list_struct ) 192 | {% endfor %} 193 | 194 | ) 195 | ) 196 | 197 | ; close opened files 198 | close(sweep_f) 199 | foreach( entry cdar(data_list_struct) 200 | close(cadr(entry)) 201 | ) 202 | 203 | ocnxlEndXLMode() 204 | 205 | exit() 206 | -------------------------------------------------------------------------------- /bag/io/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /bag/io/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This package provides all IO related functionalities for BAG. 4 | 5 | Most importantly, this module sorts out all the bytes v.s. unicode differences 6 | and simplifies writing python2/3 compatible code. 7 | """ 8 | 9 | from .common import fix_string, to_bytes, set_encoding, get_encoding, \ 10 | set_error_policy, get_error_policy 11 | from .sim_data import load_sim_results, save_sim_results, load_sim_file 12 | from .file import read_file, read_resource, read_yaml, read_yaml_env, readlines_iter, \ 13 | write_file, make_temp_dir, open_temp, open_file, Pickle, Yaml 14 | 15 | from . import process 16 | 17 | __all__ = ['fix_string', 'to_bytes', 'set_encoding', 'get_encoding', 18 | 'set_error_policy', 'get_error_policy', 19 | 'load_sim_results', 'save_sim_results', 'load_sim_file', 20 | 'read_file', 'read_resource', 'read_yaml', 'read_yaml_env', 'readlines_iter', 21 | 'write_file', 'make_temp_dir', 'open_temp', 'open_file', 22 | 'Pickle', 'Yaml' 23 | ] 24 | -------------------------------------------------------------------------------- /bag/io/common.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This module contains some commonly used IO functions. 4 | 5 | In particular, this module keeps track of BAG's system-wide encoding/decoding settings. 6 | """ 7 | 8 | # default BAG file encoding. 9 | bag_encoding = 'utf-8' 10 | # default codec error policy 11 | bag_codec_error = 'replace' 12 | 13 | 14 | def fix_string(obj): 15 | """Fix the given potential string object to ensure python 2/3 compatibility. 16 | 17 | If the given object is raw bytes, decode it into a string using 18 | current encoding and return it. Otherwise, just return the given object. 19 | 20 | This method is useful for writing python 2/3 compatible code. 21 | 22 | Parameters 23 | ---------- 24 | obj : 25 | any python object. 26 | 27 | Returns 28 | ------- 29 | val : 30 | the given object, or a decoded string if the given object is bytes. 31 | """ 32 | if isinstance(obj, bytes): 33 | obj = obj.decode(encoding=bag_encoding, errors=bag_codec_error) 34 | return obj 35 | 36 | 37 | def to_bytes(my_str): 38 | """Convert the given string to raw bytes. 39 | 40 | Parameters 41 | ---------- 42 | my_str : string 43 | the string to encode to bytes. 44 | 45 | Returns 46 | ------- 47 | val : bytes 48 | raw bytes of the string. 49 | """ 50 | return bytes(my_str.encode(encoding=bag_encoding, errors=bag_codec_error)) 51 | 52 | 53 | def set_encoding(new_encoding): 54 | """Sets the BAG input/output encoding. 55 | 56 | Parameters 57 | ---------- 58 | new_encoding : string 59 | the new encoding name. 60 | """ 61 | global bag_encoding 62 | if not isinstance(new_encoding, str): 63 | raise Exception('encoding name must be string/unicode.') 64 | bag_encoding = new_encoding 65 | 66 | 67 | def get_encoding(): 68 | """Returns the BAG input/output encoding. 69 | 70 | Returns 71 | ------- 72 | bag_encoding : unicode 73 | the encoding name. 74 | """ 75 | return bag_encoding 76 | 77 | 78 | def set_error_policy(new_policy): 79 | """Sets the error policy on encoding/decoding errors. 80 | 81 | Parameters 82 | ---------- 83 | new_policy : string 84 | the new error policy name. See codecs package documentation 85 | for more information. 86 | """ 87 | global bag_codec_error 88 | bag_codec_error = new_policy 89 | 90 | 91 | def get_error_policy(): 92 | """Returns the current BAG encoding/decoding error policy. 93 | 94 | Returns 95 | ------- 96 | policy : unicode 97 | the current error policy name. 98 | """ 99 | return bag_codec_error 100 | -------------------------------------------------------------------------------- /bag/io/file.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This module handles file related IO. 4 | """ 5 | from typing import Dict, Any 6 | 7 | import os 8 | import tempfile 9 | import time 10 | import pkg_resources 11 | import codecs 12 | import string 13 | 14 | import yaml 15 | import pickle 16 | 17 | from .common import bag_encoding, bag_codec_error 18 | 19 | 20 | class Pickle: 21 | """ 22 | A global class for reading and writing Pickle format. 23 | """ 24 | @staticmethod 25 | def save(obj, file, **kwargs) -> None: 26 | with open(file, 'wb') as f: 27 | pickle.dump(obj, f, pickle.HIGHEST_PROTOCOL) 28 | 29 | @staticmethod 30 | def load(file, **kwargs): 31 | with open(file, 'rb') as f: 32 | return pickle.load(f) 33 | 34 | 35 | class Yaml: 36 | """ 37 | A global class for reading and writing yaml format 38 | For backward compatibility some module functions may overlap with this. 39 | """ 40 | @staticmethod 41 | def save(obj, file, **kwargs) -> None: 42 | with open(file, 'w') as f: 43 | yaml.dump(obj, f) 44 | 45 | @staticmethod 46 | def load(file, **kwargs): 47 | with open(file, 'r') as f: 48 | return yaml.load(f, Loader=yaml.Loader) 49 | 50 | 51 | def open_file(fname, mode): 52 | """Opens a file with the correct encoding interface. 53 | 54 | Use this method if you need to have a file handle. 55 | 56 | Parameters 57 | ---------- 58 | fname : string 59 | the file name. 60 | mode : string 61 | the mode, either 'r', 'w', or 'a'. 62 | 63 | Returns 64 | ------- 65 | file_obj : file 66 | a file objects that reads/writes string with the BAG system encoding. 67 | """ 68 | if mode != 'r' and mode != 'w' and mode != 'a': 69 | raise ValueError("Only supports 'r', 'w', or 'a' mode.") 70 | return open(fname, mode, encoding=bag_encoding, errors=bag_codec_error) 71 | 72 | 73 | def read_file(fname): 74 | """Read the given file and return content as string. 75 | 76 | Parameters 77 | ---------- 78 | fname : string 79 | the file name. 80 | 81 | Returns 82 | ------- 83 | content : unicode 84 | the content as a unicode string. 85 | """ 86 | with open_file(fname, 'r') as f: 87 | content = f.read() 88 | return content 89 | 90 | 91 | def readlines_iter(fname): 92 | """Iterate over lines in a file. 93 | 94 | Parameters 95 | ---------- 96 | fname : string 97 | the file name. 98 | 99 | Yields 100 | ------ 101 | line : unicode 102 | a line in the file. 103 | """ 104 | with open_file(fname, 'r') as f: 105 | for line in f: 106 | yield line 107 | 108 | 109 | def read_yaml_env(fname): 110 | # type: (str) -> Dict[str, Any] 111 | """Parse YAML file with environment variable substitution. 112 | 113 | Parameters 114 | ---------- 115 | fname : str 116 | yaml file name. 117 | 118 | Returns 119 | ------- 120 | table : Dict[str, Any] 121 | the yaml file as a dictionary. 122 | """ 123 | content = read_file(fname) 124 | # substitute environment variables 125 | content = string.Template(content).substitute(os.environ) 126 | return yaml.load(content, Loader=yaml.Loader) 127 | 128 | 129 | def read_yaml(fname): 130 | """Read the given file using YAML. 131 | 132 | Parameters 133 | ---------- 134 | fname : string 135 | the file name. 136 | 137 | Returns 138 | ------- 139 | content : Any 140 | the object returned by YAML. 141 | """ 142 | with open_file(fname, 'r') as f: 143 | content = yaml.load(f, Loader=yaml.Loader) 144 | 145 | return content 146 | 147 | 148 | def read_resource(package, fname): 149 | """Read the given resource file and return content as string. 150 | 151 | Parameters 152 | ---------- 153 | package : string 154 | the package name. 155 | fname : string 156 | the resource file name. 157 | 158 | Returns 159 | ------- 160 | content : unicode 161 | the content as a unicode string. 162 | """ 163 | raw_content = pkg_resources.resource_string(package, fname) 164 | return raw_content.decode(encoding=bag_encoding, errors=bag_codec_error) 165 | 166 | 167 | def write_file(fname, content, append=False, mkdir=True): 168 | """Writes the given content to file. 169 | 170 | Parameters 171 | ---------- 172 | fname : string 173 | the file name. 174 | content : unicode 175 | the unicode string to write to file. 176 | append : bool 177 | True to append instead of overwrite. 178 | mkdir : bool 179 | If True, will create parent directories if they don't exist. 180 | """ 181 | if mkdir: 182 | fname = os.path.abspath(fname) 183 | dname = os.path.dirname(fname) 184 | os.makedirs(dname, exist_ok=True) 185 | 186 | mode = 'a' if append else 'w' 187 | with open_file(fname, mode) as f: 188 | f.write(content) 189 | 190 | 191 | def make_temp_dir(prefix, parent_dir=None): 192 | """Create a new temporary directory. 193 | 194 | Parameters 195 | ---------- 196 | prefix : string 197 | the directory prefix. 198 | parent_dir : string 199 | the parent directory. 200 | """ 201 | prefix += time.strftime("_%Y%m%d_%H%M%S") 202 | parent_dir = parent_dir or tempfile.gettempdir() 203 | return tempfile.mkdtemp(prefix=prefix, dir=parent_dir) 204 | 205 | 206 | def open_temp(**kwargs): 207 | """Opens a new temporary file for writing with unicode interface. 208 | 209 | Parameters 210 | ---------- 211 | **kwargs 212 | the tempfile keyword arguments. See documentation for 213 | :func:`tempfile.NamedTemporaryFile`. 214 | 215 | Returns 216 | ------- 217 | file : file 218 | the opened file that accepts unicode input. 219 | """ 220 | timestr = time.strftime("_%Y%m%d_%H%M%S") 221 | if 'prefix' in kwargs: 222 | kwargs['prefix'] += timestr 223 | else: 224 | kwargs['prefix'] = timestr 225 | temp = tempfile.NamedTemporaryFile(**kwargs) 226 | return codecs.getwriter(bag_encoding)(temp, errors=bag_codec_error) 227 | -------------------------------------------------------------------------------- /bag/io/gui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import os 4 | import sys 5 | import subprocess 6 | import json 7 | import select 8 | 9 | import PyQt5.QtWidgets as QtWidgets 10 | import PyQt5.QtCore as QtCore 11 | 12 | from .file import write_file, open_file 13 | from .common import to_bytes 14 | 15 | if os.name != 'posix': 16 | raise Exception('bag.io.gui module current only works for POSIX systems.') 17 | 18 | 19 | class StdinThread(QtCore.QThread): 20 | """A QT worker thread that reads stdin.""" 21 | update = QtCore.pyqtSignal('QString') 22 | 23 | def __init__(self, parent): 24 | QtCore.QThread.__init__(self, parent=parent) 25 | self.stop = False 26 | 27 | def run(self): 28 | while not self.stop: 29 | try: 30 | stdin, _, _ = select.select([sys.stdin], [], [], 0.05) 31 | if stdin: 32 | cmd = sys.stdin.readline().strip() 33 | else: 34 | cmd = None 35 | except: 36 | cmd = 'exit' 37 | 38 | if cmd is not None: 39 | self.stop = (cmd == 'exit') 40 | self.update.emit(cmd) 41 | 42 | 43 | class LogWidget(QtWidgets.QFrame): 44 | """A Logger window widget. 45 | 46 | Note: due to QPlainTextEdit always adding an extra newline when calling 47 | appendPlainText(), we keep track of internal buffer and only print output 48 | one line at a time. This may cause some message to not display immediately. 49 | """ 50 | 51 | def __init__(self, parent=None): 52 | QtWidgets.QFrame.__init__(self, parent=parent) 53 | 54 | self.logger = QtWidgets.QPlainTextEdit(parent=self) 55 | self.logger.setReadOnly(True) 56 | self.logger.setLineWrapMode(QtWidgets.QPlainTextEdit.NoWrap) 57 | self.logger.setMinimumWidth(1100) 58 | self.buffer = '' 59 | 60 | self.clear_button = QtWidgets.QPushButton('Clear Log', parent=self) 61 | self.clear_button.clicked.connect(self.clear_log) 62 | self.save_button = QtWidgets.QPushButton('Save Log As...', parent=self) 63 | self.save_button.clicked.connect(self.save_log) 64 | 65 | self.lay = QtWidgets.QVBoxLayout(self) 66 | self.lay.addWidget(self.logger) 67 | self.lay.addWidget(self.clear_button) 68 | self.lay.addWidget(self.save_button) 69 | 70 | def clear_log(self): 71 | self.logger.setPlainText('') 72 | self.buffer = '' 73 | 74 | def save_log(self): 75 | root_dir = os.getcwd() 76 | fname, _ = QtWidgets.QFileDialog.getSaveFileName(self, 'Save File', root_dir) 77 | if fname: 78 | write_file(fname, self.logger.toPlainText() + '\n') 79 | 80 | def print_file(self, file_obj): 81 | # this code converts all types of newlines (such as '\r\n') to '\n', 82 | # and make sure any ending newlines are preserved. 83 | for line in file_obj: 84 | if self.buffer: 85 | line = self.buffer + line 86 | self.buffer = '' 87 | if line.endswith('\n'): 88 | self.logger.appendPlainText(line[:-1]) 89 | else: 90 | self.buffer = line 91 | 92 | 93 | class LogViewer(QtWidgets.QWidget): 94 | """A Simple window to see process log in real time..""" 95 | 96 | def __init__(self): 97 | QtWidgets.QWidget.__init__(self) 98 | 99 | # combo box label 100 | self.label = QtWidgets.QLabel('Log File: ', parent=self) 101 | # populate log selection combo box. 102 | self.combo_box = QtWidgets.QComboBox(parent=self) 103 | self.log_files = [] 104 | self.reader = None 105 | 106 | self.logger = LogWidget(parent=self) 107 | 108 | # setup GUI 109 | self.setWindowTitle('BAG Simulation Log Viewer') 110 | self.setAttribute(QtCore.Qt.WA_DeleteOnClose) 111 | 112 | self.layout = QtWidgets.QGridLayout(self) 113 | self.layout.addWidget(self.label, 0, 0, alignment=QtCore.Qt.AlignRight) 114 | self.layout.addWidget(self.combo_box, 0, 1, alignment=QtCore.Qt.AlignLeft) 115 | self.layout.addWidget(self.logger, 1, 0, -1, -1) 116 | self.layout.setRowStretch(0, 0.0) 117 | self.layout.setRowStretch(1, 1.0) 118 | self.layout.setColumnStretch(0, 0.0) 119 | self.layout.setColumnStretch(1, 0.0) 120 | 121 | # setup file watcher 122 | self.cur_paths = None 123 | self.watcher = QtCore.QFileSystemWatcher(parent=self) 124 | # setup signals 125 | self.watcher.fileChanged.connect(self.update_logfile) 126 | self.combo_box.currentIndexChanged.connect(self.change_log) 127 | 128 | # start thread 129 | self.thread = StdinThread(self) 130 | self.thread.update.connect(self.parse_cmd) 131 | self.thread.start() 132 | 133 | def closeEvent(self, evt): 134 | if not self.thread.stop: 135 | self.thread.stop = True 136 | self.thread.wait() 137 | QtWidgets.QWidget.closeEvent(self, evt) 138 | 139 | @QtCore.pyqtSlot('QString') 140 | def parse_cmd(self, cmd): 141 | if cmd == 'exit': 142 | self.close() 143 | else: 144 | try: 145 | cmd = json.loads(cmd) 146 | if cmd[0] == 'add': 147 | self.add_log(cmd[1], cmd[2]) 148 | elif cmd[0] == 'remove': 149 | self.remove_log(cmd[1]) 150 | except: 151 | pass 152 | 153 | @QtCore.pyqtSlot('int') 154 | def change_log(self, new_idx): 155 | # print('log change called, switching to index %d' % new_idx) 156 | if self.cur_paths is not None: 157 | self.watcher.removePaths(self.cur_paths) 158 | self.logger.clear_log() 159 | if self.reader is not None: 160 | self.reader.close() 161 | self.reader = None 162 | 163 | if new_idx >= 0: 164 | fname = os.path.abspath(self.log_files[new_idx]) 165 | dname = os.path.dirname(fname) 166 | self.reader = open_file(fname, 'r') 167 | self.logger.print_file(self.reader) 168 | self.cur_paths = [dname, fname] 169 | self.watcher.addPaths(self.cur_paths) 170 | 171 | @QtCore.pyqtSlot('QString') 172 | def update_logfile(self, fname): 173 | # print('filechanged called, fname = %s' % fname) 174 | if self.reader is not None: 175 | self.logger.print_file(self.reader) 176 | 177 | def remove_log(self, log_tag): 178 | idx = self.combo_box.findText(log_tag) 179 | if idx >= 0: 180 | del self.log_files[idx] 181 | self.combo_box.removeItem(idx) 182 | 183 | def add_log(self, log_tag, log_file): 184 | self.remove_log(log_tag) 185 | if os.path.isfile(log_file): 186 | self.log_files.append(log_file) 187 | self.combo_box.addItem(log_tag) 188 | 189 | 190 | def app_start(): 191 | app = QtWidgets.QApplication([]) 192 | 193 | window = LogViewer() 194 | app.window_reference = window 195 | window.show() 196 | app.exec_() 197 | 198 | 199 | def start_viewer(): 200 | cmd = [sys.executable, '-m', 'bag.io.gui'] 201 | devnull = open(os.devnull, 'w') 202 | proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=devnull, 203 | stderr=subprocess.STDOUT, 204 | preexec_fn=os.setpgrp) 205 | return proc 206 | 207 | 208 | def add_log(proc, tag, fname): 209 | if proc is not None: 210 | if proc.poll() is not None or proc.stdin.closed: 211 | # process finished 212 | return False 213 | cmd_str = json.dumps(['add', tag, fname]) + '\n' 214 | proc.stdin.write(to_bytes(cmd_str)) 215 | proc.stdin.flush() 216 | return True 217 | 218 | 219 | def remove_log(proc, tag): 220 | if proc is not None: 221 | if proc.poll() is not None or proc.stdin.closed: 222 | # process finished 223 | return False 224 | cmd_str = json.dumps(['remove', tag]) + '\n' 225 | proc.stdin.write(to_bytes(cmd_str)) 226 | proc.stdin.flush() 227 | return True 228 | 229 | 230 | def close(proc): 231 | if proc is not None and proc.poll() is None: 232 | proc.stdin.close() 233 | 234 | if __name__ == '__main__': 235 | app_start() 236 | -------------------------------------------------------------------------------- /bag/io/template.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This module defines methods to create files from templates. 4 | """ 5 | 6 | from jinja2 import Environment, PackageLoader, select_autoescape 7 | 8 | 9 | def new_template_env(parent_package, tmp_folder): 10 | # type: (str, str) -> Environment 11 | return Environment(trim_blocks=True, 12 | lstrip_blocks=True, 13 | keep_trailing_newline=True, 14 | autoescape=select_autoescape(default_for_string=False), 15 | loader=PackageLoader(parent_package, package_path=tmp_folder), 16 | enable_async=False, 17 | ) 18 | -------------------------------------------------------------------------------- /bag/layout/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /bag/layout/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This package contains code for templated based layout. 4 | """ 5 | 6 | from .core import BagLayout, TechInfo 7 | from .routing import RoutingGrid 8 | from .template import TemplateDB 9 | from . import util 10 | 11 | 12 | __all__ = ['BagLayout', 'TechInfo', 13 | 'RoutingGrid', 14 | 'TemplateDB', 15 | ] 16 | -------------------------------------------------------------------------------- /bag/layout/routing/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /bag/layout/routing/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This package provide routing classes. 4 | """ 5 | 6 | from .base import TrackID, WireArray, Port, TrackManager 7 | from .grid import RoutingGrid 8 | from .fill import UsedTracks 9 | -------------------------------------------------------------------------------- /bag/math/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /bag/math/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This package defines design template classes. 4 | """ 5 | 6 | from typing import Iterable 7 | 8 | import numpy as np 9 | from . import interpolate 10 | 11 | __all__ = ['lcm', 'gcd', 'interpolate', 'float_to_si_string', 'si_string_to_float'] 12 | 13 | 14 | si_mag = [-18, -15, -12, -9, -6, -3, 0, 3, 6, 9, 12] 15 | si_pre = ['a', 'f', 'p', 'n', 'u', 'm', '', 'k', 'M', 'G', 'T'] 16 | 17 | 18 | def float_to_si_string(num, precision=6): 19 | """Converts the given floating point number to a string using SI prefix. 20 | 21 | Parameters 22 | ---------- 23 | num : float 24 | the number to convert. 25 | precision : int 26 | number of significant digits, defaults to 6. 27 | 28 | Returns 29 | ------- 30 | ans : str 31 | the string representation of the given number using SI suffix. 32 | """ 33 | if abs(num) < 1e-21: 34 | return '0' 35 | exp = np.log10(abs(num)) 36 | 37 | pre_idx = len(si_mag) - 1 38 | for idx in range(len(si_mag)): 39 | if exp < si_mag[idx]: 40 | pre_idx = idx - 1 41 | break 42 | 43 | fmt = '%%.%dg%%s' % precision 44 | res = 10.0 ** (si_mag[pre_idx]) 45 | return fmt % (num / res, si_pre[pre_idx]) 46 | 47 | 48 | def si_string_to_float(si_str): 49 | """Converts the given string with SI prefix to float. 50 | 51 | Parameters 52 | ---------- 53 | si_str : str 54 | the string to convert 55 | 56 | Returns 57 | ------- 58 | ans : float 59 | the floating point value of the given string. 60 | """ 61 | if si_str[-1] in si_pre: 62 | idx = si_pre.index(si_str[-1]) 63 | return float(si_str[:-1]) * 10**si_mag[idx] 64 | else: 65 | return float(si_str) 66 | 67 | 68 | def gcd(a, b): 69 | # type: (int, int) -> int 70 | """Compute greatest common divisor of two positive integers. 71 | 72 | Parameters 73 | ---------- 74 | a : int 75 | the first number. 76 | b : int 77 | the second number. 78 | 79 | Returns 80 | ------- 81 | ans : int 82 | the greatest common divisor of the two given integers. 83 | """ 84 | while b: 85 | a, b = b, a % b 86 | return a 87 | 88 | 89 | def lcm(arr, init=1): 90 | # type: (Iterable[int], int) -> int 91 | """Compute least common multiple of all numbers in the given list. 92 | 93 | Parameters 94 | ---------- 95 | arr : Iterable[int] 96 | a list of integers. 97 | init : int 98 | the initial LCM. Defaults to 1. 99 | 100 | Returns 101 | ------- 102 | ans : int 103 | the least common multiple of all the given numbers. 104 | """ 105 | cur_lcm = init 106 | for val in arr: 107 | cur_lcm = cur_lcm * val // gcd(cur_lcm, val) 108 | return cur_lcm 109 | -------------------------------------------------------------------------------- /bag/mdao/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /bag/mdao/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This package contains various openmdao related modules. 4 | """ -------------------------------------------------------------------------------- /bag/mdao/components.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This module defines various OpenMDAO component classes. 4 | """ 5 | 6 | import numpy as np 7 | import openmdao.api as omdao 8 | 9 | 10 | class VecFunComponent(omdao.Component): 11 | """A component based on a list of functions. 12 | 13 | A component that evaluates multiple functions on the given inputs, then 14 | returns the result as an 1D array. Each of the inputs may be a scalar or 15 | a vector with the same size as the output. If a vector input is given, 16 | each function will use a different element of the vector. 17 | 18 | Parameters 19 | ---------- 20 | output_name : str 21 | output name. 22 | fun_list : list[bag.math.dfun.DiffFunction] 23 | list of interpolator functions, one for each dimension. 24 | params : list[str] 25 | list of parameter names. Parameter names may repeat, in which case the 26 | same parameter will be used for multiple arguments of the function. 27 | vector_params : set[str] 28 | set of parameters that are vector instead of scalar. If a parameter 29 | is a vector, it will be the same size as the output, and each function 30 | only takes in the corresponding element of the parameter. 31 | """ 32 | 33 | def __init__(self, output_name, fun_list, params, 34 | vector_params=None): 35 | omdao.Component.__init__(self) 36 | 37 | vector_params = vector_params or set() 38 | 39 | self._output = output_name 40 | self._out_dim = len(fun_list) 41 | self._in_dim = len(params) 42 | self._params = params 43 | self._unique_params = {} 44 | self._fun_list = fun_list 45 | 46 | for par in params: 47 | adj = par in vector_params 48 | shape = self._out_dim if adj else 1 49 | 50 | if par not in self._unique_params: 51 | # linear check, but small list so should be fine. 52 | self.add_param(par, val=np.zeros(shape)) 53 | self._unique_params[par] = len(self._unique_params), adj 54 | 55 | # construct chain rule jacobian matrix 56 | self._chain_jacobian = np.zeros((self._in_dim, len(self._unique_params))) 57 | for idx, par in enumerate(params): 58 | self._chain_jacobian[idx, self._unique_params[par][0]] = 1 59 | 60 | self.add_output(output_name, val=np.zeros(self._out_dim)) 61 | 62 | def __call__(self, **kwargs): 63 | """Evaluate on the given inputs. 64 | 65 | Parameters 66 | ---------- 67 | kwargs : dict[str, np.array or float] 68 | the inputs as a dictionary. 69 | 70 | Returns 71 | ------- 72 | out : np.array 73 | the output array. 74 | """ 75 | tmp = {} 76 | self.solve_nonlinear(kwargs, tmp) 77 | return tmp[self._output] 78 | 79 | def _get_inputs(self, params): 80 | """Given parameter values, construct inputs for functions. 81 | 82 | Parameters 83 | ---------- 84 | params : VecWrapper, optional 85 | VecWrapper containing parameters. (p) 86 | 87 | Returns 88 | ------- 89 | ans : list[list[float]] 90 | input lists. 91 | """ 92 | ans = np.empty((self._out_dim, self._in_dim)) 93 | for idx, name in enumerate(self._params): 94 | ans[:, idx] = params[name] 95 | return ans 96 | 97 | def solve_nonlinear(self, params, unknowns, resids=None): 98 | """Compute the output parameter. 99 | 100 | Parameters 101 | ---------- 102 | params : VecWrapper, optional 103 | VecWrapper containing parameters. (p) 104 | 105 | unknowns : VecWrapper, optional 106 | VecWrapper containing outputs and states. (u) 107 | 108 | resids : VecWrapper, optional 109 | VecWrapper containing residuals. (r) 110 | """ 111 | xi_mat = self._get_inputs(params) 112 | 113 | tmp = np.empty(self._out_dim) 114 | for idx in range(self._out_dim): 115 | tmp[idx] = self._fun_list[idx](xi_mat[idx, :]) 116 | 117 | unknowns[self._output] = tmp 118 | 119 | def linearize(self, params, unknowns=None, resids=None): 120 | """Compute the Jacobian of the parameter. 121 | 122 | Parameters 123 | ---------- 124 | params : VecWrapper, optional 125 | VecWrapper containing parameters. (p) 126 | 127 | unknowns : VecWrapper, optional 128 | VecWrapper containing outputs and states. (u) 129 | 130 | resids : VecWrapper, optional 131 | VecWrapper containing residuals. (r) 132 | """ 133 | # print('rank {} computing jac for {}'.format(self.comm.rank, self._outputs)) 134 | 135 | xi_mat = self._get_inputs(params) 136 | 137 | jf = np.empty((self._out_dim, self._in_dim)) 138 | for k, fun in enumerate(self._fun_list): 139 | jf[k, :] = fun.jacobian(xi_mat[k, :]) 140 | 141 | jmat = np.dot(jf, self._chain_jacobian) 142 | jdict = {} 143 | for par, (pidx, adj) in self._unique_params.items(): 144 | tmp = jmat[:, pidx] 145 | if adj: 146 | tmp = np.diag(tmp) 147 | jdict[self._output, par] = tmp 148 | 149 | return jdict 150 | -------------------------------------------------------------------------------- /bag/simulation/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /bag/simulation/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This package defines various utility classes for running simulations and data post-processing. 4 | """ -------------------------------------------------------------------------------- /bag/tech/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /bag/tech/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This package contains various technology related utilities, such as transistor characterization. 4 | """ -------------------------------------------------------------------------------- /bag/util/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /bag/util/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This package defines various utilities classes. 4 | """ -------------------------------------------------------------------------------- /bag/util/immutable.py: -------------------------------------------------------------------------------- 1 | """This module defines various immutable and hashable data types. 2 | """ 3 | 4 | from __future__ import annotations 5 | 6 | from typing import TypeVar, Any, Generic, Dict, Iterable, Tuple, Union, Optional, overload 7 | 8 | import sys 9 | import bisect 10 | from collections import Hashable, Mapping, Sequence 11 | 12 | T = TypeVar('T') 13 | U = TypeVar('U') 14 | ImmutableType = Union[None, Hashable, Tuple[Hashable, ...]] 15 | 16 | 17 | def combine_hash(a: int, b: int) -> int: 18 | """Combine the two given hash values. 19 | 20 | Parameter 21 | --------- 22 | a : int 23 | the first hash value. 24 | b : int 25 | the second hash value. 26 | 27 | Returns 28 | ------- 29 | hash : int 30 | the combined hash value. 31 | """ 32 | # algorithm taken from boost::hash_combine 33 | return sys.maxsize & (a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2))) 34 | 35 | 36 | class ImmutableList(Hashable, Sequence, Generic[T]): 37 | """An immutable homogeneous list.""" 38 | 39 | def __init__(self, values: Optional[Sequence[T]] = None) -> None: 40 | if values is None: 41 | self._content = [] 42 | self._hash = 0 43 | elif isinstance(values, ImmutableList): 44 | self._content = values._content 45 | self._hash = values._hash 46 | else: 47 | self._content = values 48 | self._hash = 0 49 | for v in values: 50 | self._hash = combine_hash(self._hash, hash(v)) 51 | 52 | @classmethod 53 | def sequence_equal(cls, a: Sequence[T], b: Sequence[T]) -> bool: 54 | if len(a) != len(b): 55 | return False 56 | for av, bv in zip(a, b): 57 | if av != bv: 58 | return False 59 | return True 60 | 61 | def __repr__(self) -> str: 62 | return repr(self._content) 63 | 64 | def __eq__(self, other: Any) -> bool: 65 | return (isinstance(other, ImmutableList) and self._hash == other._hash and 66 | self.sequence_equal(self._content, other._content)) 67 | 68 | def __hash__(self) -> int: 69 | return self._hash 70 | 71 | def __bool__(self) -> bool: 72 | return len(self) > 0 73 | 74 | def __len__(self) -> int: 75 | return len(self._content) 76 | 77 | def __iter__(self) -> Iterable[T]: 78 | return iter(self._content) 79 | 80 | @overload 81 | def __getitem__(self, idx: int) -> T: ... 82 | @overload 83 | def __getitem__(self, idx: slice) -> ImmutableList[T]: ... 84 | 85 | def __getitem__(self, idx) -> T: 86 | if isinstance(idx, int): 87 | return self._content[idx] 88 | return ImmutableList(self._content[idx]) 89 | 90 | def __contains__(self, val: Any) -> bool: 91 | return val in self._content 92 | 93 | 94 | class ImmutableSortedDict(Hashable, Mapping, Generic[T, U]): 95 | """An immutable dictionary with sorted keys.""" 96 | 97 | def __init__(self, 98 | table: Optional[Mapping[T, Any]] = None) -> None: 99 | if table is not None: 100 | if isinstance(table, ImmutableSortedDict): 101 | self._keys = table._keys 102 | self._vals = table._vals 103 | self._hash = table._hash 104 | else: 105 | self._keys = ImmutableList(sorted(table.keys())) 106 | self._vals = ImmutableList([to_immutable(table[k]) for k in self._keys]) 107 | self._hash = combine_hash(hash(self._keys), hash(self._vals)) 108 | else: 109 | self._keys = ImmutableList([]) 110 | self._vals = ImmutableList([]) 111 | self._hash = combine_hash(hash(self._keys), hash(self._vals)) 112 | 113 | def __repr__(self) -> str: 114 | return repr(list(zip(self._keys, self._vals))) 115 | 116 | def __eq__(self, other: Any) -> bool: 117 | return (isinstance(other, ImmutableSortedDict) and 118 | self._hash == other._hash and 119 | self._keys == other._keys and 120 | self._vals == other._vals) 121 | 122 | def __hash__(self) -> int: 123 | return self._hash 124 | 125 | def __bool__(self) -> bool: 126 | return len(self) > 0 127 | 128 | def __len__(self) -> int: 129 | return len(self._keys) 130 | 131 | def __iter__(self) -> Iterable[T]: 132 | return iter(self._keys) 133 | 134 | def __contains__(self, item: Any) -> bool: 135 | idx = bisect.bisect_left(self._keys, item) 136 | return idx != len(self._keys) and self._keys[idx] == item 137 | 138 | def __getitem__(self, item: T) -> U: 139 | idx = bisect.bisect_left(self._keys, item) 140 | if idx == len(self._keys) or self._keys[idx] != item: 141 | raise KeyError('Key not found: {}'.format(item)) 142 | return self._vals[idx] 143 | 144 | def get(self, item: T, default: Optional[U] = None) -> Optional[U]: 145 | idx = bisect.bisect_left(self._keys, item) 146 | if idx == len(self._keys) or self._keys[idx] != item: 147 | return default 148 | return self._vals[idx] 149 | 150 | def keys(self) -> Iterable[T]: 151 | return iter(self._keys) 152 | 153 | def values(self) -> Iterable[U]: 154 | return iter(self._vals) 155 | 156 | def items(self) -> Iterable[Tuple[T, U]]: 157 | return zip(self._keys, self._vals) 158 | 159 | def copy(self, append: Optional[Dict[T, Any]] = None) -> ImmutableSortedDict[T, U]: 160 | if append is None: 161 | return self.__class__(self) 162 | else: 163 | tmp = self.to_dict() 164 | tmp.update(append) 165 | return self.__class__(tmp) 166 | 167 | def to_dict(self) -> Dict[T, U]: 168 | return dict(zip(self._keys, self._vals)) 169 | 170 | 171 | Param = ImmutableSortedDict[str, Any] 172 | 173 | 174 | def to_immutable(obj: Any) -> ImmutableType: 175 | """Convert the given Python object into an immutable type.""" 176 | if obj is None: 177 | return obj 178 | if isinstance(obj, Hashable): 179 | # gets around cases of tuple of un-hashable types. 180 | try: 181 | hash(obj) 182 | return obj 183 | except TypeError: 184 | pass 185 | if isinstance(obj, tuple): 186 | return tuple((to_immutable(v) for v in obj)) 187 | if isinstance(obj, list): 188 | return ImmutableList([to_immutable(v) for v in obj]) 189 | if isinstance(obj, set): 190 | return ImmutableList([to_immutable(v) for v in sorted(obj)]) 191 | if isinstance(obj, dict): 192 | return ImmutableSortedDict(obj) 193 | 194 | raise ValueError('Cannot convert the following object to immutable type: {}'.format(obj)) 195 | -------------------------------------------------------------------------------- /bag/util/parse.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This module defines parsing utility methods. 4 | """ 5 | 6 | import ast 7 | 8 | 9 | class ExprVarScanner(ast.NodeVisitor): 10 | """ 11 | This node visitor collects all variable names found in the 12 | AST, and excludes names of functions. Variables having 13 | dotted names are not supported. 14 | """ 15 | def __init__(self): 16 | self.varnames = set() 17 | 18 | # noinspection PyPep8Naming 19 | def visit_Name(self, node): 20 | self.varnames.add(node.id) 21 | 22 | # noinspection PyPep8Naming 23 | def visit_Call(self, node): 24 | if not isinstance(node.func, ast.Name): 25 | self.visit(node.func) 26 | for arg in node.args: 27 | self.visit(arg) 28 | 29 | # noinspection PyPep8Naming 30 | def visit_Attribute(self, node): 31 | # ignore attributes 32 | pass 33 | 34 | 35 | def get_variables(expr): 36 | """Parses the given Python expression and return a list of all variables. 37 | 38 | Parameters 39 | ---------- 40 | expr : str 41 | An expression string that we want to parse for variable names. 42 | 43 | Returns 44 | ------- 45 | var_list : list[str] 46 | Names of variables from the given expression. 47 | """ 48 | root = ast.parse(expr, mode='exec') 49 | scanner = ExprVarScanner() 50 | scanner.visit(root) 51 | return list(scanner.varnames) 52 | -------------------------------------------------------------------------------- /bag/verification/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /bag/verification/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This package contains LVS/RCX related verification methods. 4 | """ 5 | 6 | from typing import Any 7 | 8 | import importlib 9 | 10 | from .base import Checker 11 | 12 | __all__ = ['make_checker', 'Checker'] 13 | 14 | 15 | def make_checker(checker_cls, tmp_dir, **kwargs): 16 | # type: (str, str, **Any) -> Checker 17 | """Returns a checker object. 18 | 19 | Parameters 20 | ----------- 21 | checker_cls : str 22 | the Checker class absolute path name. 23 | tmp_dir : str 24 | directory to save temporary files in. 25 | **kwargs : Any 26 | keyword arguments needed to create a Checker object. 27 | """ 28 | sections = checker_cls.split('.') 29 | 30 | module_str = '.'.join(sections[:-1]) 31 | class_str = sections[-1] 32 | module = importlib.import_module(module_str) 33 | return getattr(module, class_str)(tmp_dir, **kwargs) 34 | -------------------------------------------------------------------------------- /bag/verification/templates/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /bag/verification/templates/layout_export_config.txt: -------------------------------------------------------------------------------- 1 | case "preserve" 2 | cellListFile "" 3 | cellMap "" 4 | cellNamePrefix "" 5 | cellNameSuffix "" 6 | convertDot "node" 7 | convertPin "geometry" 8 | #doNotPreservePcellPins 9 | #flattenPcells 10 | #flattenVias 11 | fontMap "" 12 | #ignoreLines 13 | #ignorePcellEvalFail 14 | labelCase "preserve" 15 | labelDepth "1" 16 | labelMap "" 17 | layerMap "" 18 | library "{{lib_name}}" 19 | logFile "strmOut.log" 20 | maxVertices "200" 21 | #mergePathSegsToPath 22 | #noConvertHalfWidthPath 23 | noInfo "" 24 | #noObjectProp 25 | #noOutputTextDisplays 26 | #noOutputUnplacedInst 27 | noWarn "" 28 | objectMap "" 29 | outputDir "{{run_dir}}" 30 | #pathToPolygon 31 | pinAttNum "0" 32 | propMap "" 33 | #propValueOnly 34 | #rectToBox 35 | refLibList "" 36 | #replaceBusBitChar 37 | #reportPrecisionLoss 38 | #respectGDSIINameLimit 39 | runDir "{{run_dir}}" 40 | #snapToGrid 41 | strmFile "{{output_name}}" 42 | strmVersion "5" 43 | summaryFile "" 44 | techLib "" 45 | topCell "{{cell_name}}" 46 | userSkillFile "" 47 | viaMap "" 48 | view "{{view_name}}" 49 | warnToErr "" 50 | -------------------------------------------------------------------------------- /bag/verification/templates/si_env.txt: -------------------------------------------------------------------------------- 1 | simStopList = '("auCdl") 2 | simViewList = '("auCdl" "schematic") 3 | globalGndSig = "" 4 | globalPowerSig = "" 5 | shrinkFACTOR = 0 6 | checkScale = "meter" 7 | diodeCheck = "none" 8 | capacitorCheck = "none" 9 | resistorCheck = "none" 10 | resistorModel = "" 11 | shortRES = 2000 12 | simNetlistHier = 't 13 | pinMAP = 'nil 14 | displayPININFO = 't 15 | checkLDD = 'nil 16 | connects = "" 17 | setEQUIV = "" 18 | simRunDir = "{{run_dir}}" 19 | hnlNetlistFileName = "{{output_name}}" 20 | simSimulator = "auCdl" 21 | simViewName = "{{view_name}}" 22 | simCellName = "{{cell_name}}" 23 | simLibName = "{{lib_name}}" 24 | incFILE = "{{source_added_file}}" 25 | cdlSimViewList = '("auCdl" "schematic") 26 | cdlSimStopList = '("auCdl") 27 | auCdlDefNetlistProc = "ansCdlHnlPrintInst" 28 | -------------------------------------------------------------------------------- /bag/verification/virtuoso.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This module handles exporting schematic/layout from Virtuoso. 4 | """ 5 | 6 | from typing import TYPE_CHECKING, Optional, Dict, Any 7 | 8 | import os 9 | from abc import ABC 10 | 11 | from ..io import write_file, open_temp 12 | from .base import SubProcessChecker 13 | 14 | if TYPE_CHECKING: 15 | from .base import ProcInfo 16 | 17 | 18 | class VirtuosoChecker(SubProcessChecker, ABC): 19 | """the base Checker class for Virtuoso. 20 | 21 | This class implement layout/schematic export procedures. 22 | 23 | Parameters 24 | ---------- 25 | tmp_dir : str 26 | temporary file directory. 27 | max_workers : int 28 | maximum number of parallel processes. 29 | cancel_timeout : float 30 | timeout for cancelling a subprocess. 31 | source_added_file : str 32 | file to include for schematic export. 33 | """ 34 | 35 | def __init__(self, tmp_dir, max_workers, cancel_timeout, source_added_file): 36 | # type: (str, int, float, str) -> None 37 | SubProcessChecker.__init__(self, tmp_dir, max_workers, cancel_timeout) 38 | self._source_added_file = source_added_file 39 | 40 | def setup_export_layout(self, lib_name, cell_name, out_file, view_name='layout', params=None): 41 | # type: (str, str, str, str, Optional[Dict[str, Any]]) -> ProcInfo 42 | out_file = os.path.abspath(out_file) 43 | 44 | run_dir = os.path.dirname(out_file) 45 | out_name = os.path.basename(out_file) 46 | log_file = os.path.join(run_dir, 'layout_export.log') 47 | 48 | os.makedirs(run_dir, exist_ok=True) 49 | 50 | # fill in stream out configuration file. 51 | content = self.render_file_template('layout_export_config.txt', 52 | dict( 53 | lib_name=lib_name, 54 | cell_name=cell_name, 55 | view_name=view_name, 56 | output_name=out_name, 57 | run_dir=run_dir, 58 | )) 59 | 60 | with open_temp(prefix='stream_template', dir=run_dir, delete=False) as config_file: 61 | config_fname = config_file.name 62 | config_file.write(content) 63 | 64 | # run strmOut 65 | cmd = ['strmout', '-templateFile', config_fname] 66 | 67 | return cmd, log_file, None, os.environ['BAG_WORK_DIR'] 68 | 69 | def setup_export_schematic(self, lib_name, cell_name, out_file, view_name='schematic', 70 | params=None): 71 | # type: (str, str, str, str, Optional[Dict[str, Any]]) -> ProcInfo 72 | out_file = os.path.abspath(out_file) 73 | 74 | run_dir = os.path.dirname(out_file) 75 | out_name = os.path.basename(out_file) 76 | log_file = os.path.join(run_dir, 'schematic_export.log') 77 | 78 | # fill in stream out configuration file. 79 | content = self.render_file_template('si_env.txt', 80 | dict( 81 | lib_name=lib_name, 82 | cell_name=cell_name, 83 | view_name=view_name, 84 | output_name=out_name, 85 | source_added_file=self._source_added_file, 86 | run_dir=run_dir, 87 | )) 88 | 89 | # create configuration file. 90 | config_fname = os.path.join(run_dir, 'si.env') 91 | write_file(config_fname, content) 92 | 93 | # run command 94 | cmd = ['si', run_dir, '-batch', '-command', 'netlist'] 95 | 96 | return cmd, log_file, None, os.environ['BAG_WORK_DIR'] 97 | -------------------------------------------------------------------------------- /bag/virtuoso.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """This module provides functions needed to get Virtuoso to work with BAG. 4 | """ 5 | 6 | import os 7 | import sys 8 | import atexit 9 | import signal 10 | import argparse 11 | 12 | import bag.interface 13 | import bag.io 14 | 15 | 16 | def run_skill_server(args): 17 | """Run the BAG/Virtuoso server.""" 18 | error_msg = '' 19 | server = None 20 | port_file = None 21 | port_number = None 22 | 23 | try: 24 | # process command line arguments 25 | min_port = args.min_port 26 | max_port = args.max_port 27 | # remove directory from port file name 28 | port_file = os.path.basename(args.port_file) 29 | log_file = args.log_file 30 | 31 | # create log file directory, and remove old log. 32 | if log_file is not None: 33 | log_file = os.path.abspath(log_file) 34 | log_dir = os.path.dirname(log_file) 35 | if not os.path.exists(log_dir): 36 | os.makedirs(log_dir) 37 | elif os.path.exists(log_file): 38 | os.remove(log_file) 39 | 40 | # determine port file name 41 | if 'BAG_WORK_DIR' not in os.environ: 42 | raise Exception('Environment variable BAG_WORK_DIR not defined') 43 | work_dir = os.environ['BAG_WORK_DIR'] 44 | if not os.path.isdir(work_dir): 45 | raise Exception('$BAG_WORK_DIR = %s is not a directory' % work_dir) 46 | 47 | port_file = os.path.join(work_dir, port_file) 48 | 49 | # determine temp directory 50 | tmp_dir = None 51 | if 'BAG_TEMP_DIR' in os.environ: 52 | tmp_dir = os.environ['BAG_TEMP_DIR'] 53 | if not os.path.isdir(tmp_dir): 54 | if os.path.exists(tmp_dir): 55 | raise Exception('$BAG_TEMP_DIR = %s is not a directory' % tmp_dir) 56 | else: 57 | os.makedirs(tmp_dir) 58 | 59 | # attempt to open port and start server 60 | router = bag.interface.ZMQRouter(min_port=min_port, max_port=max_port, log_file=log_file) 61 | server = bag.interface.SkillServer(router, sys.stdout, sys.stdin, tmpdir=tmp_dir) 62 | port_number = router.get_port() 63 | except Exception as ex: 64 | error_msg = 'bag server process error:\n%s\n' % str(ex) 65 | 66 | if not error_msg: 67 | bag.io.write_file(port_file, '%r\n' % port_number) 68 | 69 | # TODO: somehow this is a bug??!! figure it out. 70 | # make sure port_file is removed at exit 71 | # def exit_handler(): 72 | # if os.path.exists(port_file): 73 | # os.remove(port_file) 74 | 75 | # atexit.register(exit_handler) 76 | # signal.signal(signal.SIGTERM, exit_handler) 77 | 78 | try: 79 | sys.stdout.write('BAG skill server has started. Yay!\n') 80 | sys.stdout.flush() 81 | server.run() 82 | except Exception as ex: 83 | error_msg = 'bag server process error:\n%s\n' % str(ex) 84 | 85 | if error_msg: 86 | sys.stderr.write(error_msg) 87 | sys.stderr.flush() 88 | 89 | 90 | def parse_command_line_arguments(): 91 | """Parse command line arguments, then run the corresponding function.""" 92 | 93 | desc = 'A Python program that performs tasks for virtuoso.' 94 | parser = argparse.ArgumentParser(description=desc) 95 | desc = 'Valid commands. Supply -h/--help flag after the command name to learn more about the command.' 96 | sub_parsers = parser.add_subparsers(title='Commands', description=desc, help='command name.') 97 | 98 | desc = 'Run BAG skill server.' 99 | par2 = sub_parsers.add_parser('run_skill_server', description=desc, help=desc) 100 | 101 | par2.add_argument('min_port', type=int, help='minimum socket port number.') 102 | par2.add_argument('max_port', type=int, help='maximum socket port number.') 103 | par2.add_argument('port_file', type=str, help='file to write the port number to.') 104 | par2.add_argument('log_file', type=str, nargs='?', default=None, 105 | help='log file name.') 106 | par2.set_defaults(func=run_skill_server) 107 | 108 | args = parser.parse_args() 109 | args.func(args) 110 | 111 | 112 | if __name__ == '__main__': 113 | parse_command_line_arguments() 114 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | -------------------------------------------------------------------------------- /docs/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /docs/README: -------------------------------------------------------------------------------- 1 | To build/update documentation: 2 | 3 | 1. make sure BAG Python's bin folder is in your path. 4 | 5 | 2. run: 6 | 7 | ./refresh_api.sh 8 | 9 | to generate API documentations. 10 | 11 | 3. run: 12 | 13 | make html 14 | 15 | to build the documentation webpage. 16 | -------------------------------------------------------------------------------- /docs/refresh_api.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env tcsh 2 | 3 | sphinx-apidoc --force --output-dir=source/api ../bag 4 | -------------------------------------------------------------------------------- /docs/source/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /docs/source/api/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /docs/source/api/bag.data.rst: -------------------------------------------------------------------------------- 1 | bag.data package 2 | ================ 3 | 4 | Submodules 5 | ---------- 6 | 7 | bag.data.core module 8 | -------------------- 9 | 10 | .. automodule:: bag.data.core 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | bag.data.dc module 16 | ------------------ 17 | 18 | .. automodule:: bag.data.dc 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | bag.data.digital module 24 | ----------------------- 25 | 26 | .. automodule:: bag.data.digital 27 | :members: 28 | :undoc-members: 29 | :show-inheritance: 30 | 31 | bag.data.lti module 32 | ------------------- 33 | 34 | .. automodule:: bag.data.lti 35 | :members: 36 | :undoc-members: 37 | :show-inheritance: 38 | 39 | bag.data.ltv module 40 | ------------------- 41 | 42 | .. automodule:: bag.data.ltv 43 | :members: 44 | :undoc-members: 45 | :show-inheritance: 46 | 47 | bag.data.mos module 48 | ------------------- 49 | 50 | .. automodule:: bag.data.mos 51 | :members: 52 | :undoc-members: 53 | :show-inheritance: 54 | 55 | bag.data.plot module 56 | -------------------- 57 | 58 | .. automodule:: bag.data.plot 59 | :members: 60 | :undoc-members: 61 | :show-inheritance: 62 | 63 | 64 | Module contents 65 | --------------- 66 | 67 | .. automodule:: bag.data 68 | :members: 69 | :undoc-members: 70 | :show-inheritance: 71 | -------------------------------------------------------------------------------- /docs/source/api/bag.design.rst: -------------------------------------------------------------------------------- 1 | bag.design package 2 | ================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | bag.design.database module 8 | -------------------------- 9 | 10 | .. automodule:: bag.design.database 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | bag.design.module module 16 | ------------------------ 17 | 18 | .. automodule:: bag.design.module 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | 24 | Module contents 25 | --------------- 26 | 27 | .. automodule:: bag.design 28 | :members: 29 | :undoc-members: 30 | :show-inheritance: 31 | -------------------------------------------------------------------------------- /docs/source/api/bag.interface.rst: -------------------------------------------------------------------------------- 1 | bag.interface package 2 | ===================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | bag.interface.database module 8 | ----------------------------- 9 | 10 | .. automodule:: bag.interface.database 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | bag.interface.ocean module 16 | -------------------------- 17 | 18 | .. automodule:: bag.interface.ocean 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | bag.interface.server module 24 | --------------------------- 25 | 26 | .. automodule:: bag.interface.server 27 | :members: 28 | :undoc-members: 29 | :show-inheritance: 30 | 31 | bag.interface.simulator module 32 | ------------------------------ 33 | 34 | .. automodule:: bag.interface.simulator 35 | :members: 36 | :undoc-members: 37 | :show-inheritance: 38 | 39 | bag.interface.skill module 40 | -------------------------- 41 | 42 | .. automodule:: bag.interface.skill 43 | :members: 44 | :undoc-members: 45 | :show-inheritance: 46 | 47 | bag.interface.zmqwrapper module 48 | ------------------------------- 49 | 50 | .. automodule:: bag.interface.zmqwrapper 51 | :members: 52 | :undoc-members: 53 | :show-inheritance: 54 | 55 | 56 | Module contents 57 | --------------- 58 | 59 | .. automodule:: bag.interface 60 | :members: 61 | :undoc-members: 62 | :show-inheritance: 63 | -------------------------------------------------------------------------------- /docs/source/api/bag.io.rst: -------------------------------------------------------------------------------- 1 | bag.io package 2 | ============== 3 | 4 | Submodules 5 | ---------- 6 | 7 | bag.io.common module 8 | -------------------- 9 | 10 | .. automodule:: bag.io.common 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | bag.io.file module 16 | ------------------ 17 | 18 | .. automodule:: bag.io.file 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | bag.io.gui module 24 | ----------------- 25 | 26 | .. automodule:: bag.io.gui 27 | :members: 28 | :undoc-members: 29 | :show-inheritance: 30 | 31 | bag.io.process module 32 | --------------------- 33 | 34 | .. automodule:: bag.io.process 35 | :members: 36 | :undoc-members: 37 | :show-inheritance: 38 | 39 | bag.io.sim_data module 40 | ---------------------- 41 | 42 | .. automodule:: bag.io.sim_data 43 | :members: 44 | :undoc-members: 45 | :show-inheritance: 46 | 47 | 48 | Module contents 49 | --------------- 50 | 51 | .. automodule:: bag.io 52 | :members: 53 | :undoc-members: 54 | :show-inheritance: 55 | -------------------------------------------------------------------------------- /docs/source/api/bag.layout.routing.rst: -------------------------------------------------------------------------------- 1 | bag.layout.routing package 2 | ========================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | bag.layout.routing.base module 8 | ------------------------------ 9 | 10 | .. automodule:: bag.layout.routing.base 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | bag.layout.routing.fill module 16 | ------------------------------ 17 | 18 | .. automodule:: bag.layout.routing.fill 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | bag.layout.routing.grid module 24 | ------------------------------ 25 | 26 | .. automodule:: bag.layout.routing.grid 27 | :members: 28 | :undoc-members: 29 | :show-inheritance: 30 | 31 | 32 | Module contents 33 | --------------- 34 | 35 | .. automodule:: bag.layout.routing 36 | :members: 37 | :undoc-members: 38 | :show-inheritance: 39 | -------------------------------------------------------------------------------- /docs/source/api/bag.layout.rst: -------------------------------------------------------------------------------- 1 | bag.layout package 2 | ================== 3 | 4 | Subpackages 5 | ----------- 6 | 7 | .. toctree:: 8 | 9 | bag.layout.routing 10 | 11 | Submodules 12 | ---------- 13 | 14 | bag.layout.connection module 15 | ---------------------------- 16 | 17 | .. automodule:: bag.layout.connection 18 | :members: 19 | :undoc-members: 20 | :show-inheritance: 21 | 22 | bag.layout.core module 23 | ---------------------- 24 | 25 | .. automodule:: bag.layout.core 26 | :members: 27 | :undoc-members: 28 | :show-inheritance: 29 | 30 | bag.layout.digital module 31 | ------------------------- 32 | 33 | .. automodule:: bag.layout.digital 34 | :members: 35 | :undoc-members: 36 | :show-inheritance: 37 | 38 | bag.layout.objects module 39 | ------------------------- 40 | 41 | .. automodule:: bag.layout.objects 42 | :members: 43 | :undoc-members: 44 | :show-inheritance: 45 | 46 | bag.layout.template module 47 | -------------------------- 48 | 49 | .. automodule:: bag.layout.template 50 | :members: 51 | :undoc-members: 52 | :show-inheritance: 53 | 54 | bag.layout.util module 55 | ---------------------- 56 | 57 | .. automodule:: bag.layout.util 58 | :members: 59 | :undoc-members: 60 | :show-inheritance: 61 | 62 | 63 | Module contents 64 | --------------- 65 | 66 | .. automodule:: bag.layout 67 | :members: 68 | :undoc-members: 69 | :show-inheritance: 70 | -------------------------------------------------------------------------------- /docs/source/api/bag.math.rst: -------------------------------------------------------------------------------- 1 | bag.math package 2 | ================ 3 | 4 | Submodules 5 | ---------- 6 | 7 | bag.math.dfun module 8 | -------------------- 9 | 10 | .. automodule:: bag.math.dfun 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | bag.math.interpolate module 16 | --------------------------- 17 | 18 | .. automodule:: bag.math.interpolate 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | 24 | Module contents 25 | --------------- 26 | 27 | .. automodule:: bag.math 28 | :members: 29 | :undoc-members: 30 | :show-inheritance: 31 | -------------------------------------------------------------------------------- /docs/source/api/bag.mdao.rst: -------------------------------------------------------------------------------- 1 | bag.mdao package 2 | ================ 3 | 4 | Submodules 5 | ---------- 6 | 7 | bag.mdao.components module 8 | -------------------------- 9 | 10 | .. automodule:: bag.mdao.components 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | bag.mdao.core module 16 | -------------------- 17 | 18 | .. automodule:: bag.mdao.core 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | 24 | Module contents 25 | --------------- 26 | 27 | .. automodule:: bag.mdao 28 | :members: 29 | :undoc-members: 30 | :show-inheritance: 31 | -------------------------------------------------------------------------------- /docs/source/api/bag.rst: -------------------------------------------------------------------------------- 1 | bag package 2 | =========== 3 | 4 | Subpackages 5 | ----------- 6 | 7 | .. toctree:: 8 | 9 | bag.data 10 | bag.design 11 | bag.interface 12 | bag.io 13 | bag.layout 14 | bag.math 15 | bag.mdao 16 | bag.tech 17 | bag.util 18 | bag.verification 19 | 20 | Submodules 21 | ---------- 22 | 23 | bag.core module 24 | --------------- 25 | 26 | .. automodule:: bag.core 27 | :members: 28 | :undoc-members: 29 | :show-inheritance: 30 | 31 | bag.virtuoso module 32 | ------------------- 33 | 34 | .. automodule:: bag.virtuoso 35 | :members: 36 | :undoc-members: 37 | :show-inheritance: 38 | 39 | 40 | Module contents 41 | --------------- 42 | 43 | .. automodule:: bag 44 | :members: 45 | :undoc-members: 46 | :show-inheritance: 47 | -------------------------------------------------------------------------------- /docs/source/api/bag.tech.rst: -------------------------------------------------------------------------------- 1 | bag.tech package 2 | ================ 3 | 4 | Submodules 5 | ---------- 6 | 7 | bag.tech.core module 8 | -------------------- 9 | 10 | .. automodule:: bag.tech.core 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | bag.tech.mos module 16 | ------------------- 17 | 18 | .. automodule:: bag.tech.mos 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | 24 | Module contents 25 | --------------- 26 | 27 | .. automodule:: bag.tech 28 | :members: 29 | :undoc-members: 30 | :show-inheritance: 31 | -------------------------------------------------------------------------------- /docs/source/api/bag.util.rst: -------------------------------------------------------------------------------- 1 | bag.util package 2 | ================ 3 | 4 | Submodules 5 | ---------- 6 | 7 | bag.util.interval module 8 | ------------------------ 9 | 10 | .. automodule:: bag.util.interval 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | bag.util.libimport module 16 | ------------------------- 17 | 18 | .. automodule:: bag.util.libimport 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | bag.util.parse module 24 | --------------------- 25 | 26 | .. automodule:: bag.util.parse 27 | :members: 28 | :undoc-members: 29 | :show-inheritance: 30 | 31 | bag.util.search module 32 | ---------------------- 33 | 34 | .. automodule:: bag.util.search 35 | :members: 36 | :undoc-members: 37 | :show-inheritance: 38 | 39 | 40 | Module contents 41 | --------------- 42 | 43 | .. automodule:: bag.util 44 | :members: 45 | :undoc-members: 46 | :show-inheritance: 47 | -------------------------------------------------------------------------------- /docs/source/api/bag.verification.rst: -------------------------------------------------------------------------------- 1 | bag.verification package 2 | ======================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | bag.verification.base module 8 | ---------------------------- 9 | 10 | .. automodule:: bag.verification.base 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | bag.verification.calibre module 16 | ------------------------------- 17 | 18 | .. automodule:: bag.verification.calibre 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | bag.verification.pvs module 24 | --------------------------- 25 | 26 | .. automodule:: bag.verification.pvs 27 | :members: 28 | :undoc-members: 29 | :show-inheritance: 30 | 31 | bag.verification.virtuoso_export module 32 | --------------------------------------- 33 | 34 | .. automodule:: bag.verification.virtuoso_export 35 | :members: 36 | :undoc-members: 37 | :show-inheritance: 38 | 39 | 40 | Module contents 41 | --------------- 42 | 43 | .. automodule:: bag.verification 44 | :members: 45 | :undoc-members: 46 | :show-inheritance: 47 | -------------------------------------------------------------------------------- /docs/source/api/modules.rst: -------------------------------------------------------------------------------- 1 | bag 2 | === 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | 7 | bag 8 | -------------------------------------------------------------------------------- /docs/source/developer/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /docs/source/developer/developer.rst: -------------------------------------------------------------------------------- 1 | Developer Guide 2 | =============== 3 | 4 | Nothing here yet... 5 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. BAG documentation master file, created by 2 | sphinx-quickstart on Fri May 27 15:45:44 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to BAG's documentation! 7 | =============================== 8 | 9 | Contents: 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | 14 | tutorial/tutorial 15 | overview/overview 16 | setup/setup 17 | developer/developer 18 | api/modules 19 | 20 | Indices and tables 21 | ================== 22 | 23 | * :ref:`genindex` 24 | * :ref:`modindex` 25 | * :ref:`search` 26 | 27 | -------------------------------------------------------------------------------- /docs/source/overview/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /docs/source/overview/design.rst: -------------------------------------------------------------------------------- 1 | Design Module 2 | ============= 3 | 4 | A design module is a Python class that generates new schematics. It computes all parameters needed to generate a 5 | schematic from user defined specifications. For example, a design module for an inverter needs to compute the width, 6 | length, and threshold flavor of the NMOS and PMOS to generate a new inverter schematic. The designer of this module can 7 | let the user specify these parameters directly, or alternatively compute them from higher level specifications, such as 8 | fanout, input capacitance, and leakage specs. 9 | 10 | To create a default design module for a schematic generator, create a :class:`~bag.BagProject` instance and call 11 | :meth:`~bag.BagProject.import_design_library` to import all schematic generators in a library from your CAD 12 | program into Python. The designer should then implement the three methods, :meth:`~bag.design.Module.design`, 13 | :meth:`~bag.design.Module.get_layout_params`, and :meth:`~bag.design.Module.get_layout_pin_mapping` (The latter two are 14 | optional if you do not use BAG to generate layout). Once you finish the design module definition, you can create new 15 | design module instances by calling :meth:`~bag.BagProject.create_design_module`. 16 | 17 | 18 | The following sections describe how each of these methods should be implemented. 19 | 20 | design() 21 | -------- 22 | 23 | This method computes all parameters needed to generate a schematic from user defined specifications. The input 24 | arguments should also be specified in this method. 25 | 26 | A design module can have multiple design methods, as long as they have difference names. For example, You can implement 27 | the ``design()`` method to compute parameters from high level specifications, and define a new method named 28 | ``design_override()`` that allows the user to assign parameter values directly for debugging purposes. 29 | 30 | To enable hierarchical design, design module has a dictionary, :attr:`~bag.design.Module.instances`, that 31 | maps children instance names to corresponding design modules, so you can simply call their 32 | :meth:`~bag.design.Module.design` methods to set their parameters. See :doc:`/tutorial/tutorial` for an simple example. 33 | 34 | If you need to modify the schematic structure (such as adding more inverter buffers), you should call the corresponding 35 | methods before calling :meth:`~bag.design.Module.design` methods of child instances, as those design module could be 36 | changed. The rest of this section explains how you modify the schematic. 37 | 38 | Pin Renaming 39 | ^^^^^^^^^^^^ 40 | 41 | Most of the time, you should not rename the pin of schematic. The only time you should rename the pin is when you have 42 | a variable bus pin where the number of bits in the bus can change with the design. In this case, call 43 | :meth:`~bag.design.Module.rename_pin` to change the number of bits in the bus. To connect/remove instances from 44 | the added/deleted bus pins, see :ref:`instance_connection_modification` 45 | 46 | Delete Instances 47 | ^^^^^^^^^^^^^^^^ 48 | 49 | Delete a child instance by calling :meth:`~bag.design.Module.delete_instance`. After 50 | this call, the corresponding value in :attr:`~bag.design.Module.instances` dictionary will become ``None``. 51 | 52 | .. note:: 53 | You don't have to delete 0-width or 0-finger transistors; BAG already handles that for you. 54 | 55 | Replace Instance Master 56 | ^^^^^^^^^^^^^^^^^^^^^^^ 57 | 58 | If you have two different designs of a child instance, and you want to swap between the two designs, you can call 59 | :meth:`~bag.design.Module.replace_instance_master` to change the instance master of a child. 60 | 61 | .. note:: 62 | You can replace instance masters only if the two instance masters have exactly the symbol, including pin names. 63 | 64 | .. _instance_connection_modification: 65 | 66 | Instance Connection Modification 67 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 68 | 69 | Call :meth:`~bag.design.Module.reconnect_instance_terminal` to change a child instance's connection. 70 | 71 | Arraying Child Instances 72 | ^^^^^^^^^^^^^^^^^^^^^^^^ 73 | 74 | Call :meth:`~bag.design.Module.array_instance` to array a child instance. After this call, 75 | :attr:`~bag.design.Module.instances` will map the child instance name to a list of design modules, one for each instance 76 | in the array. You can then iterate through this list and design each of the instances. They do not need to have the 77 | same parameter values. 78 | 79 | Restoring to Default 80 | ^^^^^^^^^^^^^^^^^^^^ 81 | 82 | If you are using the design module in a design iteration loop, or you're using BAG interactively through the Python 83 | console, and you want to restore a deleted/replaced/arrayed child instance to the default state, you can call 84 | :meth:`~bag.design.Module.restore_instance`. 85 | 86 | 87 | get_layout_params() 88 | ------------------- 89 | 90 | This method should return a dictionary from layout parameter names to their values. This dictionary is used to create 91 | a layout cell that will pass LVS against the generated schematic. 92 | 93 | get_layout_pin_mapping() 94 | ------------------------ 95 | 96 | This method should return a dictionary from layout pin names to schematic pin names. This method exists because a 97 | layout cell may not have the same pin names as the schematic. If a layout pin should be left un-exported, its 98 | corresponding value in the dictionary must be ``None``. 99 | 100 | This dictionary only need to list the layout pins that needs to be renamed. If no renaming is necessary, an empty 101 | dictionary can be returned. 102 | -------------------------------------------------------------------------------- /docs/source/overview/figures/bag_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucb-art/BAG_framework/daf4b0aaa72f056c7b3c90a402812a07dba9b4d7/docs/source/overview/figures/bag_flow.png -------------------------------------------------------------------------------- /docs/source/overview/figures/bag_prim_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucb-art/BAG_framework/daf4b0aaa72f056c7b3c90a402812a07dba9b4d7/docs/source/overview/figures/bag_prim_screenshot.png -------------------------------------------------------------------------------- /docs/source/overview/figures/gm_schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucb-art/BAG_framework/daf4b0aaa72f056c7b3c90a402812a07dba9b4d7/docs/source/overview/figures/gm_schematic.png -------------------------------------------------------------------------------- /docs/source/overview/figures/inv_chain_schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucb-art/BAG_framework/daf4b0aaa72f056c7b3c90a402812a07dba9b4d7/docs/source/overview/figures/inv_chain_schematic.png -------------------------------------------------------------------------------- /docs/source/overview/overview.rst: -------------------------------------------------------------------------------- 1 | Overview 2 | ======== 3 | 4 | .. figure:: ./figures/bag_flow.png 5 | :align: center 6 | :figclass: align-center 7 | 8 | BAG design flow diagram 9 | 10 | BAG is a Python-based circuit design platform that aims to automate analog circuit design, but at the same time give the 11 | user full visibility and control over every step in the design flow. 12 | 13 | The analog circuit design flow is generally as follows: 14 | 15 | #. Create a schematic generator of the circuit. 16 | #. Create a testbench generator to measure specifications and verify functionality. 17 | #. Create a layout generator if post-extraction verification is needed. 18 | #. Generate a schematic with given specifications. 19 | #. Generate a testbench that instantiates the generated schematic. 20 | #. Simulate the testbenches and post-process data to verify that the circuit meets specifications. 21 | #. Create the layout of your schematic and verify it's LVS/DRC clean. 22 | #. Repeat step 3 on post-extraction schematic. 23 | 24 | BAG 2.0 is designed so that any or all steps of the design flow can be performed in a Python script or console, thus 25 | enabling rapid design iteration and architecture exploration. 26 | 27 | To achieve its goal, BAG is divided into 4 components: schematic generators, layout generators, design modules, and 28 | testbench generators. These components are independent from one another, so the designer can pick and choose which steps 29 | in the design flow to automate. For example, the designer can simply use BAG to generate new schematics, and use his 30 | own CAD program for simulation and verification. Alternatively, The designer can provide an existing schematic to BAG 31 | and simply use it to automate the verification process. 32 | 33 | BAG interacts with an external CAD program or simulator to complete all the design and simulation tasks. BAG comes with 34 | Virtuoso and Ocean simulator support, but can be extended to other CAD programs or simulators. The rest of this 35 | document assumes you are using Virtuoso and running simulations in Ocean. 36 | 37 | Next we will describe each components of BAG in detail. 38 | 39 | .. toctree:: 40 | :maxdepth: 2 41 | 42 | schematic 43 | design 44 | testbench -------------------------------------------------------------------------------- /docs/source/overview/schematic.rst: -------------------------------------------------------------------------------- 1 | Schematic Generator 2 | =================== 3 | 4 | A schematic generator is a schematic in your CAD program that tells BAG all the information needed to create a design. 5 | BAG creates design modules from schematic generators, and BAG will copy and modify schematic generators to implement 6 | new designs. 7 | 8 | .. figure:: ./figures/gm_schematic.png 9 | :align: center 10 | :figclass: align-center 11 | 12 | An example schematic generator of a differential gm cell. 13 | 14 | A schematic generator needs to follow some rules to work with BAG: 15 | 16 | #. Instances in a schematic generator must be other schematic generators, or a cell in the ``BAG_prim`` library. 17 | #. BAG can array any instance in a schematic generator. That is, in the design implementation phase, BAG can 18 | copy/paste this instance any number of times, and modify the connections or parameters of any copy. This is useful 19 | in creating array structures, such as an inverter chain with variable number of stages, or a DAC with variable 20 | number of bits. 21 | 22 | However, if you need to array an instance, its ports must be connected to wire stubs, with net labels on each of the 23 | wire stubs. Also, there must be absolutely nothing to the right of the instance, since BAG will array the instance 24 | by copying-and-pasting to the right. An example of an inverter buffer chain schematic generator is shown below. 25 | 26 | .. figure:: ./figures/inv_chain_schematic.png 27 | :align: center 28 | :figclass: align-center 29 | 30 | An example schematic generator of an inverter buffer chain. Ports connected by wire stubs, nothing on the right. 31 | 32 | #. BAG can replace the instance master of any instance. The primary use of this is to allow the designer to change 33 | transistor threshold values, but this could be used for other schematic generators if implemented. Whenever you 34 | switch the instance master of an instance, the symbol of the new instance must exactly match the old instance, 35 | including the port names. 36 | #. Although not required, it is good practice to fill in default parameter values for all instances from the 37 | ``BAG_prim`` library. This makes it so that you can simulate a schematic generator in a normal testbench, and make 38 | debugging easier. 39 | 40 | -------------------------------------------------------------------------------- /docs/source/overview/testbench.rst: -------------------------------------------------------------------------------- 1 | Testbench Generator 2 | =================== 3 | 4 | A testbench generator is just a normal testbench with schematic and adexl view. BAG will simply copy the schematic and 5 | adexl view, and replace the device under test with the new generated schematic. There are only 3 restrictions to the 6 | testbench: 7 | 8 | #. All device-under-test's (DUTs) in the testbench must have an instance name starting with ``XDUT``. This is to inform BAG 9 | which child instances should be replaced. 10 | #. The testbench must be configured to simulate with ADE-XL. This is to make parametric/corner sweeps and monte carlo 11 | easier. 12 | #. You should not define any process corners in the ADE-XL state, as BAG will load them for you. This makes it 13 | possible to use the same testbench generator across different technologies. 14 | 15 | To verify a new design, call :meth:`~bag.BagProject.create_testbench` and specify the testbench generator library/cell, 16 | DUT library/cell, and the library to create the new testbench in. BAG will create a :class:`~bag.core.Testbench` object 17 | to represent this testbench. You can then call its methods to set the parameters, process corners, or enable parametric 18 | sweeps. When you're done, call :meth:`~bag.core.Testbench.update_testbench` to commit the changes to Virtuoso. If you 19 | do not wish to run simulation in BAG, you can then open this testbench in Virtuoso and simulate it there. 20 | 21 | If you want to start simulation from BAG and load simulation data, you need to call 22 | :meth:`~bag.core.Testbench.add_output` method to specify which outputs to record and send back to Python. Output 23 | expression is a Virtuoso calculator expression. Then, call :meth:`~bag.core.Testbench.run_simulation` to start a 24 | simulation run. During the simulation, you can press ``Ctrl-C`` anytime to abort simulation. When the simulation 25 | finish, the result directory will be saved to the attribute :attr:`~bag.core.Testbench.save_dir`, and you can call 26 | :func:`bag.data.load_sim_results` to load the result in Python. See :doc:`/tutorial/tutorial` for an example. 27 | 28 | Since BAG uses the ADE-XL interface to run simulation, all simulation runs will be recorded in ADE-XL's history tab, so 29 | you can plot them in Virtuoso later for debugging purposes. By default, all simulation runs from BAG has the ``BagSim`` 30 | history tag, but you can also specify your own tag name when you call :meth:`~bag.core.Testbench.run_simulation`. Read 31 | ADE-XL documentation if you want to know more about ADE-XL's history feature. 32 | -------------------------------------------------------------------------------- /docs/source/setup/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /docs/source/setup/bag_config/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /docs/source/setup/bag_config/bag_config.rst: -------------------------------------------------------------------------------- 1 | BAG Configuration File 2 | ====================== 3 | 4 | BAG configuration file is written in YAML format. This document describes each setting. 5 | BAG configuration file may use environment variable to specify values of any entries. 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | socket/socket 11 | database/database 12 | simulation/simulation 13 | misc 14 | -------------------------------------------------------------------------------- /docs/source/setup/bag_config/database/database.rst: -------------------------------------------------------------------------------- 1 | database 2 | ======== 3 | 4 | This entry defines all settings related to Virtuoso. 5 | 6 | 7 | data.class 8 | ---------- 9 | 10 | The Python class that handles database interaction. This entry is mainly to support non-Virtuoso CAD programs. If you 11 | use Virtuoso, the value must be ``bag.interface.skill.SkillInterface``. 12 | 13 | database.schematic 14 | ------------------ 15 | 16 | This entry contains all settings needed to read/generate schematics. 17 | 18 | .. _sch_tech_lib: 19 | 20 | database.schematic.tech_lib 21 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 22 | 23 | Technology library. When BAG create new libraries, they will be attached to this technology library. Usually this is 24 | the PDK library provided by the foundry. 25 | 26 | .. _sch_sympin: 27 | 28 | database.schematic.sympin 29 | ^^^^^^^^^^^^^^^^^^^^^^^^^ 30 | 31 | Instance master of symbol pins. This is a list of library/cell/view names. Most of the time this should be 32 | ``["basic", "sympin", "symbolNN"]``. 33 | 34 | .. _sch_ipin: 35 | 36 | database.schematic.ipin 37 | ^^^^^^^^^^^^^^^^^^^^^^^ 38 | 39 | Instance master of input pins in schematic. This is a list of library/cell/view names. Most of the time this should be 40 | ``["basic", "ipin", "symbol"]``. 41 | 42 | .. _sch_opin: 43 | 44 | database.schematic.opin 45 | ^^^^^^^^^^^^^^^^^^^^^^^ 46 | 47 | Instance master of output pins in schematic. This is a list of library/cell/view names. Most of the time this should be 48 | ``["basic", "opin", "symbol"]``. 49 | 50 | .. _sch_iopin: 51 | 52 | database.schematic.iopin 53 | ^^^^^^^^^^^^^^^^^^^^^^^^ 54 | 55 | Instance master of inout pins in schematic. This is a list of library/cell/view names. Most of the time this should be 56 | ``["basic", "iopin", "symbolr"]``. 57 | 58 | .. _sch_simulators: 59 | 60 | database.schematic.simulators 61 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 62 | 63 | A list of simulators where the ``termOrder`` CDF field should be defined. 64 | 65 | When Virtuoso convert schematics to netlists, it uses the ``termOrder`` CDF field to decide how to order the pin names 66 | in the netlist. This entry makes BAG update the ``termOrder`` field correctly whenever pins are changed. 67 | 68 | Most of the time, this should be ``["auLvs", "auCdl", "spectre", "hspiceD"]``. 69 | 70 | .. _sch_exclude: 71 | 72 | database.schematic.exclude_libraries 73 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 74 | 75 | A list of libraries to exclude when importing schematic generators to BAG. Most of the time, this should be 76 | ``["analogLib", "basic", {PDK}]``, where ``{PDK}`` is the PDK library. 77 | 78 | database.testbench 79 | ------------------ 80 | 81 | This entry contains all settings needed to create new testbenches. 82 | 83 | .. _tb_config_libs: 84 | 85 | database.testbench.config_libs 86 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 87 | 88 | A string of config view global libries, separated by spaces. Used to generate config view. 89 | 90 | database.testbench.config_views 91 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 92 | 93 | A string of config view global cellviews, separated by spaces. Used to generate config view. Most of the time this 94 | should be ``"spectre calibre schematic veriloga"``. 95 | 96 | database.testbench.config_stops 97 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 98 | 99 | A string of config view global stop cellviews, separated by spaces. Used to generate config view. Most of the time this 100 | should be ``"spectre veriloga"``. 101 | 102 | .. _sim_env_file: 103 | 104 | database.testbench.env_file 105 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 106 | 107 | The simulation environment file name. A simulation environment is a combination of process corner and temperature. 108 | For example, if you simulate your circuit at TT corner with a temperature of 50 degrees Celsius, you may say the 109 | simulation environment is TT_50. A simulation environment file contains all simulation environments you want to define 110 | when BAG creates a new testbench. This file can be generated by exporting corner setup from an ADE-XL view. 111 | 112 | database.testbench.def_files 113 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 114 | 115 | A list of ADE/spectre definition files to include. Sometimes, a process technology uses definition files 116 | in addition to model files. If so, you can specify definition files to include here as a list of strings. 117 | Use an empty list (``[]``) if no definition file is needed. 118 | 119 | database.testbench.default_env 120 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 121 | 122 | The default simulation environment name. See :ref:`sim_env_file`. 123 | 124 | database.checker 125 | ---------------- 126 | 127 | This entry contains all settings needed to run LVS/RCX from BAG. 128 | 129 | database.checker.checker_cls 130 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 131 | 132 | The Python class that handles LVS/RCX. If you use Calibre with Virtuoso for LVS/RCX, the value must be 133 | ``bag.verification.calibre.Calibre``. 134 | 135 | .. _lvs_rundir: 136 | 137 | database.checker.lvs_run_dir 138 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 139 | 140 | LVS run directory. 141 | 142 | .. _rcx_rundir: 143 | 144 | database.checker.rcx_run_dir 145 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 146 | 147 | RCX run directory 148 | 149 | .. _lvs_runset: 150 | 151 | database.checker.lvs_runset 152 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 153 | 154 | LVS runset. 155 | 156 | .. _rcx_runset: 157 | 158 | database.checker.rcx_runset 159 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 160 | 161 | RCX runset. 162 | 163 | database.checker.source_added_file 164 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 165 | 166 | Location of the source.added file for Calibre LVS. If this entry is not defined, BAG 167 | defaults to ``$DK/Calibre/lvs/source.added``. 168 | 169 | database.checker.rcx_mode 170 | ^^^^^^^^^^^^^^^^^^^^^^^^^ 171 | 172 | Whether to use Calibre PEX or Calibre XACT3D flow to perform parasitic extraction. The 173 | value should be either ``pex`` or ``xact``. If this entry is not defined, BAG defaults to 174 | ``pex``. 175 | 176 | database.checker.xact_rules 177 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 178 | 179 | Location of the Calibre XACT3D rules file. This entry must be defined if using Calibre XACT3D flow. 180 | 181 | 182 | database.calibreview 183 | -------------------- 184 | 185 | This entry contains all settings needed to generate calibre view after RCX. 186 | 187 | .. _calibre_cellmap: 188 | 189 | database.calibreview.cell_map 190 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 191 | 192 | The calibre view cellmap file. 193 | 194 | database.calibreview.view_name 195 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 196 | 197 | view name for calibre view. Usually ``calibre``. 198 | -------------------------------------------------------------------------------- /docs/source/setup/bag_config/misc.rst: -------------------------------------------------------------------------------- 1 | class 2 | ===== 3 | 4 | The subclass of :ref: 5 | 6 | 7 | .. _bag_lib_defs: 8 | 9 | lib_defs 10 | ======== 11 | 12 | Location of the BAG design module libraries definition file. 13 | 14 | The BAG libraries definition file is similar to the ``cds.lib`` file for Virtuoso, where it defines every design module 15 | library and its location. This file makes it easy to share design module libraries made by different designers. 16 | 17 | Each line in the file contains two entries, separated by spaces. The first entry is the name of the design module 18 | library, and the second entry is the location of the design module library. Environment variables may be used in this 19 | file. 20 | 21 | .. _bag_new_lib_path: 22 | 23 | new_lib_path 24 | ============ 25 | 26 | Directory to put new generated design module libraries. 27 | 28 | When you import a new schematic generator library, BAG will create a corresponding Python design module library and 29 | define this library in the library definition file (see :ref:`bag_lib_defs`). This field tells BAG where new design 30 | module libraries should be created. 31 | -------------------------------------------------------------------------------- /docs/source/setup/bag_config/simulation/simulation.rst: -------------------------------------------------------------------------------- 1 | simulation 2 | ========== 3 | 4 | This entry defines all settings related to Ocean. 5 | 6 | simulation.class 7 | ---------------- 8 | 9 | The Python class that handles simulator interaction. This entry is mainly to support non-Ocean simulators. If you 10 | use Ocean, the value must be ``bag.interface.ocean.OceanInterface``. 11 | 12 | simulation.prompt 13 | ----------------- 14 | 15 | The ocean prompt string. 16 | 17 | .. _sim_init_file: 18 | 19 | simulation.init_file 20 | -------------------- 21 | 22 | This file will be loaded when Ocean first started up. This allows you to configure the Ocean simulator. If you do not want to load an initialization file, set this field to an empty string (``""``). 23 | 24 | simulation.view 25 | --------------- 26 | 27 | Testbench view name. Usually ``adexl``. 28 | 29 | simulation.state 30 | ---------------- 31 | 32 | ADE-XL setup state name. When you run simulations from BAG, the simulation configuration will be saved to this setup 33 | state. 34 | 35 | simulation.update_timeout_ms 36 | ---------------------------- 37 | 38 | If simulation takes a lone time, BAG will print out a message at this time interval (in milliseconds) so you can know 39 | if BAG is still running. 40 | 41 | simulation.kwargs 42 | ----------------- 43 | 44 | pexpect keyword arguments dictionary used to start the simulation. When BAG server receive a simulation request, it 45 | will run Ocean in a subprocess using Python pexpect module. This entry allows you to control how pexpect starts the 46 | Ocean subprocess. Refer to pexpect documentation for more information. 47 | 48 | job_options 49 | ----------- 50 | 51 | A dictionary of job options for ADE-XL. This entry controls whether ADE-XL runs simulations remotely or locally, and how many jobs it launches for a simulation run. Refer to ADE-XL documentation for available options. 52 | -------------------------------------------------------------------------------- /docs/source/setup/bag_config/socket/socket.rst: -------------------------------------------------------------------------------- 1 | socket 2 | ====== 3 | 4 | This entry defines socket settings for BAG to communicate with Virtuoso. 5 | 6 | socket.host 7 | ----------- 8 | 9 | The host of the BAG server socket, i.e. the machine running the Virtuoso program. usually ``localhost``. 10 | 11 | socket.port_file 12 | ---------------- 13 | 14 | File containing socket port number for BAG server. When Virtuoso starts the BAG server process, it finds a open port and bind the 15 | server to this port. It then creates a file with name in ``$BAG_WORK_DIR`` directory, and write the port number to this 16 | file. 17 | 18 | socket.sim_port_file 19 | -------------------- 20 | 21 | File containing socket port number for simulation server. When the simulation server starts, it finds a open port and bind the 22 | server to this port. It then creates a file with name in ``$BAG_WORK_DIR`` directory, and write the port number to this 23 | file. 24 | 25 | 26 | socket.log_file 27 | --------------- 28 | 29 | Socket communication debugging log file. All messages sent or received by BAG will be recorded in this log. 30 | 31 | socket.pipeline 32 | --------------- 33 | 34 | number of messages allowed in the ZMQ pipeline. Usually you don't have to change this. 35 | -------------------------------------------------------------------------------- /docs/source/setup/config_summary.rst: -------------------------------------------------------------------------------- 1 | Configuration Files Summary 2 | =========================== 3 | 4 | Although BAG has many configuration settings, most of them do not need to be changed. This file summarizes which 5 | settings you should modify under various use cases. 6 | 7 | Starting New Project 8 | -------------------- 9 | 10 | For every new project, it is a good practice to keep a set of global configuration files to make sure everyone working 11 | on the project is simulating the same corners, running LVS and extraction with the same settings, and so on. In this 12 | case, you should change the following fields to point to the global configuration files: 13 | 14 | * :ref:`sim_env_file` 15 | * :ref:`lvs_runset` 16 | * :ref:`rcx_runset` 17 | * :ref:`calibre_cellmap` 18 | 19 | Customizing Virtuoso Setups 20 | --------------------------- 21 | 22 | If you changed your Virtuoso setup (configuration files, working directory, etc.), double check the following fields to 23 | see if they need to be modified: 24 | 25 | * :ref:`lvs_rundir` 26 | * :ref:`rcx_rundir` 27 | * :ref:`sim_init_file` 28 | 29 | Python Design Module Customization 30 | ---------------------------------- 31 | 32 | The following fields control how BAG 2.0 finds design modules, and also where it puts new imported modules: 33 | 34 | * :ref:`bag_lib_defs` 35 | * :ref:`bag_new_lib_path` 36 | 37 | .. _change_pdk: 38 | 39 | Changing Process Technology 40 | --------------------------- 41 | 42 | If you want to change the process technology, double check the following fields: 43 | 44 | * :ref:`sch_tech_lib` 45 | * :ref:`sch_exclude` 46 | * :ref:`tb_config_libs` 47 | * :ref:`tech_config_path` 48 | 49 | The following fields probably won't change, but if something doesn't work it's worth to double check: 50 | 51 | * :ref:`sch_sympin` 52 | * :ref:`sch_ipin` 53 | * :ref:`sch_opin` 54 | * :ref:`sch_iopin` 55 | * :ref:`sch_simulators` 56 | 57 | -------------------------------------------------------------------------------- /docs/source/setup/install_python.rst: -------------------------------------------------------------------------------- 1 | Installing Python for BAG 2 | ========================== 3 | 4 | This section describes how to install Python for running BAG. 5 | 6 | Installation Requirements 7 | ------------------------- 8 | 9 | BAG is compatible with Python 3.5+ (Python 2.7+ is theoretically supported but untested), so you will need to have 10 | Python 3.5+ installed. For Linux/Unix systems, it is recommended to install a separate Python distribution from 11 | the system Python. 12 | 13 | BAG requires multiple Python packages, some of which requires compiling C++/C/Fortran extensions. Therefore, it is 14 | strongly recommended to download `Anaconda Python `_, which provides a Python 15 | distribution with most of the packages preinstalled. Otherwise, please refer to documentation for each required 16 | package for how to install/build from source. 17 | 18 | Required Packages 19 | ----------------- 20 | In addition to the default packages that come with Anaconda (numpy, scipy, etc.), you'll need the following additional 21 | packages: 22 | 23 | - `subprocess32 `_ (Python 2 only) 24 | 25 | This package is a backport of Python 3.2's subprocess module to Python 2. It is installable from ``pip``. 26 | 27 | - `sqlitedict `_ 28 | 29 | This is a dependency of OpenMDAO. It is installable from ``pip``. 30 | 31 | - `OpenMDAO `_ 32 | 33 | This is a flexible optimization framework in Python developed by NASA. It is installable from ``pip``. 34 | 35 | - `mpich2 `_ (optional) 36 | 37 | This is the Message Passing Interface (MPI) library. OpenMDAO and Pyoptsparse can optionally use this library 38 | for parallel computing. You can install this package with: 39 | 40 | .. code-block:: bash 41 | 42 | > conda install mpich2 43 | 44 | - `mpi4py `_ (optional) 45 | 46 | This is the Python wrapper of ``mpich2``. You can install this package with: 47 | 48 | .. code-block:: bash 49 | 50 | > conda install mpi4py 51 | 52 | - `ipopt `__ (optional) 53 | 54 | `Ipopt `__ is a free software package for large-scale nonlinear optimization. 55 | This can be used to replace the default optimization solver that comes with scipy. You can install this package with: 56 | 57 | .. code-block:: bash 58 | 59 | > conda install --channel pkerichang ipopt 60 | 61 | - `pyoptsparse `_ (optional) 62 | 63 | ``pyoptsparse`` is a python package that contains a collection of optmization solvers, including a Python wrapper 64 | around ``Ipopt``. You can install this package with: 65 | 66 | .. code-block:: bash 67 | 68 | > conda install --channel pkerichang pyoptsparse 69 | -------------------------------------------------------------------------------- /docs/source/setup/new_pdk.rst: -------------------------------------------------------------------------------- 1 | Setting up New PDK 2 | ================== 3 | 4 | This section describes how to get BAG 2.0 to work with a new PDK. 5 | 6 | #. Create a new technology configuration file for this PDK. See :doc:`tech_config/tech_config` for a description of 7 | the technology configuration file format. 8 | 9 | #. Create a new BAG configuration file for this PDK. You can simply copy an existing configuration, then change the 10 | fields listed in :ref:`change_pdk`. 11 | 12 | #. Create a new ``BAG_prim`` library for this PDK. The easiest way to do this is to copy an existing ``BAG_prim`` 13 | library, then change the underlying instances to be instances from the new PDK. You should use the **pPar** command 14 | in Virtuoso to pass CDF parameters from ``BAG_prim`` instances to PDK instances. 15 | 16 | #. Change your cds.lib to refer to the new ``BAG_prim`` library. 17 | 18 | #. To avoid everyone having their own python design modules for BAG primitive, you should generated a global design module 19 | library for BAG primitives, then ask every user to include this global library in their ``bag_libs.def`` file. To 20 | do so, setup a BAG workspace and execute the following commands: 21 | 22 | .. code-block:: python 23 | 24 | import bag 25 | prj = bag.BagProject() 26 | prj.import_design_library('BAG_prim') 27 | 28 | now copy the generate design library to a global location. 29 | -------------------------------------------------------------------------------- /docs/source/setup/pyoptsparse.rst: -------------------------------------------------------------------------------- 1 | Building Pyoptsparse 2 | ==================== 3 | 4 | To be written. 5 | -------------------------------------------------------------------------------- /docs/source/setup/setup.rst: -------------------------------------------------------------------------------- 1 | BAG Setup Procedure 2 | =================== 3 | 4 | This document describes how to install Python for BAG and the various configuration settings. Since a lot of the 5 | configuration depends on the external CAD program and simulator, this document assumes you are using Virtuoso and 6 | Ocean (with ADEXL) for schematic design and simulation, respectively. 7 | 8 | .. toctree:: 9 | :maxdepth: 2 10 | 11 | install_python 12 | pyoptsparse 13 | config_summary 14 | bag_config/bag_config 15 | tech_config/tech_config 16 | new_pdk 17 | -------------------------------------------------------------------------------- /docs/source/setup/tech_config/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /docs/source/setup/tech_config/layout/layout.rst: -------------------------------------------------------------------------------- 1 | layout 2 | ====== 3 | 4 | This entry defines all layout specific settings. 5 | 6 | 7 | layout.em_temp 8 | -------------- 9 | 10 | The temperature used to calculate electro-migration specs. The temperature should 11 | be specified in degrees Celsius. 12 | -------------------------------------------------------------------------------- /docs/source/setup/tech_config/misc.rst: -------------------------------------------------------------------------------- 1 | .. _tech_config_path: 2 | 3 | class 4 | ===== 5 | 6 | The subclass of :class:`bag.layout.core.TechInfo` for this process technology. 7 | If this entry is not defined, a default dummy :class:`~bag.layout.core.TechInfo` 8 | instance will be created for schematic-only design flow. 9 | -------------------------------------------------------------------------------- /docs/source/setup/tech_config/mos/mos.rst: -------------------------------------------------------------------------------- 1 | mos 2 | === 3 | 4 | This entry defines all MOS transistor settings. 5 | 6 | 7 | mos.width_resolution 8 | -------------------- 9 | 10 | The transistor width minimum resolution, in meters or number of fins in finfet technology. 11 | 12 | mos.length_resolution 13 | --------------------- 14 | 15 | The transistor length minimum resolution, in meters. 16 | 17 | mos.mos_char_root 18 | ----------------- 19 | 20 | The default transistor characterization data directory. 21 | -------------------------------------------------------------------------------- /docs/source/setup/tech_config/tech_config.rst: -------------------------------------------------------------------------------- 1 | Technology Configuration File 2 | ============================= 3 | 4 | Technology configuration file is written in YAML format. This document describes each setting. 5 | Technology configuration file may use environment variable to specify values of any entries. 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | misc 11 | mos/mos 12 | layout/layout 13 | -------------------------------------------------------------------------------- /docs/source/tutorial/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /docs/source/tutorial/figures/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /docs/source/tutorial/figures/bag_server_start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucb-art/BAG_framework/daf4b0aaa72f056c7b3c90a402812a07dba9b4d7/docs/source/tutorial/figures/bag_server_start.png -------------------------------------------------------------------------------- /docs/source/tutorial/figures/bag_sim_server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucb-art/BAG_framework/daf4b0aaa72f056c7b3c90a402812a07dba9b4d7/docs/source/tutorial/figures/bag_sim_server.png -------------------------------------------------------------------------------- /docs/source/tutorial/figures/gm_schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucb-art/BAG_framework/daf4b0aaa72f056c7b3c90a402812a07dba9b4d7/docs/source/tutorial/figures/gm_schematic.png -------------------------------------------------------------------------------- /docs/source/tutorial/figures/gm_testbench.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucb-art/BAG_framework/daf4b0aaa72f056c7b3c90a402812a07dba9b4d7/docs/source/tutorial/figures/gm_testbench.png -------------------------------------------------------------------------------- /docs/source/tutorial/figures/testbench_dut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucb-art/BAG_framework/daf4b0aaa72f056c7b3c90a402812a07dba9b4d7/docs/source/tutorial/figures/testbench_dut.png -------------------------------------------------------------------------------- /docs/source/tutorial/figures/tran_prop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucb-art/BAG_framework/daf4b0aaa72f056c7b3c90a402812a07dba9b4d7/docs/source/tutorial/figures/tran_prop.png -------------------------------------------------------------------------------- /docs/source/tutorial/figures/tran_schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucb-art/BAG_framework/daf4b0aaa72f056c7b3c90a402812a07dba9b4d7/docs/source/tutorial/figures/tran_schematic.png -------------------------------------------------------------------------------- /docs/source/tutorial/tutorial.rst: -------------------------------------------------------------------------------- 1 | Tutorial 2 | ======== 3 | 4 | This section contains several simple tutorials for you to get an idea of the BAG workflow. 5 | 6 | In these tutorials, we will be using :program:`git` extensively. git allows you to copy a working setup, 7 | and it also allows you to checkout and use other people's design while they can work on adding future 8 | improvements. To learn git, you can read the documentations here_, or alternatively you can just 9 | google git commands to learn more about it while working through the tutorial. 10 | 11 | .. _here: https://git-scm.com/doc 12 | 13 | .. toctree:: 14 | :maxdepth: 2 15 | 16 | schematic 17 | collaboration -------------------------------------------------------------------------------- /run_scripts/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /run_scripts/clean_cds_lib.py: -------------------------------------------------------------------------------- 1 | """ 2 | This script removes the '#Removed by ddDeleteObj' items in cds.lib. 3 | It is also capable of taking a list of patterns as input and delete the generated libraries that 4 | match that pattern in glob style. 5 | """ 6 | 7 | from argparse import Namespace 8 | import argparse 9 | import re 10 | import os 11 | import shutil 12 | 13 | from pathlib import Path 14 | from bag.io.file import read_yaml_env, readlines_iter, write_file 15 | 16 | 17 | def arg_parse() -> Namespace: 18 | 19 | parser = argparse.ArgumentParser() 20 | parser.add_argument('-rm', '--rm_patterns', nargs='+', dest='patterns', default=[], 21 | help='A list of patterns to be removed from cadence library, the pattern ' 22 | 'should be the name of the library in glob style') 23 | 24 | args = parser.parse_args() 25 | return args 26 | 27 | 28 | def run_main(args: Namespace): 29 | bag_workspace_dir = Path(os.environ['BAG_WORK_DIR']) 30 | if 'BAG_CONFIG_PATH' not in os.environ: 31 | raise Exception('BAG_CONFIG_PATH not defined.') 32 | bag_config_path = os.environ['BAG_CONFIG_PATH'] 33 | bag_config = read_yaml_env(bag_config_path) 34 | 35 | gen_libs_path = Path(bag_config['database']['default_lib_path']) 36 | if not gen_libs_path.exists(): 37 | print(f'path {str(gen_libs_path)} does not exist') 38 | 39 | cds_lib_path = bag_workspace_dir / 'cds.lib' 40 | if not cds_lib_path.exists(): 41 | print(f'path {str(cds_lib_path)} does not exist') 42 | return 43 | 44 | cds_patterns = ['#Removed by ddDeleteObj'] + [f'DEFINE {p}' for p in args.patterns] 45 | 46 | # clean cds.lib 47 | cds_lib_lines_iter = readlines_iter(str(cds_lib_path)) 48 | 49 | new_cds_lib_content = [] 50 | for line in cds_lib_lines_iter: 51 | found = False 52 | for p in cds_patterns: 53 | if re.match(p, line): 54 | found = True 55 | break 56 | if not found: 57 | new_cds_lib_content.append(line) 58 | 59 | write_file(str(cds_lib_path), ''.join(new_cds_lib_content)) 60 | 61 | # clean gen_libs library names that match the pattern in args 62 | for p in args.patterns: 63 | for dir in gen_libs_path.glob(f'{p}*'): 64 | if dir.is_dir(): 65 | shutil.rmtree(dir) 66 | else: 67 | print(f'path {str(dir)} is not a directory') 68 | 69 | 70 | if __name__ == '__main__': 71 | args = arg_parse() 72 | run_main(args) 73 | -------------------------------------------------------------------------------- /run_scripts/compile_verilog.il: -------------------------------------------------------------------------------- 1 | 2 | procedure( compile_netlist_views(fname "t") 3 | let( (p line info_list lib cell view obj cv) 4 | unless( p = infile(fname) 5 | error("Cannot open file %s" fname) 6 | ) 7 | while( gets(line p) 8 | info_list = parseString(line) 9 | lib = car(info_list) 10 | cell = cadr(info_list) 11 | view = caddr(info_list) 12 | obj = ddGetObj(lib cell view "verilog.sv" nil "a") 13 | cv = dbOpenCellViewByType(lib cell view "netlist" "ac") 14 | dbSetConnCurrent(cv) 15 | dbSave(cv) 16 | dbClose(cv) 17 | ) 18 | close(p) 19 | ) 20 | ) 21 | 22 | compile_netlist_views("verilog_cell_list.txt") 23 | -------------------------------------------------------------------------------- /run_scripts/gen_cell.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from argparse import Namespace 3 | from pathlib import Path 4 | 5 | from bag.io.file import Pickle, Yaml 6 | from bag.core import BagProject 7 | 8 | io_cls_dict = { 9 | 'pickle': Pickle, 10 | 'yaml': Yaml, 11 | } 12 | 13 | 14 | def parse_args() -> Namespace: 15 | parser = argparse.ArgumentParser() 16 | parser.add_argument('specs_fname', help='specs yaml file') 17 | parser.add_argument('--no-sch', dest='gen_sch', action='store_false', 18 | default=True, help='skip schematic generation') 19 | parser.add_argument('--no-lay', dest='gen_lay', action='store_false', 20 | default=True, help='skip layout generation') 21 | parser.add_argument('-v', '--lvs', action='store_true', default=False, 22 | help='run lvs') 23 | parser.add_argument('-x', '--rcx', action='store_true', default=False, 24 | help='run rcx') 25 | parser.add_argument('--use-cache', dest='use_cache', action='store_true', 26 | default=False, 27 | help='uses the cache in cache_dir') 28 | parser.add_argument('--save-cache', dest='save_cache', action='store_true', 29 | default=False, 30 | help='updates design database stored in cache_dir') 31 | parser.add_argument('--pre', dest='prefix', default='', 32 | help='prefix used to generate all the cells') 33 | parser.add_argument('--suf', dest='suffix', default='', 34 | help='suffix used to generate all the cells') 35 | parser.add_argument('--format', default='yaml', 36 | help='format of spec file (yaml, json, pickle)') 37 | parser.add_argument('-dump', '--dump', default='', 38 | help='If given will dump output of script into that ' 39 | 'file according to the format specified') 40 | args = parser.parse_args() 41 | return args 42 | 43 | 44 | def run_main(prj: BagProject, args: Namespace): 45 | specs_fname = Path(args.specs_fname) 46 | io_cls = io_cls_dict[args.format] 47 | specs = io_cls.load(str(specs_fname)) 48 | 49 | results = prj.generate_cell(specs=specs, 50 | gen_lay=args.gen_lay, 51 | gen_sch=args.gen_sch, 52 | run_lvs=args.lvs, 53 | run_rcx=args.rcx, 54 | use_cybagoa=True, 55 | use_cache=args.use_cache, 56 | save_cache=args.save_cache, 57 | prefix=args.prefix, 58 | suffix=args.suffix) 59 | 60 | if results is not None and args.dump: 61 | out_tmp_file = Path(args.dump) 62 | io_cls.save(results, out_tmp_file) 63 | 64 | 65 | if __name__ == '__main__': 66 | 67 | args = parse_args() 68 | local_dict = locals() 69 | bprj = local_dict.get('bprj', BagProject()) 70 | run_main(bprj, args) 71 | 72 | -------------------------------------------------------------------------------- /run_scripts/generate_verilog.py: -------------------------------------------------------------------------------- 1 | 2 | import os 3 | 4 | import yaml 5 | from jinja2 import Environment, FileSystemLoader 6 | 7 | 8 | def run_main(): 9 | verilog_dir = 'verilog_models' 10 | cell_map_fname = 'verilog_cell_map.yaml' 11 | skill_read_fname = 'verilog_cell_list.txt' 12 | lib_name = 'AAAMODEL_QDR_HYBRID3' 13 | lib_loc = 'gen_libs' 14 | view_name = 'systemVerilog' 15 | model_fname = 'verilog.sv' 16 | 17 | with open(cell_map_fname, 'r') as f: 18 | cell_map = yaml.load(f) 19 | 20 | jinja_env = Environment(loader=FileSystemLoader(verilog_dir)) 21 | 22 | with open(skill_read_fname, 'w') as g: 23 | for cell_name, fname in cell_map.items(): 24 | root_dir = os.path.join(lib_loc, lib_name, cell_name, view_name) 25 | os.makedirs(root_dir, exist_ok=True) 26 | 27 | content = jinja_env.get_template(fname).render(cell_name=cell_name) 28 | 29 | with open(os.path.join(root_dir, model_fname), 'w') as f: 30 | f.write(content) 31 | 32 | g.write('%s %s %s\n' % (lib_name, cell_name, view_name)) 33 | 34 | 35 | if __name__ == '__main__': 36 | run_main() 37 | -------------------------------------------------------------------------------- /run_scripts/meas_cell.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from argparse import Namespace 3 | from pathlib import Path 4 | import pdb 5 | 6 | from bag.io.file import Pickle, Yaml 7 | from bag.core import BagProject 8 | 9 | io_cls_dict = { 10 | 'pickle': Pickle, 11 | 'yaml': Yaml, 12 | } 13 | 14 | 15 | def parse_args() -> Namespace: 16 | parser = argparse.ArgumentParser() 17 | parser.add_argument('specs_fname', help='specs yaml file') 18 | parser.add_argument('--no-cell', dest='gen_cell', action='store_false', 19 | default=True, help='skip cell generation') 20 | parser.add_argument('--no-wrapper', dest='gen_wrapper', action='store_false', 21 | default=True, help='skip wrapper generation') 22 | parser.add_argument('--no-tb', dest='gen_tb', action='store_false', 23 | default=True, help='skip tb generation') 24 | parser.add_argument('--load', dest='load_results', action='store_true', 25 | default=False, help='skip simulation, just load the results') 26 | parser.add_argument('-x', '--extract', dest='extract', action='store_true', 27 | default=False, help='do extracted simulation') 28 | parser.add_argument('--no-sim', dest='run_sim', action='store_false', 29 | default=True, help='run simulation, --load has a priority over this') 30 | parser.add_argument('--format', default='yaml', 31 | help='format of spec file (yaml, json, pickle)') 32 | parser.add_argument('-dump', '--dump', default='', help='output will be dumped to this path, ' 33 | 'according to the format specified') 34 | parser.add_argument('--pause', default=False, action='store_true', 35 | help='True to pause using pdb.set_trace() after simulation is done') 36 | args = parser.parse_args() 37 | return args 38 | 39 | 40 | def run_main(prj: BagProject, args: Namespace): 41 | specs_fname = Path(args.specs_fname) 42 | io_cls = io_cls_dict[args.format] 43 | specs = io_cls.load(str(specs_fname)) 44 | 45 | results = prj.measure_cell(specs=specs, 46 | gen_cell=args.gen_cell, 47 | gen_wrapper=args.gen_wrapper, 48 | gen_tb=args.gen_tb, 49 | load_results=args.load_results, 50 | extract=args.extract, 51 | run_sims=args.run_sim) 52 | if args.pause: 53 | pdb.set_trace() 54 | 55 | if results is not None and args.dump: 56 | out_tmp_file = Path(args.dump) 57 | io_cls.save(results, out_tmp_file) 58 | 59 | 60 | if __name__ == '__main__': 61 | 62 | args = parse_args() 63 | local_dict = locals() 64 | bprj = local_dict.get('bprj', BagProject()) 65 | run_main(bprj, args) -------------------------------------------------------------------------------- /run_scripts/run_bag.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source .bashrc_pypath 4 | 5 | exec ${BAG_PYTHON} $@ 6 | -------------------------------------------------------------------------------- /run_scripts/setup_submodules.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # crazy black magic from: 4 | # https://unix.stackexchange.com/questions/20880/how-can-i-use-environment-variables-in-my-shebang 5 | # this block of code is valid in both bash and python. 6 | # this means if this script is run under bash, it'll 7 | # call this script again using BAG_PYTHON. If 8 | # this script is run under Python, this block of code 9 | # effectively does nothing. 10 | if "true" : '''\' 11 | then 12 | if [[ $BAG_PYTHON ]]; then 13 | exec ${BAG_PYTHON} "$0" "$@" 14 | else 15 | echo "BAG_PYTHON environment variable is not set" 16 | fi 17 | exit 127 18 | fi 19 | ''' 20 | import os 21 | import subprocess 22 | 23 | import yaml 24 | 25 | 26 | def write_to_file(fname, lines): 27 | with open(fname, 'w') as f: 28 | f.writelines((l + '\n' for l in lines)) 29 | add_git_file(fname) 30 | 31 | 32 | def setup_python_path(module_list): 33 | lines = ['# -*- coding: utf-8 -*-', 34 | 'import os', 35 | 'import sys', 36 | '', 37 | "sys.path.append(os.environ['BAG_FRAMEWORK'])", 38 | "sys.path.append(os.environ['BAG_TECH_CONFIG_DIR'])", 39 | ] 40 | template = "sys.path.append(os.path.join(os.environ['BAG_WORK_DIR'], '%s'))" 41 | lines.append(template % 'BAG2_TEMPLATES_EC') 42 | for mod_name, _ in module_list: 43 | lines.append(template % mod_name) 44 | 45 | write_to_file('bag_startup.py', lines) 46 | 47 | 48 | def get_sch_libraries(mod_name, mod_info): 49 | bag_modules = mod_info.get('lib_path', 'BagModules') 50 | root_dir = os.path.realpath(os.path.join(mod_name, bag_modules)) 51 | if not os.path.isdir(root_dir): 52 | return [] 53 | return [name for name in os.listdir(root_dir) if os.path.isdir(os.path.join(root_dir, name))] 54 | 55 | 56 | def setup_libs_def(module_list): 57 | lines = ['BAG_prim $BAG_TECH_CONFIG_DIR/DesignModules'] 58 | template = '%s $BAG_WORK_DIR/%s/%s' 59 | for mod_name, mod_info in module_list: 60 | bag_modules = mod_info.get('lib_path', 'BagModules') 61 | for lib_name in get_sch_libraries(mod_name, mod_info): 62 | lines.append(template % (lib_name, mod_name, bag_modules)) 63 | 64 | write_to_file('bag_libs.def', lines) 65 | 66 | 67 | def setup_cds_lib(module_list): 68 | lines = ['DEFINE BAG_prim $BAG_TECH_CONFIG_DIR/BAG_prim'] 69 | template = 'DEFINE %s $BAG_WORK_DIR/%s/%s' 70 | for mod_name, mod_info in module_list: 71 | for lib_name in get_sch_libraries(mod_name, mod_info): 72 | lines.append(template % (lib_name, mod_name, lib_name)) 73 | 74 | write_to_file('cds.lib.bag', lines) 75 | 76 | 77 | def run_command(cmd): 78 | timeout = 5 79 | proc = subprocess.Popen(cmd) 80 | try: 81 | proc.communicate() 82 | except KeyboardInterrupt: 83 | print('Ctrl-C detected, terminating') 84 | if proc.returncode is None: 85 | proc.terminate() 86 | print('terminating process...') 87 | try: 88 | proc.wait(timeout=timeout) 89 | print('process terminated') 90 | except subprocess.TimeoutExpired: 91 | proc.kill() 92 | print('process did not terminate, try killing...') 93 | try: 94 | proc.wait(timeout=timeout) 95 | print('process killed') 96 | except subprocess.TimeoutExpired: 97 | print('cannot kill process...') 98 | 99 | if proc.returncode is None: 100 | raise ValueError('Ctrl-C detected, but cannot kill process') 101 | elif proc.returncode < 0: 102 | raise ValueError('process terminated with return code = %d' % proc.returncode) 103 | elif proc.returncode > 0: 104 | raise ValueError('command %s failed' % ' '.join(cmd)) 105 | 106 | 107 | def add_git_submodule(module_name, url): 108 | if os.path.exists(module_name): 109 | # skip if already exists 110 | return 111 | 112 | run_command(['git', 'submodule', 'add', url]) 113 | 114 | 115 | def add_git_file(fname): 116 | run_command(['git', 'add', '-f', fname]) 117 | 118 | 119 | def link_submodule(repo_path, module_name): 120 | if os.path.exists(module_name): 121 | # skip if already exists 122 | return 123 | 124 | src = os.path.join(repo_path, module_name) 125 | if not os.path.isdir(src): 126 | raise ValueError('Cannot find submodule %s in %s' % (module_name, repo_path)) 127 | os.symlink(src, module_name) 128 | add_git_file(module_name) 129 | 130 | 131 | def setup_git_submodules(module_list): 132 | add_git_submodule('BAG2_TEMPLATES_EC', 'git@github.com:ucb-art/BAG2_TEMPLATES_EC') 133 | 134 | for module_name, module_info in module_list: 135 | add_git_submodule(module_name, module_info['url']) 136 | 137 | 138 | def setup_submodule_links(module_list, repo_path): 139 | link_submodule(repo_path, 'BAG2_TEMPLATES_EC') 140 | for module_name, _ in module_list: 141 | link_submodule(repo_path, module_name) 142 | 143 | 144 | def run_main(): 145 | with open('bag_submodules.yaml', 'r') as f: 146 | modules_info = yaml.load(f) 147 | 148 | module_list = [(key, modules_info[key]) for key in sorted(modules_info.keys())] 149 | 150 | # error checking 151 | bag_dir = 'BAG_framework' 152 | if not os.path.isdir(bag_dir): 153 | raise ValueError('Cannot find directory %s' % bag_dir) 154 | 155 | # get real absolute path of parent directory of BAG_framework 156 | repo_path = os.path.dirname(os.path.realpath(bag_dir)) 157 | cur_path = os.path.realpath('.') 158 | if cur_path == repo_path: 159 | # BAG_framework is an actual directory in this repo; add dependencies as git submodules 160 | setup_git_submodules(module_list) 161 | else: 162 | setup_submodule_links(module_list, repo_path) 163 | 164 | setup_python_path(module_list) 165 | setup_libs_def(module_list) 166 | setup_cds_lib(module_list) 167 | 168 | 169 | if __name__ == '__main__': 170 | run_main() 171 | -------------------------------------------------------------------------------- /run_scripts/sim_cell.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from argparse import Namespace 3 | from pathlib import Path 4 | import pdb 5 | 6 | from bag.io.file import Pickle, Yaml 7 | from bag.core import BagProject 8 | 9 | io_cls_dict = { 10 | 'pickle': Pickle, 11 | 'yaml': Yaml, 12 | } 13 | 14 | 15 | def parse_args() -> Namespace: 16 | parser = argparse.ArgumentParser() 17 | parser.add_argument('specs_fname', help='specs yaml file') 18 | parser.add_argument('--no-cell', dest='gen_cell', action='store_false', 19 | default=True, help='skip cell generation') 20 | parser.add_argument('--no-wrapper', dest='gen_wrapper', action='store_false', 21 | default=True, help='skip wrapper generation') 22 | parser.add_argument('--no-tb', dest='gen_tb', action='store_false', 23 | default=True, help='skip tb generation') 24 | parser.add_argument('--load', dest='load_results', action='store_true', 25 | default=False, help='skip simulation, just load the results') 26 | parser.add_argument('-x', '--extract', dest='extract', action='store_true', 27 | default=False, help='do extracted simulation') 28 | parser.add_argument('--no-sim', dest='run_sim', action='store_false', 29 | default=True, help='run simulation, --load has a priority over this') 30 | parser.add_argument('--format', default='yaml', 31 | help='format of spec file (yaml, json, pickle)') 32 | parser.add_argument('-dump', '--dump', default='', help='output will be dumped to this path, ' 33 | 'according to the format specified') 34 | parser.add_argument('--pause', default=False, action='store_true', 35 | help='True to pause using pdb.set_trace() after simulation is done') 36 | args = parser.parse_args() 37 | return args 38 | 39 | 40 | def run_main(prj: BagProject, args: Namespace): 41 | specs_fname = Path(args.specs_fname) 42 | io_cls = io_cls_dict[args.format] 43 | specs = io_cls.load(str(specs_fname)) 44 | 45 | results = prj.simulate_cell(specs=specs, 46 | gen_cell=args.gen_cell, 47 | gen_wrapper=args.gen_wrapper, 48 | gen_tb=args.gen_tb, 49 | load_results=args.load_results, 50 | extract=args.extract, 51 | run_sim=args.run_sim) 52 | 53 | if args.pause: 54 | pdb.set_trace() 55 | 56 | if results is not None and args.dump: 57 | out_tmp_file = Path(args.dump) 58 | io_cls.save(results, out_tmp_file) 59 | 60 | 61 | if __name__ == '__main__': 62 | 63 | args = parse_args() 64 | local_dict = locals() 65 | bprj = local_dict.get('bprj', BagProject()) 66 | run_main(bprj, args) -------------------------------------------------------------------------------- /run_scripts/start_bag.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | export PYTHONPATH="" 4 | 5 | # disable QT session manager warnings 6 | unset SESSION_MANAGER 7 | 8 | exec ${BAG_PYTHON} -m IPython $@ 9 | -------------------------------------------------------------------------------- /run_scripts/virt_server.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | export PYTHONPATH="${BAG_FRAMEWORK}" 4 | 5 | export cmd="-m bag.virtuoso run_skill_server" 6 | export min_port=5000 7 | export max_port=9999 8 | export port_file="BAG_server_port.txt" 9 | export log="skill_server.log" 10 | 11 | export cmd="${BAG_PYTHON} ${cmd} ${min_port} ${max_port} ${port_file} ${log}" 12 | exec $cmd 13 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from setuptools import setup, find_packages 4 | 5 | 6 | setup( 7 | name='bag', 8 | version='2.0', 9 | description='Berkeley Analog Generator', 10 | classifiers=[ 11 | 'Development Status :: 3 - Alpha', 12 | 'License :: OSI Approved :: BSD License', 13 | 'Operating System :: POSIX :: Linux', 14 | 'Programming Language :: Python :: 3.5', 15 | 'Programming Language :: Python :: 3.6', 16 | 'Programming Language :: Python :: 3.7', 17 | ], 18 | author='Eric Chang', 19 | author_email='pkerichang@berkeley.edu', 20 | packages=find_packages(), 21 | python_requires='>=3.5', 22 | install_requires=[ 23 | 'setuptools>=18.5', 24 | 'PyYAML>=3.11', 25 | 'Jinja2>=2.9', 26 | 'numpy>=1.10', 27 | 'networkx>=1.11', 28 | 'pexpect>=4.0', 29 | 'pyzmq>=15.2.0', 30 | 'scipy>=0.17', 31 | 'matplotlib>=1.5', 32 | 'rtree', 33 | 'h5py', 34 | 'Shapely', 35 | ], 36 | extras_require={ 37 | 'mdao': ['openmdao'] 38 | }, 39 | tests_require=[ 40 | 'openmdao', 41 | 'pytest', 42 | ], 43 | package_data={ 44 | 'bag.interface': ['templates/*'], 45 | 'bag.verification': ['templates/*'], 46 | }, 47 | ) 48 | -------------------------------------------------------------------------------- /tests/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucb-art/BAG_framework/daf4b0aaa72f056c7b3c90a402812a07dba9b4d7/tests/__init__.py -------------------------------------------------------------------------------- /tests/layout/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /tests/layout/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucb-art/BAG_framework/daf4b0aaa72f056c7b3c90a402812a07dba9b4d7/tests/layout/__init__.py -------------------------------------------------------------------------------- /tests/layout/routing/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Regents of the University of California 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /tests/layout/routing/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucb-art/BAG_framework/daf4b0aaa72f056c7b3c90a402812a07dba9b4d7/tests/layout/routing/__init__.py --------------------------------------------------------------------------------