1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// Copyright (c) 2021-2021 Thomas Kramer.
// SPDX-FileCopyrightText: 2022 Thomas Kramer <code@tkramer.ch>
//
// SPDX-License-Identifier: AGPL-3.0-or-later

//! Abstraction of the constraint computation.

use super::delay_base::DelayBase;

/// Abstraction of a constraint model.
pub trait ConstraintBase: DelayBase {
    /// Representation of a constraint.
    /// This might be for example an earliest or latest required arrival time or a allowed timing window
    /// or also a constraint on any other signal properties such as the slew.
    type Constraint: Clone + std::fmt::Debug + Sync + Send;

    /// Representation of a signal which is required to satisfy constraints.
    type RequiredSignal: Clone + std::fmt::Debug + Sync + Send;

    /// Difference between the arrival times of an actual signal and a required signal.
    type Slack: Clone + std::fmt::Debug + Sync + Send;

    /// Summarize two constraints `c1` and `c2` into a single constraint `c` such that if `c` is satisfied
    /// then also `c1` and `c2` are satisfied.
    /// Depending on the timing analysis mode (late/early) this might be
    /// a `max` or `min` function.
    fn summarize_constraints(
        &self,
        constraint1: &Self::RequiredSignal,
        constraint2: &Self::RequiredSignal,
    ) -> Self::RequiredSignal;

    /// Find the required input signal such that the actual output signal is equal to the
    /// `required_output`. The `actual_delay` from the input to the output is given.
    /// Also the actual output is given (might not be necessary to compute the result).
    fn solve_delay_constraint(
        &self,
        actual_delay: &Self::Delay,
        required_output: &Self::RequiredSignal,
        actual_signal: &Self::Signal,
    ) -> Self::RequiredSignal;

    /// Compute the slack between the actual signal and the required signal.
    /// Positive slack implies a met timing.
    /// Negative slack implies a violated timing.
    fn get_slack(
        &self,
        actual_signal: &Self::Signal,
        required_signal: &Self::RequiredSignal,
    ) -> Self::Slack;
}