def _pin_info_iter(pin_list: List[Dict[str, Any]]) -> Iterable[Tuple[str, Dict[str, Any]]]: for pin_info in pin_list: basename: str = pin_info.get('basename', '') if basename: # bus pin bus_range = pin_info['bus_range'] values: List[Dict[str, Any]] = pin_info['values'] for bus_idx, cur_info in zip(bus_range, values): pin_name = get_bus_bit_name(basename, bus_idx, cdba=True) yield pin_name, cur_info else: # scalar pin yield pin_info['name'], pin_info
def _add_pins(cell: Cell, pin_type: TermType, pin_list: List[Dict[str, Any]], pin_data: Mapping[str, Mapping[str, Any]]) -> None: remove_keys = ['reset_val', 'cap_info', 'timing_info'] for pin_info in pin_list: basename: str = pin_info.get('basename', '') if basename: # bus pin bus_range = pin_info['bus_range'] values: List[Dict[str, Any]] = pin_info['values'] bus = cell.create_bus(pin_info['name'], pin_type) for idx, (bus_idx, cur_info) in enumerate(zip(bus_range, values)): bit_name = get_bus_bit_name(basename, bus_idx, cdba=True) for rm_key in remove_keys: cur_info.pop(rm_key, None) cur_info.update(pin_data[bit_name]) timing_list: Optional[List[Dict[str, Any]]] = cur_info.pop( 'timing', None) pin = bus.create_pin(idx, pin_type, cur_info) if timing_list is not None: for timing in timing_list: pin.add_timing(**timing) else: # scalar pin pin_name = pin_info['name'] for rm_key in remove_keys: pin_info.pop(rm_key, None) pin_info.update(pin_data[pin_name]) timing_list: Optional[List[Dict[str, Any]]] = pin_info.pop( 'timing', None) pin = cell.create_pin(pin_type, pin_info) if timing_list is not None: for timing in timing_list: pin.add_timing(**timing)
def _get_pin_info_list(src_list: Sequence[Mapping[str, Any]], defaults: Mapping[str, Any], pwr_domain: Dict[str, Tuple[str, str]], reset_table: Optional[Dict[str, bool]] = None, in_cap_table: Optional[Dict[str, float]] = None, cap_guess: float = 1.0e-15 ) -> List[Dict[str, Any]]: pin_list = [] empty_dict = {} default_dict = {k: v for k, v in defaults.items()} for pin_info in src_list: pin_name: str = pin_info['name'] reset_val: Optional[int] = pin_info.get('reset_val', None) basename, bus_range = parse_cdba_name(pin_name) if bus_range is None: # scalar pin if 'basename' in pin_info: raise ValueError('Scalar pins cannot have basename entry defined.') cur_info = default_dict.copy() cur_info.update(pin_info) cur_info.pop('hide', None) in_cap_guess = cur_info.pop('cap_guess', cap_guess) if in_cap_table is not None: in_cap_table[pin_name] = in_cap_guess # record power domain pwr_domain[pin_name] = (cur_info['gnd_pin'], cur_info['pwr_pin']) if reset_val is not None: if reset_table is None: raise ValueError('reset_table is not given but reset_val is defined.') if pin_name in reset_table: raise ValueError(f'pin {pin_name} is already in reset_table.') reset_table[pin_name] = (reset_val == 1) if not pin_info.get('hide', False): pin_list.append(cur_info) else: # bus pin values: Optional[List[Dict[str, Any]]] = pin_info.get('values', None) bus_defaults: Dict[str, Any] = pin_info.get('defaults', empty_dict) cur_defaults = default_dict.copy() cur_defaults.update(bus_defaults) if 'reset_val' not in cur_defaults: cur_defaults['reset_val'] = None num_bits = len(bus_range) # NOTE: make dictionary copies, so we can add cap info to them later if values is None: values = [cur_defaults.copy() for _ in range(num_bits)] elif len(values) != num_bits: raise ValueError(f'values list of bus {pin_name} length mismatch') else: values = [] for val_ in values: val_ = val_.copy() val_.update(cur_defaults) values.append(val_) # record power domain and reset values for bus_idx, bit_info in zip(bus_range, values): pwr_str: str = _get('pwr_pin', bit_info, cur_defaults) gnd_str: str = _get('gnd_pin', bit_info, cur_defaults) reset_val: Optional[int] = _get('reset_val', bit_info, cur_defaults) in_cap_guess = bit_info.pop('cap_guess', cap_guess) bit_name = get_bus_bit_name(basename, bus_idx, cdba=True) pwr_domain[bit_name] = (gnd_str, pwr_str) if reset_val is not None: if reset_table is None: raise ValueError('reset_table is not given but reset_val is defined.') if bit_name in reset_table: raise ValueError(f'pin {bit_name} is already in reset_table.') reset_table[bit_name] = (reset_val == 1) if in_cap_table is not None: in_cap_table[bit_name] = in_cap_guess if not pin_info.get('hide', False): pin_list.append(dict(name=pin_name, basename=basename, bus_range=bus_range, values=values)) return pin_list