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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Copyright (c) 2021-2021 Thomas Kramer.
// SPDX-FileCopyrightText: 2022 Thomas Kramer <code@tkramer.ch>
//
// SPDX-License-Identifier: AGPL-3.0-or-later

//! Trait definitions for accessing timing data.
//!
//! * [`TimingLibrary`] Abstraction over timing data.

use uom::si::f64::{Capacitance, Time};

use super::{cell_constraint_model::CellConstraintArc, CellDelayArc};

/// Type of a signal edge. Either rising (0->1), falling (1->0).
///
/// See also [`SignalTransition`] which also allows an unspecified signal transition.
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub enum RiseFall {
    /// Rising edge.
    Rise = 0,
    /// Falling edge.
    Fall = 1,
}

/// Type of a signal edge. Either rising (0->1), falling (1->0) or both of them.
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub enum SignalTransition {
    /// One specific polarity.
    Unipolar(RiseFall),
    /// Both types, rising and falling edge.
    Bipolar,
}

impl From<RiseFall> for SignalTransition {
    fn from(p: RiseFall) -> Self {
        Self::Unipolar(p)
    }
}

/// Type of a timing constraint.
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub enum SetupHold {
    /// Signal must remain stable after the related event.
    Hold,
    /// Signal must remain stable before the related event.
    Setup,
}

/// Bundled arguments for specifying delay arcs.
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct DelayArcArg<'a, CellId, PinId> {
    /// Cell.
    pub cell: &'a CellId,
    /// Specification of the arc.
    pub arc: &'a CellDelayArc<PinId>,
}

/// Bundled arguments for specifying constraint arcs.
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct ConstraintArcArg<'a, CellId, PinId> {
    /// Cell.
    pub cell: &'a CellId,
    /// Specification of the arc.
    pub arc: &'a CellConstraintArc<PinId>,
}

/// Query cell delays and setup/hold constraints.
// TODO: Consider to remove this trait.
pub trait TimingLibrary {
    /// ID type for cells.
    type CellId;
    /// ID type for pins.
    type PinId;

    // fn get_input_capacitance(&self, cell: &str, pin: &str) -> Option<f64>;

    /// Get the transition time (slew) of an output pin.
    /// The transition time is dependent on the input transition time `input_slew` and the capacitive load
    /// at the output pin `output_capacitance`.
    fn get_slew(
        &self,
        arc: DelayArcArg<Self::CellId, Self::PinId>,
        input_slew: Time,
        output_capacitance: Capacitance,
    ) -> Option<Time>;

    /// Get the signal propagation time from the `related_pin` to the `output_pin`.
    /// The delay is dependent on the input transition time `input_slew` and the capacitive load
    /// at the output pin `output_capacitance`.
    fn get_cell_delay(
        &self,
        arc: DelayArcArg<Self::CellId, Self::PinId>,
        input_slew: Time,
        output_capacitance: Capacitance,
    ) -> Option<Time>;

    /// Get the a constraint between edges of two input signals.
    /// The 'constrained' edge is usually some data signal with is constrained
    /// by a clock signal (also called 'related' edge).
    ///
    /// * `constrained_edge_polarity`: Polarity of the constrained edge.
    /// * `edge_polarity`: Polarity of the related edge.
    fn get_hold_constraint(
        &self,
        arc: ConstraintArcArg<Self::CellId, Self::PinId>,
        related_pin_transition: Time,
        constrained_pin_transition: Time,
        output_load: Capacitance,
    ) -> Option<Time>;

    /// Get the a constraint between edges of two input signals.
    /// The 'constrained' edge is usually some data signal with is constrained
    /// by a clock signal (also called 'related' edge).
    ///
    /// * `constrained_edge_polarity`: Polarity of the constrained edge.
    /// * `edge_polarity`: Polarity of the related edge.
    fn get_setup_constraint(
        &self,
        arc: ConstraintArcArg<Self::CellId, Self::PinId>,
        related_pin_transition: Time,
        constrained_pin_transition: Time,
        output_load: Capacitance,
    ) -> Option<Time>;
}