libreda_pnr/route/
routing_problem.rs1use libreda_db::prelude as db;
9use std::collections::HashMap;
10
11pub trait RoutingProblem<C: db::L2NBase> {
25 fn fused_layout_netlist(&self) -> &C;
27
28 fn top_cell(&self) -> C::CellId;
30
31 fn nets(&self) -> Box<dyn Iterator<Item=C::NetId> + '_>;
33
34 fn net_weight(&self, _net: &C::NetId) -> f64 {
39 1.0
40 }
41
42 fn arc_weight(&self, _signal_source: &db::TerminalId<C>, _signal_destination: &db::TerminalId<C>) -> f64 {
46 1.0
47 }
48
49 fn blockages(&self) -> Box<dyn Iterator<Item=(C::LayerId, db::SimpleRPolygon<C::Coord>)>> {
51 Box::new(std::iter::empty())
52 }
53
54 fn boundary(&self) -> Option<db::SimpleRPolygon<C::Coord>>;
56}
57
58pub trait GlobalRoutingProblem<C: db::L2NBase>: RoutingProblem<C> {}
60
61pub trait DetailRoutingProblem<C: db::L2NBase>: RoutingProblem<C> {
63 type RoutingGuide: RoutingGuide<C>;
65
66 fn routing_guide(&self, net: &C::NetId) -> Option<&Self::RoutingGuide>;
68}
69
70pub trait RoutingGuide<C: db::L2NBase> {
72 fn contains_point(&self, layer: &C::LayerId, p: db::Point<C::Coord>) -> bool;
74
75 fn to_rectangles(&self) -> Vec<(db::Rect<C::Coord>, C::LayerId)>;
77}
78
79
80#[derive(Clone)]
83pub struct SimpleRoutingProblem<'a, LN, RoutingGuide = ()>
84 where LN: db::L2NBase {
85 pub chip: &'a LN,
87 pub top_cell: LN::CellId,
89 pub nets: Vec<LN::NetId>,
91 pub net_weights: HashMap<LN::NetId, f64>,
95 pub boundary: Option<db::SimpleRPolygon<LN::Coord>>,
97 pub routing_guides: HashMap<LN::NetId, RoutingGuide>,
99}
100
101impl<'a, LN: db::L2NBase, RG> SimpleRoutingProblem<'a, LN, RG> {
102 pub fn new(chip: &'a LN, top_cell: LN::CellId) -> Self {
105 Self {
106 chip,
107 top_cell,
108 nets: Default::default(),
109 net_weights: Default::default(),
110 boundary: Default::default(),
111 routing_guides: Default::default(),
112 }
113 }
114
115 pub fn with_routing_guides(mut self, routing_guides: HashMap<LN::NetId, RG>) -> Self {
117 self.routing_guides = routing_guides;
118 self
119 }
120}
121
122impl<'a, LN, RG> RoutingProblem<LN> for SimpleRoutingProblem<'a, LN, RG>
123 where LN: db::L2NBase {
124 fn fused_layout_netlist(&self) -> &LN {
125 self.chip
126 }
127
128 fn top_cell(&self) -> LN::CellId {
129 self.top_cell.clone()
130 }
131
132 fn nets(&self) -> Box<dyn Iterator<Item=LN::NetId> + '_> {
133 Box::new(self.nets.iter().cloned())
134 }
135
136 fn net_weight(&self, net: &LN::NetId) -> f64 {
137 self.net_weights.get(net)
138 .copied()
139 .unwrap_or(1.0)
140 }
141
142 fn blockages(&self) -> Box<dyn Iterator<Item=(LN::LayerId, db::SimpleRPolygon<LN::Coord>)>> {
143 Box::new(std::iter::empty())
144 }
145
146 fn boundary(&self) -> Option<db::SimpleRPolygon<LN::Coord>> {
147 self.boundary.clone()
148 }
149}
150
151impl<'a, LN: db::L2NBase, RG> GlobalRoutingProblem<LN> for SimpleRoutingProblem<'a, LN, RG> {}
152
153
154impl<'a, LN: db::L2NBase, RG> DetailRoutingProblem<LN> for SimpleRoutingProblem<'a, LN, RG>
155 where RG: RoutingGuide<LN> {
156 type RoutingGuide = RG;
157
158 fn routing_guide(&self, net: &LN::NetId) -> Option<&Self::RoutingGuide> {
159 self.routing_guides.get(net)
160 }
161}