libreda_pnr/rebuffer/
buffer_insertion.rs

1// Copyright (c) 2020-2021 Thomas Kramer.
2// SPDX-FileCopyrightText: 2022 Thomas Kramer <code@tkramer.ch>
3//
4// SPDX-License-Identifier: AGPL-3.0-or-later
5
6//! Trait definition for buffer insertion algorithms.
7
8use crate::db::{TerminalId, Direction};
9
10use crate::db::traits::*;
11use num_traits::PrimInt;
12
13/// Create a simple buffer tree between a specified source pin and
14/// a set of sink pins.
15/// The insertion strategy is up to the trait implementation.
16pub trait SimpleBufferInsertion<LN: LayoutEdit + NetlistEdit>
17    where LN::Coord: PrimInt {
18
19    /// Error type that is returned on failure.
20    type Error;
21
22    /// Create a buffer tree between the source terminal
23    /// and the sinks. The terminals are given together with their location to enable creation of
24    /// a placement-aware buffer tree.
25    ///
26    /// On success: Return a list of created cell instances and a list of created nets.
27    ///
28    /// # Note
29    /// All further information (which buffer to use, how many buffers to place, where to place them, etc.)
30    /// is to be defined by the implementation of this trait.
31    fn insert_buffers(
32        &self,
33        chip: &mut LN,
34        signal_source: TerminalId<LN>,
35        signal_sinks: &Vec<TerminalId<LN>>,
36    ) -> Result<(Vec<LN::CellInstId>, Vec<LN::NetId>), Self::Error>;
37
38    /// Replace the net by a buffer tree.
39    /// 1) Identify signal driver and sinks by the direction of the pins.
40    /// 2) Call `insert_buffers()`.
41    ///
42    /// On success: Return a list of created cell instances and a list of created nets.
43    fn add_buffer_tree_on_net(
44        &self,
45        chip: &mut LN,
46        net: &LN::NetId,
47    ) -> Result<(Vec<LN::CellInstId>, Vec<LN::NetId>), Self::Error> {
48
49        // Check if the net is a special net (LOW or HIGH).
50        if chip.is_constant_net(net) {
51            let parent_name = chip.cell_name(&chip.parent_cell_of_net(net));
52            log::warn!("Net '{:?}' in '{}' probably requires a tie cell instead of a buffer.", net, parent_name);
53        }
54
55        // Find the sinks of the net and the source that drives the net.
56        let mut sources = vec![]; // There should be only one source.
57        let mut sinks = vec![];
58
59        for t in chip.each_terminal_of_net(net) {
60            // A pin of the parent cell is considered to be a source when it's direction is 'INPUT',
61            // however a pin instance that connects to a child instance is considered a sink when it's direction is 'INPUT'.
62            match &t {
63                TerminalId::PinId(p) => {
64                    match chip.pin_direction(p) {
65                        Direction::Input => sources.push(t),
66                        Direction::Output => sinks.push(t),
67                        d => {
68                            let cell_name = chip.cell_name(&chip.parent_cell_of_pin(&p));
69                            let pin_name = chip.pin_name(p);
70                            panic!("Cannot handle pin direction of pin '{}' in cell '{}': {:?} (must be input or output)", pin_name, cell_name, d)
71                        }
72                    }
73                }
74                TerminalId::PinInstId(p) => {
75                    match chip.pin_direction(&chip.template_pin(p)) {
76                        Direction::Input => sinks.push(t),
77                        Direction::Output => sources.push(t),
78                        d => {
79                            let pin = chip.template_pin(p);
80                            let cell_name = chip.cell_name(&chip.parent_cell_of_pin(&pin));
81                            let pin_name = chip.pin_name(&pin);
82                            panic!("Cannot handle pin direction of pin '{}' in cell '{}': {:?} (must be input or output)", pin_name, cell_name, d)
83                        }
84                    }
85                }
86            }
87        }
88
89        log::debug!("Number of drivers: {}", sources.len());
90        log::debug!("Number of sinks: {}", sinks.len());
91
92        if sources.len() != 1 {
93            log::error!("Net must be driven by exactly one output pin but net {:?} is driven by {} output pins.",
94                        chip.net_name(net),
95                        sources.len()
96            );
97            // Print drivers of the net for easier debugging.
98            for driver in &sources {
99                let pin = match driver {
100                    TerminalId::PinId(p) => p.clone(),
101                    TerminalId::PinInstId(p) => chip.template_pin(p)
102                };
103                let pin_name = chip.pin_name(&pin);
104                let cell = chip.parent_cell_of_pin(&pin);
105                let cell_name = chip.cell_name(&cell);
106                log::error!("Pin '{}' of cell '{}' drives the net.", pin_name, cell_name)
107            }
108        }
109
110        if !sources.is_empty() {
111            assert_eq!(sources.len(), 1, "Cannot handle more than one signal driver.");
112            let source = sources[0].clone();
113
114            self.insert_buffers(chip, source, &sinks)
115        } else {
116            log::warn!("Skip buffer tree on net '{:?}': No driver found.", chip.net_name(net));
117            Ok((vec![], vec![]))
118        }
119    }
120}