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
// SPDX-FileCopyrightText: 2023 Thomas Kramer <code@tkramer.ch>
//
// SPDX-License-Identifier: AGPL-3.0-or-later

//! Trait for a cell library which provides logic views of the cells.

use liberty_io::boolean::BooleanExpr;
use libreda_db::traits::NetlistIds;
use libreda_logic::truth_table::small_lut::SmallTruthTable;

use super::CellModel;

use blanket::blanket;

/// Either a combinational/boolean function or a state-holding element.
#[derive(Debug, Clone, Default)]
#[non_exhaustive]
pub enum OutputFunction<PinId> {
    /// The output function of the pin is not known.
    #[default]
    Unknown,
    /// Combinational logic: The value of the output pin is defined by a boolean function.
    Comb(BooleanFn<PinId>),
    /// Sequential logic: The value of the output pin is defined by a state-holding element.
    Sequential(Sequential<PinId>),
}

/// Description of an output pin which is driven by a sequential circuit.
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct Sequential<PinId> {
    /// The sequential output is updated when at least one
    /// of the boolean expressions transitions from `false` to `true`.
    pub clocked_on: Vec<BooleanExpr<PinId>>,
    /// TODO: Latches:
    pub transparent_on: Vec<BooleanExpr<PinId>>,
    //TODO pub data: BooleanExpr<PinOrState<PinId>>,
    //TODO pub next_state: BooleanExpr<PinOrState<PinId>>,
}

/// A boolean input which can either be an input pin
/// or an internal state. Used for storage elements such as flip-flops
/// and latches.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum PinOrState<PinId> {
    /// An input pin.
    Pin(PinId),
    /// An internal state bit.
    State(usize),
}

/// Unateness describes a monotonic property of a boolean function.
/// Usually, unateness is related to a specific input.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Default)]
pub enum Unateness {
    /// A rising/falling edge at the input can cause both rising and falling edges at the output.
    #[default]
    None,
    /// An edge at the input can only cause edges of the opposite polarity at the output.
    Negative,
    /// An edge at the input can only cause edges of the same polarity at the output.
    Positive,
}

/// Representation of a boolean function.
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum BooleanFn<PinId> {
    /// Logic function with few inputs (6 or less).
    Small(SmallTruthTable),
    /// A boolean expression tree.
    Expr(BooleanExpr<PinId>),
}

/// Provide logic abstraction of digital cells.
#[blanket(derive(Ref))]
pub trait LogicModel<N: NetlistIds>: CellModel<N> {
    /// Get the logic function of a cell output pin.
    fn pin_function(&self, output_pin: &N::PinId) -> &OutputFunction<N::PinId>;

    /// Get the unateness of the timing arc.
    fn timing_sense(
        &self,
        output_pin: &N::PinId,
        related_pin: &N::PinId,
        other_inputs: &impl Fn(&N::PinId) -> Option<bool>,
    ) -> Unateness;
}