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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use crate::db::{Direction, TerminalId};
use crate::db::traits::*;
use num_traits::PrimInt;
pub trait SimpleBufferInsertion<LN: LayoutEdit + NetlistEdit>
where
LN::Coord: PrimInt,
{
type Error;
fn insert_buffers(
&self,
chip: &mut LN,
signal_source: TerminalId<LN>,
signal_sinks: &Vec<TerminalId<LN>>,
) -> Result<(Vec<LN::CellInstId>, Vec<LN::NetId>), Self::Error>;
fn add_buffer_tree_on_net(
&self,
chip: &mut LN,
net: &LN::NetId,
) -> Result<(Vec<LN::CellInstId>, Vec<LN::NetId>), Self::Error> {
if chip.is_constant_net(net) {
let parent_name = chip.cell_name(&chip.parent_cell_of_net(net));
log::warn!(
"Net '{:?}' in '{}' probably requires a tie cell instead of a buffer.",
net,
parent_name
);
}
let mut sources = vec![];
let mut sinks = vec![];
for t in chip.each_terminal_of_net(net) {
match &t {
TerminalId::PinId(p) => match chip.pin_direction(p) {
Direction::Input => sources.push(t),
Direction::Output => sinks.push(t),
d => {
let cell_name = chip.cell_name(&chip.parent_cell_of_pin(&p));
let pin_name = chip.pin_name(p);
panic!("Cannot handle pin direction of pin '{}' in cell '{}': {:?} (must be input or output)", pin_name, cell_name, d)
}
},
TerminalId::PinInstId(p) => match chip.pin_direction(&chip.template_pin(p)) {
Direction::Input => sinks.push(t),
Direction::Output => sources.push(t),
d => {
let pin = chip.template_pin(p);
let cell_name = chip.cell_name(&chip.parent_cell_of_pin(&pin));
let pin_name = chip.pin_name(&pin);
panic!("Cannot handle pin direction of pin '{}' in cell '{}': {:?} (must be input or output)", pin_name, cell_name, d)
}
},
}
}
log::debug!("Number of drivers: {}", sources.len());
log::debug!("Number of sinks: {}", sinks.len());
if sources.len() != 1 {
log::error!("Net must be driven by exactly one output pin but net {:?} is driven by {} output pins.",
chip.net_name(net),
sources.len()
);
for driver in &sources {
let pin = match driver {
TerminalId::PinId(p) => p.clone(),
TerminalId::PinInstId(p) => chip.template_pin(p),
};
let pin_name = chip.pin_name(&pin);
let cell = chip.parent_cell_of_pin(&pin);
let cell_name = chip.cell_name(&cell);
log::error!("Pin '{}' of cell '{}' drives the net.", pin_name, cell_name)
}
}
if !sources.is_empty() {
assert_eq!(
sources.len(),
1,
"Cannot handle more than one signal driver."
);
let source = sources[0].clone();
self.insert_buffers(chip, source, &sinks)
} else {
log::warn!(
"Skip buffer tree on net '{:?}': No driver found.",
chip.net_name(net)
);
Ok((vec![], vec![]))
}
}
}