Skip to content

Commit

Permalink
Merge pull request ucb-art#2 from ucb-art/master
Browse files Browse the repository at this point in the history
Update from master
  • Loading branch information
mkosunen authored Feb 5, 2020
2 parents 88ac46e + bd32023 commit a44c036
Show file tree
Hide file tree
Showing 15 changed files with 169 additions and 112 deletions.
69 changes: 45 additions & 24 deletions bag/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,24 @@ def import_design_library(self, lib_name):
new_lib_path = self.bag_config['new_lib_path']
self.impl_db.import_design_library(lib_name, self.dsn_db, new_lib_path)

def import_sch_cellview(self, lib_name: str, cell_name: str) -> None:
"""Import the given schematic and symbol template into Python.
This import process is done recursively.
Parameters
----------
lib_name : str
library name.
cell_name : str
cell name.
"""
if self.impl_db is None:
raise Exception('BAG Server is not set up.')

new_lib_path = self.bag_config['new_lib_path']
self.impl_db.import_sch_cellview(lib_name, cell_name, self.dsn_db, new_lib_path)

def get_cells_in_library(self, lib_name):
# type: (str) -> Sequence[str]
"""Get a list of cells in the given library.
Expand Down Expand Up @@ -712,29 +730,36 @@ def generate_cell(self, # type: BagProject
if run_lvs:
print('running lvs...')
lvs_passed, lvs_log = self.run_lvs(impl_lib, impl_cell, gds_lay_file=gds_lay_file)
print('LVS log: %s' % lvs_log)
if lvs_passed:
print('LVS passed!')
result = dict(log='')
else:
print('LVS failed...')
result = dict(log=lvs_log)
raise ValueError(f'LVS failed, lvs_log: {lvs_log}')

if run_rcx and ((run_lvs and lvs_passed) or not run_lvs):
print('running rcx...')
rcx_passed, rcx_log = self.run_rcx(impl_lib, impl_cell)
print('RCX log: %s' % rcx_log)
if rcx_passed:
print('RCX passed!')
result = dict(log='')
else:
print('RCX failed...')
result = dict(log=rcx_log)
raise ValueError(f'RCX failed, rcx_log: {rcx_log}')

if result_pstat:
return result_pstat
return result

def replace_dut_in_wrapper(self, params: Dict[str, Any], dut_lib: str,
dut_cell: str) -> None:
# helper function that replaces dut_lib and dut_cell in the wrapper recursively base on
# dut_params
dut_params = params.get('dut_params', None)
if dut_params is None:
params['dut_lib'] = dut_lib
params['dut_cell'] = dut_cell
return
return self.replace_dut_in_wrapper(dut_params, dut_lib, dut_cell)

def simulate_cell(self,
specs: Dict[str, Any],
gen_cell: bool = True,
Expand Down Expand Up @@ -805,13 +830,13 @@ def simulate_cell(self,
tbm: TestbenchManager = tbm_cls(root_dir)
sim_view_list = tbm_specs.get('sim_view_list', [])
if not sim_view_list:
# TODO: Is netlist always the right keyword?
view_name = tbm_specs.get('view_name', 'netlist' if extract else 'schematic')
view_name = 'netlist' if extract else 'schematic'
sim_view_list.append((impl_cell, view_name))
sim_envs = tbm_specs['sim_envs']

if load_results:
return tbm.load_results(impl_cell, tbm_specs)

results = tbm.simulate(bprj=self,
impl_lib=impl_lib,
impl_cell=impl_cell,
Expand All @@ -831,7 +856,7 @@ def simulate_cell(self,
if gen_wrapper and not has_wrapper:
raise ValueError('must provide a wrapper in sim_params')

wrapped_cell = ''
wrapper_lib = wrapper_cell = wrapped_cell = wrapper_params = None
if has_wrapper:
wrapper_lib = wrapper['wrapper_lib']
wrapper_cell = wrapper['wrapper_cell']
Expand Down Expand Up @@ -862,10 +887,9 @@ def simulate_cell(self,

if gen_wrapper and has_wrapper:
print('generating wrapper ...')
# noinspection PyUnboundLocalVariable
master = self.create_design_module(lib_name=wrapper_lib, cell_name=wrapper_cell)
# noinspection PyUnboundLocalVariable
master.design(dut_lib=impl_lib, dut_cell=impl_cell, **wrapper_params)
self.replace_dut_in_wrapper(wrapper_params, impl_lib, impl_cell)
master.design(**wrapper_params)
master.implement_design(impl_lib, wrapped_cell)
print('wrapper generated.')

Expand All @@ -878,17 +902,10 @@ def simulate_cell(self,
print('testbench generated.')

if run_sim:
print('seting up ADEXL ...')
# TODO: when running simulations directly (not through tb_manager), sim_view_list is
# not supported
# TODO: netlist might not be always the right keyword.
# something like:
# view_name = self.get_proper_view_name if extract else 'netlist'

print('setting up ADEXL ...')
sim_view_list = sim_params.get('sim_view_list', [])
if not sim_view_list:
# TODO: Is netlist always the right keyword?
view_name = sim_params.get('view_name', 'netlist' if extract else 'schematic')
view_name = 'netlist' if extract else 'schematic'
sim_view_list.append((impl_cell, view_name))

sim_envs = sim_params['sim_envs']
Expand All @@ -904,14 +921,14 @@ def simulate_cell(self,

# set sweep parameters
for key, val in sim_swp_params.items():
tb.set_sweep_parameter(key, values=val)
tb.set_sweep_parameter(key, **val)

# set the simulation outputs
for key, val in sim_outputs.items():
tb.add_output(key, val)

# change the view_name (netlist or schematic)
for cell, view in sim_view_list.items():
for cell, view in sim_view_list:
tb.set_simulation_view(impl_lib, cell, view)

tb.set_simulation_environments(sim_envs)
Expand All @@ -922,6 +939,9 @@ def simulate_cell(self,
print('simulation done.')
print('loading results ...')
results = sim_data.load_sim_results(tb.save_dir)
if not results.get('sweep_params', {}):
raise ValueError(f'results are empty, either you forgot to specify outputs, or '
f'simulation failed. check sim_log: {tb.save_dir}/ocn_output.log')
print('results loaded.')
print('saving results into hdf5')
sim_data.save_sim_results(results, tb_fname)
Expand Down Expand Up @@ -995,7 +1015,8 @@ def measure_cell(self,
mm_cls = _import_class_from_str(mm_cls_str)
mm: MeasurementManager = mm_cls(root_dir, mm_specs)
return mm.measure(self, impl_lib, impl_cell, load_results=load_results,
gen_wrapper=gen_wrapper, gen_tb=gen_tb, run_sims=run_sims)
gen_wrapper=gen_wrapper, gen_tb=gen_tb, run_sims=run_sims,
extract=extract)

def create_library(self, lib_name, lib_path=''):
# type: (str, str) -> None
Expand Down
10 changes: 5 additions & 5 deletions bag/design/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
from typing import TYPE_CHECKING, List, Dict, Optional, Tuple, Any, Type, Set, Sequence, \
Callable, Union

from bag import float_to_si_string
from bag.io import read_yaml
from bag.util.cache import DesignMaster, MasterDB
from ..math import float_to_si_string
from ..io import read_yaml
from ..util.cache import DesignMaster, MasterDB

if TYPE_CHECKING:
from bag.core import BagProject
from bag.layout.core import TechInfo
from ..core import BagProject
from ..layout.core import TechInfo


class ModuleDB(MasterDB):
Expand Down
19 changes: 19 additions & 0 deletions bag/interface/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,25 @@ def import_design_library(self, lib_name, dsn_db, new_lib_path):
for cell_name in self.get_cells_in_library(lib_name):
self._import_design(lib_name, cell_name, imported_cells, dsn_db, new_lib_path)

def import_sch_cellview(self, lib_name, cell_name, dsn_db, new_lib_path):
"""Import the given schematic and symbol template into Python.
This import process is done recursively.
Parameters
----------
lib_name : str
library name.
cell_name : str
cell name.
dsn_db : ModuleDB
the design database object.
new_lib_path: str
location to import new libraries to.
"""
imported_cells = set()
self._import_design(lib_name, cell_name, imported_cells, dsn_db, new_lib_path)

def _import_design(self, lib_name, cell_name, imported_cells, dsn_db, new_lib_path):
"""Recursive helper for import_design_library.
"""
Expand Down
20 changes: 10 additions & 10 deletions bag/interface/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

import traceback

import bag.io
from .. import io


def _object_to_skill_file_helper(py_obj, file_obj):
Expand All @@ -35,11 +35,11 @@ def _object_to_skill_file_helper(py_obj, file_obj):
py_obj : any
the object to convert.
file_obj : file
the file object to write to. Must be created with bag.io
the file object to write to. Must be created with io
package so that encodings are handled correctly.
"""
# fix potential raw bytes
py_obj = bag.io.fix_string(py_obj)
py_obj = io.fix_string(py_obj)
if isinstance(py_obj, str):
# string
file_obj.write(py_obj)
Expand Down Expand Up @@ -83,7 +83,7 @@ def object_to_skill_file(py_obj, file_obj):
py_obj : any
the object to convert.
file_obj : file
the file object to write to. Must be created with bag.io
the file object to write to. Must be created with io
package so that encodings are handled correctly.
"""
_object_to_skill_file_helper(py_obj, file_obj)
Expand All @@ -105,10 +105,10 @@ class SkillServer(object):
router : :class:`bag.interface.ZMQRouter`
the :class:`~bag.interface.ZMQRouter` object used for socket communication.
virt_in : file
the virtuoso input file. Must be created with bag.io
the virtuoso input file. Must be created with io
package so that encodings are handled correctly.
virt_out : file
the virtuoso output file. Must be created with bag.io
the virtuoso output file. Must be created with io
package so that encodings are handled correctly.
tmpdir : str or None
if given, will save all temporary files to this folder.
Expand All @@ -122,7 +122,7 @@ def __init__(self, router, virt_in, virt_out, tmpdir=None):
self.virt_out = virt_out

# create a directory for all temporary files
self.dtmp = bag.io.make_temp_dir('skillTmp', parent_dir=tmpdir)
self.dtmp = io.make_temp_dir('skillTmp', parent_dir=tmpdir)

def run(self):
"""Starts this server.
Expand Down Expand Up @@ -203,7 +203,7 @@ def process_skill_request(self, request):
fname_dict = {}
# write input parameters to files
for key, val in input_files.items():
with bag.io.open_temp(prefix=key, delete=False, dir=self.dtmp) as file_obj:
with io.open_temp(prefix=key, delete=False, dir=self.dtmp) as file_obj:
fname_dict[key] = '"%s"' % file_obj.name
# noinspection PyBroadException
try:
Expand All @@ -216,7 +216,7 @@ def process_skill_request(self, request):

# generate output file
if out_file:
with bag.io.open_temp(prefix=out_file, delete=False, dir=self.dtmp) as file_obj:
with io.open_temp(prefix=out_file, delete=False, dir=self.dtmp) as file_obj:
fname_dict[out_file] = '"%s"' % file_obj.name
out_file = file_obj.name

Expand All @@ -241,7 +241,7 @@ def process_skill_result(self, msg, out_file=None):
elif out_file:
# read result from file.
try:
msg = bag.io.read_file(out_file)
msg = io.read_file(out_file)
data = dict(type='str', data=msg)
except IOError:
stack_trace = traceback.format_exc()
Expand Down
18 changes: 9 additions & 9 deletions bag/interface/zmqwrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import yaml
import zmq

import bag.io
from .. import io


class ZMQDealer(object):
Expand Down Expand Up @@ -61,13 +61,13 @@ def __init__(self, port, pipeline=100, host='localhost', log_file=None):
def log_msg(self, msg):
"""Log the given message"""
if self._log_file is not None:
bag.io.write_file(self._log_file, '%s\n' % msg, append=True)
io.write_file(self._log_file, '%s\n' % msg, append=True)

def log_obj(self, msg, obj):
"""Log the given object"""
if self._log_file is not None:
obj_str = pprint.pformat(obj)
bag.io.write_file(self._log_file, '%s\n%s\n' % (msg, obj_str), append=True)
io.write_file(self._log_file, '%s\n%s\n' % (msg, obj_str), append=True)

def close(self):
"""Close the underlying socket."""
Expand All @@ -81,7 +81,7 @@ def send_obj(self, obj):
obj : any
the object to send.
"""
p = bag.io.to_bytes(yaml.dump(obj))
p = io.to_bytes(yaml.dump(obj))
z = zlib.compress(p)
self.log_obj('sending data:', obj)
self.socket.send(z)
Expand Down Expand Up @@ -117,7 +117,7 @@ def recv_obj(self, timeout=None, enable_cancel=False):

if events:
data = self.socket.recv()
z = bag.io.fix_string(zlib.decompress(data))
z = io.fix_string(zlib.decompress(data))
obj = yaml.load(z, Loader=yaml.FullLoader)
self.log_obj('received data:', obj)
return obj
Expand Down Expand Up @@ -201,13 +201,13 @@ def close(self):
def log_msg(self, msg):
"""Log the given message"""
if self._log_file is not None:
bag.io.write_file(self._log_file, '%s\n' % msg, append=True)
io.write_file(self._log_file, '%s\n' % msg, append=True)

def log_obj(self, msg, obj):
"""Log the given object"""
if self._log_file is not None:
obj_str = pprint.pformat(obj)
bag.io.write_file(self._log_file, '%s\n%s\n' % (msg, obj_str), append=True)
io.write_file(self._log_file, '%s\n%s\n' % (msg, obj_str), append=True)

def send_msg(self, msg, addr=None):
"""Sends a string message
Expand Down Expand Up @@ -242,7 +242,7 @@ def send_obj(self, obj, addr=None):
warn_msg = '*WARNING* No receiver address specified. Message not sent:'
self.log_obj(warn_msg, obj)
else:
p = bag.io.to_bytes(yaml.dump(obj))
p = io.to_bytes(yaml.dump(obj))
z = zlib.compress(p)
self.log_obj('sending data:', obj)
self.socket.send_multipart([addr, z])
Expand Down Expand Up @@ -272,7 +272,7 @@ def recv_obj(self):
"""
self.addr, data = self.socket.recv_multipart()

z = bag.io.fix_string(zlib.decompress(data))
z = io.fix_string(zlib.decompress(data))
obj = yaml.load(z)
self.log_obj('received data:', obj)
return obj
Expand Down
Loading

0 comments on commit a44c036

Please sign in to comment.