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
// 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 time computation.

use super::constraint_base::ConstraintBase;
use crate::traits::CellModel;
use libreda_db::prelude::NetlistBase;

/// A constraint arc within a cell.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub struct CellConstraintArc<PinId> {
    /// The pin which imposes the constraints. For example a clock input of a flip-flop.
    pub related_pin: PinId,
    /// The pin which is constrained by the `related_pin`. For example the data input of a flip-flop.
    pub constrained_pin: PinId,
}

/// Define the computation of constraint times.
pub trait CellConstraintModel<N: NetlistBase>: CellModel<N> + ConstraintBase {
    /// Compute the constraint on the `constrained_pin` imposed by the `related_pin`.
    /// Returns `None` if there's no such constraint.
    ///
    /// # Example
    /// Assume a flip-flop with three pins: `clock`, `data_in` and `data_out`.
    /// For the flip-flop to work properly there is a constraint imposed by the signal arriving at `clock` on the signal at `data_in`.
    /// The constraint might depend on the waveform at `data_in` (slope and polarity), but also on output loads on other pins (`data_out`).
    ///
    fn get_required_input(
        &self,
        netlist: &N,
        constrained_pin: &N::PinId,
        constrained_pin_signal: &Self::Signal,
        related_pin: &N::PinId,
        related_pin_signal: &Self::Signal,
        other_inputs: &impl Fn(&N::PinId) -> Option<Self::Signal>,
        output_loads: &impl Fn(&N::PinId) -> Option<Self::Load>,
    ) -> Option<Self::RequiredSignal>;

    /// Get all constraint arcs in the given cell.
    fn constraint_arcs(
        &self,
        netlist: &N,
        cell_id: &N::CellId,
    ) -> Box<dyn Iterator<Item = CellConstraintArc<N::PinId>> + '_>;
}