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
// Copyright (c) 2021-2021 Thomas Kramer.
// SPDX-FileCopyrightText: 2022 Thomas Kramer <code@tkramer.ch>
//
// SPDX-License-Identifier: AGPL-3.0-or-later

//! Traits for abstracting timing models.
//!
//! * [`crate::traits::TimingBase`] defines the concept of signals (e.g.  slew rates and actual arrival times) and output loads (e.g. load capacitance).
//! * [`crate::traits::DelayBase`] defines the concept of delays between an input signal and an output signal.
//! * [`crate::traits::CellDelayModel`] defines how delays through a cell can be looked-up. This is then typically implemented by
//! a timing library such as liberty.
//! * [`crate::traits::InterconnectDelayModel`] define how interconnect delays can be looked-up.
//! * [`crate::traits::ConstraintBase`] define the concept of constraints and required signals (e.g. required arrival times).
//! * [`crate::traits::CellConstraintModel`] define how constraint arcs within cells can be looked-up.
//!
//! Types for actual signals, output loads, delays, required signals and constraints are kept abstract.
//! The idea is to be able to use the same architecture for simple timing models such as the non-linear delay model (NDLM)
//! but also for more complicated methods like statistical timing analysis. In the latter case a signal
//! type would for example not only consist of a delay and a slew rate but represent a probability distribution thereof.

pub mod cell_constraint_model;
pub mod cell_delay_model;
pub mod cell_load_model;
pub mod cell_logic_model;
pub mod cell_model;
pub mod constraint_base;
pub mod delay_base;
pub mod interconnect_delay_model;
pub mod interconnect_load_model;
pub mod load_base;
pub mod timing_base;

pub(crate) mod timing_library;

pub use cell_constraint_model::*;
pub use cell_delay_model::*;
pub use cell_load_model::*;
pub use cell_model::*;
pub use constraint_base::*;
pub use delay_base::*;
pub use interconnect_delay_model::*;
pub use interconnect_load_model::*;
pub use load_base::*;
pub use timing_base::*;

use libreda_db::prelude as db;

use crate::RiseFall;

/// Enhance a netlist with timing queries.
pub trait TimingQuery: db::NetlistIds {
    /// Type which defines IDs of netlist components.
    type NetlistIds: db::NetlistIds;

    /// Type for the actual arrival times.
    type ArrivalTime;
    /// Type for required arrival times.
    type RequiredArrivalTime;
    /// Type for delays (time difference) such as slack.
    type Slack: std::fmt::Debug;

    /// Report arrival time.
    /// Assumes prior call to `update_timing` if the netlist was modified. Might panic otherwise.
    /// Returns an `Option` because some it is possible that no arrival time is defined (for example
    /// for a floating part of the netlist which is not attached to a clock).
    fn report_aat(
        &self,
        pin: db::TerminalId<Self::NetlistIds>,
        edge_polarity: RiseFall,
    ) -> Option<Self::ArrivalTime>;

    /// Report required arrival time.
    /// Assumes prior call to `update_timing` if the netlist was modified. Might panic otherwise.
    fn report_rat(
        &self,
        pin: db::TerminalId<Self::NetlistIds>,
        edge_polarity: RiseFall,
    ) -> Option<Self::RequiredArrivalTime>;

    /// Report slack (arrival time - required arrival time).
    /// Assumes prior call to `update_timing` if the netlist was modified. Might panic otherwise.
    fn report_slack(
        &self,
        pin: db::TerminalId<Self::NetlistIds>,
        edge_polarity: RiseFall,
    ) -> Option<Self::Slack>;

    /// Report a list of worst paths.
    fn report_timing(&self) -> Vec<()>;
}