libreda_sta/models/
zero_interconnect_delay.rs

1// Copyright (c) 2021-2021 Thomas Kramer.
2// SPDX-FileCopyrightText: 2022 Thomas Kramer <code@tkramer.ch>
3//
4// SPDX-License-Identifier: AGPL-3.0-or-later
5
6//! Dummy implementation of an interconnect delay model: The delay is always zero.
7
8use crate::traits::*;
9use libreda_db::netlist::prelude::TerminalId;
10use libreda_db::prelude::{NetlistBase, NetlistUtil};
11
12/// Interconnect delay model which reports zero delay for
13/// a source and target terminal which belong to the same net
14/// and 'no delay' if the terminals don't belong to the same net.
15pub struct ZeroInterconnectDelayModel<D> {
16    delay_model: D,
17}
18
19impl<D> ZeroInterconnectDelayModel<D> {
20    /// Create a new interconnect delay model which returns a zero-delay for each interconnect.
21    /// The model derives the data types for delays from the supplied `delay_model`.
22    pub fn new(delay_model: D) -> Self {
23        Self { delay_model }
24    }
25}
26
27impl<D> LoadBase for ZeroInterconnectDelayModel<D>
28where
29    D: LoadBase,
30{
31    type Load = D::Load;
32
33    fn sum_loads(&self, load1: &Self::Load, load2: &Self::Load) -> Self::Load {
34        self.delay_model.sum_loads(load1, load2)
35    }
36}
37
38impl<D> TimingBase for ZeroInterconnectDelayModel<D>
39where
40    D: TimingBase,
41{
42    type Signal = D::Signal;
43    type LogicValue = D::LogicValue;
44}
45
46/// Delegate `DelayModel` implementation to `self.delay_model`.
47impl<D> DelayBase for ZeroInterconnectDelayModel<D>
48where
49    D: DelayBase,
50{
51    type Delay = D::Delay;
52
53    fn summarize_delays(&self, signal1: &Self::Signal, signal2: &Self::Signal) -> Self::Signal {
54        self.delay_model.summarize_delays(signal1, signal2)
55    }
56
57    fn get_delay(&self, from: &Self::Signal, to: &Self::Signal) -> Self::Delay {
58        self.delay_model.get_delay(from, to)
59    }
60}
61
62impl<D, N: NetlistBase> InterconnectDelayModel<N> for ZeroInterconnectDelayModel<D>
63where
64    D: DelayBase,
65{
66    fn interconnect_output(
67        &self,
68        netlist: &N,
69        source_terminal: &TerminalId<N>,
70        input_signal: &Self::Signal,
71        target_terminal: &TerminalId<N>,
72        output_load: &Self::Load,
73    ) -> Option<Self::Signal> {
74        // Both terminals should be connected to the same net. Otherwise, there's no defined
75        // interconnect delay.
76        let source_net = netlist.net_of_terminal(source_terminal);
77        let target_net = netlist.net_of_terminal(target_terminal);
78
79        if source_net.is_some() && source_net == target_net {
80            // Return the input signal without any delay.
81            Some(input_signal.clone())
82        } else {
83            None
84        }
85    }
86}