pyadi-jif Interface Contract

The adidt.jif_contract module provides the validated pyadi-dt projection of the versioned adi.jif-dt interchange format. See pyadi-jif to pyadi-dt interface contract for the ownership rules, validation sequence, compatibility policy, and cross-repository test agreement.

Contract model

Versioned interface contract between pyadi-jif and pyadi-dt.

The contract carries solved electrical intent. Physical device-tree placement (clock channel numbers, labels, SPI chip-selects, and GPIOs) remains owned by pyadi-dt and is joined through JifDtBindings.

exception adidt.jif_contract.ContractError

Bases: ValueError

Raised when a JIF/DT handoff is incompatible or cannot be bound.

class adidt.jif_contract.Producer(*, name: Literal['pyadi-jif'] = 'pyadi-jif', version: Annotated[str, MinLen(min_length=1)])

Bases: _StrictModel

Identity of the program that generated the handoff.

name: Literal['pyadi-jif']
version: str
model_config = {'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class adidt.jif_contract.JesdParameters(*, F: Annotated[int, Strict(strict=True), Gt(gt=0)], K: Annotated[int, Strict(strict=True), Gt(gt=0)], L: Annotated[int, Strict(strict=True), Gt(gt=0)], M: Annotated[int, Strict(strict=True), Gt(gt=0)], N: Annotated[int, Strict(strict=True), Gt(gt=0)], Np: Annotated[int, Strict(strict=True), Gt(gt=0)], S: Annotated[int, Strict(strict=True), Gt(gt=0)], HD: Annotated[int, Strict(strict=True), Ge(ge=0), Le(le=1)], CS: Annotated[int, Strict(strict=True), Ge(ge=0)] = 0, CF: Annotated[int, Strict(strict=True), Ge(ge=0)] = 0)

Bases: _StrictModel

JESD transport parameters shared by converter and FPGA endpoints.

F: int
K: int
L: int
M: int
N: int
Np: int
S: int
HD: int
CS: int
CF: int
validate_transport_identity() JesdParameters
model_config = {'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

Bases: _StrictModel

One solved unidirectional JESD link.

id: str
direction: Literal['adc-to-fpga', 'fpga-to-dac']
converter: str
fpga: str
standard: Literal['jesd204b', 'jesd204c']
sample_rate_hz: int
lane_rate_hz: int
parameters: JesdParameters
fpga_config: dict[str, JsonValue]
validate_lane_rate() JesdLink
model_config = {'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class adidt.jif_contract.ClockRequirement(*, id: Annotated[str, _PydanticGeneralMetadata(pattern='^[a-z0-9][a-z0-9_.-]*$')], role: Literal['converter-device', 'converter-sysref', 'fpga-ref', 'fpga-link', 'pll-ref', 'other'], sink: Annotated[str, MinLen(min_length=1)], rate_hz: Annotated[int, Strict(strict=True), Gt(gt=0)], divider: Annotated[int | None, Strict(strict=True), Gt(gt=0)] = None, source: Annotated[str, MinLen(min_length=1)])

Bases: _StrictModel

A semantic solved clock requirement, not a physical output channel.

id: str
role: Literal['converter-device', 'converter-sysref', 'fpga-ref', 'fpga-link', 'pll-ref', 'other']
sink: str
rate_hz: int
divider: int | None
source: str
model_config = {'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class adidt.jif_contract.JifDtContract(*, schema: ~typing.Literal['adi.jif-dt'] = 'adi.jif-dt', version: ~typing.Literal['1.0'] = '1.0', producer: ~adidt.jif_contract.Producer, jesd_links: tuple[~adidt.jif_contract.JesdLink, ...], clock_requirements: tuple[~adidt.jif_contract.ClockRequirement, ...], metadata: dict[str, ~pydantic.types.JsonValue] = <factory>)

Bases: _StrictModel

Portable, versioned result produced by JIF and consumed by DT.

schema_name: Literal['adi.jif-dt']
version: Literal['1.0']
producer: Producer
clock_requirements: tuple[ClockRequirement, ...]
metadata: dict[str, JsonValue]
validate_unique_ids() JifDtContract
classmethod from_json_file(path: str | Path) JifDtContract

Load and validate a contract without mutating any DT state.

to_json_file(path: str | Path) None

Write deterministic JSON suitable for fixtures and interchange.

model_config = {'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class adidt.jif_contract.ClockBinding(*, requirement_id: str, dt_label: Annotated[str, MinLen(min_length=1)], output_index: Annotated[int, Strict(strict=True), Ge(ge=0)])

Bases: _StrictModel

pyadi-dt-owned placement of one semantic clock onto a DT endpoint.

requirement_id: str
dt_label: str
output_index: int
model_config = {'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class adidt.jif_contract.JesdBinding(*, link_id: str, converter_label: Annotated[str, MinLen(min_length=1)], jesd_label: Annotated[str, MinLen(min_length=1)], xcvr_label: Annotated[str, MinLen(min_length=1)])

Bases: _StrictModel

pyadi-dt-owned placement of one semantic JESD link onto DT nodes.

converter_label: str
jesd_label: str
xcvr_label: str
model_config = {'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class adidt.jif_contract.JifDtBindings(*, clocks: tuple[ClockBinding, ...], jesd_links: tuple[JesdBinding, ...])

Bases: _StrictModel

Physical pyadi-dt profile bindings for a JIF handoff.

clocks: tuple[ClockBinding, ...]
check(contract: JifDtContract) None

Require complete, unique bindings before any DT is rendered or edited.

model_config = {'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].