Source code for align.schema.instance

from . import types
from .types import Dict, Optional, List, set_context

import logging
logger = logging.getLogger(__name__)


[docs]class Instance(types.BaseModel): model: str name: str pins: Dict[str, str] parameters: Optional[Dict[str, str]] abstract_name: Optional[str] # unique name based on model and parameters
[docs] class Config: allow_mutation = True
[docs] def xyce(self): return f'{self.name} ' + \ ' '.join(self.pins.values()) + \ f' {self.model.name} ' + \ ' '.join(f'{x}={{{y}}}' for x, y in self.parameters.items())
[docs] def translate(self, solver): ''' Bounding boxes must have non-zero height & width ''' b = solver.bbox_vars(self.name) yield b.llx < b.urx yield b.lly < b.ury
# # Private attributes affecting class behavior # @staticmethod def _get_model(library, name): return next((x for x in library if x.name == name), None)
[docs] def add_abs_name(self, abn): with set_context(self.parent): self.abstract_name = abn
@property def mclass(self): model = self._get_model(self.parent.parent.parent, self.model) assert model is not None, self.parent.parent.parent return model
[docs] @types.validator('model', allow_reuse=True) def model_exists_in_library(cls, model): model = model.upper() assert isinstance(cls._validator_ctx().parent, List[Instance]), 'Instance can only be instanitated within List[Instance]' assert cls._validator_ctx().parent.parent is not None, 'List[Instance] can only be instantiated within a SubCircuit / Circuit' assert cls._validator_ctx().parent.parent.parent is not None, 'Circuit / SubCircuit constaining instance must be registered to a Library' assert cls._get_model(cls._validator_ctx().parent.parent.parent, model) is not None, f'Could not find model {model}' return model
[docs] @types.validator('name', allow_reuse=True) def name_complies_with_model(cls, name, values): assert 'model' in values, 'Cannot run check without model definition' model = cls._get_model(cls._validator_ctx().parent.parent.parent, values['model']) name = name.upper() if model.prefix and not name.startswith(model.prefix): raise AssertionError(f"{name} does not start with {model.prefix}") return name
[docs] @types.validator('pins', allow_reuse=True) def pins_comply_with_model(cls, pins, values): assert 'model' in values, 'Cannot run check without model definition' model = cls._get_model(cls._validator_ctx().parent.parent.parent, values['model']) pins = {k.upper(): v.upper() for k, v in pins.items()} assert set(pins.keys()) == set(model.pins) return pins
[docs] @types.validator('parameters', allow_reuse=True, always=True) def parameters_comply_with_model(cls, parameters, values): assert 'model' in values, 'Cannot run check without model definition' model = cls._get_model(cls._validator_ctx().parent.parent.parent, values['model']) if parameters: parameters = {k.upper(): v.upper() for k, v in parameters.items()} assert model.parameters and set(parameters.keys()).issubset(model.parameters.keys()), \ f"{cls.__name__} parameters must be a subset of {model.__class__.__name__} parameters" parameters = {k: parameters[k] if k in parameters else v for k, v in model.parameters.items()} elif model.parameters: parameters = model.parameters.copy() return parameters