libreda_pnr/rebuffer/
buffer_insertion.rs1use crate::db::{TerminalId, Direction};
9
10use crate::db::traits::*;
11use num_traits::PrimInt;
12
13pub trait SimpleBufferInsertion<LN: LayoutEdit + NetlistEdit>
17 where LN::Coord: PrimInt {
18
19 type Error;
21
22 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 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 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 let mut sources = vec![]; let mut sinks = vec![];
58
59 for t in chip.each_terminal_of_net(net) {
60 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 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}