Source code for padrick.Generators.ConstraintsGenerator.ConstraintsSpec

# Manuel Eggimann <meggimann@iis.ee.ethz.ch>
#
# Copyright (C) 2021-2022 ETH Zürich
# 
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import logging
import re

import click_log
from pydantic import BaseModel, conint, constr, validator, root_validator
from typing import List, Union, Optional, Tuple, Mapping

from padrick.Model.Constants import MANIFEST_VERSION, OLD_MANIFEST_VERSION_COMPATIBILITY_TABLE
from padrick.Model.PadDomain import PadDomain
from padrick.Model.PadInstance import PadInstance
from padrick.Model.PadSignal import PadSignal
from padrick.Model.Padframe import Padframe
from padrick.Model.Port import Port
from padrick.Model.PortGroup import PortGroup
from padrick.Model.SignalExpressionType import SignalExpressionType
from padrick.Model.TemplatedIdentifier import TemplatedIdentifierType
from padrick.Model.TemplatedString import TemplatedStringType

logger = logging.getLogger("padrick.ConstraintsGenerator")
click_log.basic_config(logger)

[docs]class ConstraintsGenException(Exception): pass
[docs]class ConstraintsPadMode(BaseModel): pad_inst: Union[TemplatedIdentifierType, PadInstance] port_sel: Optional[Union[TemplatedStringType, Tuple[PortGroup, Port]]] pad_cfg: Optional[Mapping[Union[PadSignal, str], Union[constr(regex=r"(0x|0b)?[0-9a-f]+"), int]]] multiple: conint(gt=1) = 1
[docs] @validator("pad_cfg") def validate_pad_cfg_expression_valid(cls, pad_cfg: Mapping[Union[PadSignal, str], str]): for key, value in pad_cfg.items(): try: pad_cfg[key] = int(value) except ValueError: raise ValueError(f"{value} is not a valid literal. You must only use hex (0x...), binary (0b) or decimal literals (42).") return pad_cfg
[docs] def expand_pad_mode(self) -> List['ConstraintsPadMode']: expanded_pad_configs = [] for i in range(self.multiple): pc: ConstraintsPadMode = self.copy() pc.pad_inst = pc.pad_inst.evaluate_template(i) if isinstance(pc.pad_inst, TemplatedIdentifierType) else pc.pad_inst pc.multiple = 1 pc.port_sel = pc.port_sel.evaluate_template(i) if isinstance(pc.port_sel, TemplatedStringType) else pc.port_sel expanded_pad_configs.append(pc) return expanded_pad_configs
[docs]class ConstraintsMode(BaseModel): name: str pad_domain: str pad_mode: List[ConstraintsPadMode]
[docs] @validator("pad_mode") def expand_multi_pad_modes(cls, pad_configs: List[ConstraintsPadMode]): expanded_pad_modes = [] for pc in pad_configs: expanded_pad_modes.extend(pc.expand_pad_mode()) return expanded_pad_modes
[docs]class ConstraintsSpec(BaseModel): manifest_version: conint(le=MANIFEST_VERSION) modes: List[ConstraintsMode]
[docs] @validator('manifest_version') def check_manifest_version(cls, version): """ Verifies that the configuration file has the right version number for the current version of padrick.""" if version != MANIFEST_VERSION: raise ValueError( f"Manifest version {version} of the padframe config file is incompatible with the current version of padrick ({padrick.__version__}.\n" f"Please use Padrick version {OLD_MANIFEST_VERSION_COMPATIBILITY_TABLE[version]} instead.") return version