1use log;
12
13use crate::common::Orient;
14use crate::lef_ast;
15use crate::lef_ast::{Layer, RoutingDirection, TechnologyLef, LEF};
16use db::traits::*;
17use libreda_db::prelude as db;
18use libreda_db::technology::layerstack;
19use libreda_db::technology::layerstack::{RoutingLayer, RoutingLayerStack, RoutingLayerType};
20use libreda_db::technology::rules;
21use libreda_db::technology::rules::RuleBase;
22use num_traits::{FromPrimitive, ToPrimitive};
23use std::collections::HashMap;
24use std::marker::PhantomData;
25
26pub struct LEFDesignRuleAdapter<'a, L: db::LayoutBase> {
28 lef: &'a LEF,
30 dbu: f64,
32 layer_mapping: HashMap<L::LayerId, &'a lef_ast::Layer>,
34 layer_stack: Vec<(L::LayerId, &'a lef_ast::Layer)>,
36 ty: PhantomData<L>,
37}
38
39impl<'a, L> LEFDesignRuleAdapter<'a, L>
40where
41 L: db::LayoutBase,
42 L::Coord: ToPrimitive, {
44 fn db_distance_to_lef(&self, db_distance: L::Coord) -> f64 {
46 let dbu = self.dbu;
47
48 db_distance
49 .to_f64()
50 .expect("Conversion from LEF distance unit to database distance unit failed.")
51 / dbu
52 }
53}
54
55impl<'a, L> LEFDesignRuleAdapter<'a, L>
56where
57 L: db::LayoutBase,
58 L::Coord: FromPrimitive, {
60 fn lef_distance_to_db(&self, lef_distance: f64) -> L::Coord {
62 let dbu = self.dbu;
63
64 L::Coord::from_f64(lef_distance * dbu)
65 .expect("Conversion from LEF distance unit to database distance unit failed.")
66 }
67}
68
69impl<'a, L> LEFDesignRuleAdapter<'a, L>
70where
71 L: db::LayoutBase,
72 L::Coord: FromPrimitive + ToPrimitive, {
74 pub fn new(lef: &'a LEF, layout: &L) -> Self {
77 let dbu = layout
78 .dbu()
79 .to_f64()
80 .expect("failed to convert data-base unit from to f64");
81 Self::new_from_layer_mapping(lef, &Self::extract_layer_mapping_from_layout(layout), dbu)
82 }
83
84 pub fn new_from_layer_mapping(
87 lef: &'a LEF,
88 layer_ids_by_name: &HashMap<String, L::LayerId>,
89 dbu: f64,
90 ) -> Self {
91 assert!(
92 dbu > 0.0,
93 "'data-base units per micron' must be larger than 0"
94 );
95
96 let mut new = Self {
97 lef,
98 dbu,
99 layer_mapping: Default::default(),
100 layer_stack: Default::default(),
101 ty: Default::default(),
102 };
103
104 new.create_layer_mapping(layer_ids_by_name);
105
106 new
107 }
108
109 fn extract_layer_mapping_from_layout(layout: &L) -> HashMap<String, L::LayerId> {
111 layout
112 .each_layer()
113 .filter_map(|layer_id| {
114 let layer_name = layout
115 .layer_info(&layer_id)
116 .name
117 .as_ref()
118 .map(|n| n.to_string());
119 layer_name.map(|name| (name, layer_id))
120 })
121 .collect()
122 }
123
124 fn create_layer_mapping(&mut self, layer_ids_by_name: &HashMap<String, L::LayerId>) {
126 let lef_layers_by_name = self
128 .lef
129 .technology
130 .layers
131 .iter()
132 .map(|layer| (layer.name(), layer));
133
134 let lef_layers_by_layer_id: Vec<_> = lef_layers_by_name
136 .filter_map(|(layer_name, layer)| {
137 let layer_id = layer_ids_by_name.get(layer_name);
138 layer_id.map(|id| (id.clone(), layer))
139 })
140 .collect();
141
142 self.layer_mapping = lef_layers_by_layer_id.iter().cloned().collect();
143
144 self.layer_stack = lef_layers_by_layer_id;
145 }
146}
147
148impl<'a, L: db::LayoutBase> layerstack::RoutingLayerStack for LEFDesignRuleAdapter<'a, L> {
149 fn layer_stack(&self) -> Vec<RoutingLayer<Self::LayerId>> {
150 self.layer_stack
151 .iter()
152 .filter_map(|(id, layer)| match layer {
154 Layer::MasterSlice(_) => None,
155 Layer::Cut(_) => Some(RoutingLayer::new(id.clone(), RoutingLayerType::Cut)),
156 Layer::Routing(_) => Some(RoutingLayer::new(id.clone(), RoutingLayerType::Routing)),
157 })
158 .collect()
159 }
160}
161
162impl<'a, L: db::LayoutBase> rules::RuleBase for LEFDesignRuleAdapter<'a, L> {
163 type LayerId = L::LayerId;
164}
165
166impl<'a, L: db::LayoutBase> rules::DistanceRuleBase for LEFDesignRuleAdapter<'a, L> {
167 type Distance = L::Coord;
168 type Area = L::Coord;
169}
170
171impl<'a, L: db::LayoutBase> rules::MinimumSpacing for LEFDesignRuleAdapter<'a, L>
172where
173 L::Coord: ToPrimitive + FromPrimitive,
174{
175 fn min_spacing_absolute(&self, layer_id: &Self::LayerId) -> Option<Self::Distance> {
176 self.layer_mapping
177 .get(layer_id)
178 .and_then(|layer| match layer {
179 Layer::MasterSlice(_) => unimplemented!("Min spacing for MASTERSLICE layers."),
180 Layer::Cut(_) => {
181 None
184 }
185 Layer::Routing(routing_layer) => {
186 get_absolute_min_spacing_of_routing_layer(routing_layer)
188 }
189 })
190 .map(|d| self.lef_distance_to_db(d))
191 }
192
193 fn min_spacing(
194 &self,
195 layer_id: &Self::LayerId,
196 run_length: Self::Distance,
197 width: Self::Distance,
198 ) -> Option<Self::Distance> {
199 let run_length = self.db_distance_to_lef(run_length);
200 let width = self.db_distance_to_lef(width);
201
202 self.layer_mapping
203 .get(layer_id)
204 .and_then(|layer| match layer {
205 Layer::MasterSlice(_) => unimplemented!("Min spacing for MASTERSLICE layers."),
206 Layer::Cut(_) => {
207 None
209 }
210 Layer::Routing(routing_layer) => {
211 get_min_spacing_of_routing_layer(routing_layer, run_length, width)
213 }
214 })
215 .map(|d| self.lef_distance_to_db(d))
216 }
217}
218
219impl<'a, L: db::LayoutBase> rules::PreferredRoutingDirection for LEFDesignRuleAdapter<'a, L>
220where
221 L::Coord: ToPrimitive + FromPrimitive,
222{
223 fn preferred_routing_direction(&self, layer_id: &Self::LayerId) -> Option<db::Orientation2D> {
224 self.layer_mapping
225 .get(layer_id) .and_then(|layer| match layer {
227 Layer::Routing(routing_layer) => {
228 match routing_layer.direction {
229 RoutingDirection::Vertical => Some(db::Orientation2D::Vertical),
230 RoutingDirection::Horizontal => Some(db::Orientation2D::Horizontal),
231 RoutingDirection::Diag45 => {
232 None
234 }
235 RoutingDirection::Diag135 => {
236 None
238 }
239 }
240 }
241 _ => None, })
243 }
244}
245
246impl<'a, L> rules::RoutingRules for LEFDesignRuleAdapter<'a, L>
247where
248 L: db::LayoutBase,
249 L::Coord: ToPrimitive + FromPrimitive,
250{
251 fn default_pitch(&self, layer_id: &Self::LayerId) -> Option<(Self::Distance, Self::Distance)> {
252 self.layer_mapping
253 .get(layer_id)
254 .and_then(|layer| match layer {
255 Layer::MasterSlice(_) => unimplemented!("Default pitch for MASTERSLICE layers."),
256 Layer::Cut(_) => None, Layer::Routing(routing_layer) => Some(routing_layer.pitch),
258 })
259 .map(|(pitch_x, pitch_y)| {
260 (
261 self.lef_distance_to_db(pitch_x),
262 self.lef_distance_to_db(pitch_y),
263 )
264 })
265 }
266}
267
268fn get_absolute_min_spacing_of_routing_layer(routing_layer: &lef_ast::RoutingLayer) -> Option<f64> {
272 if let Some(spacing_table) = &routing_layer.spacing_table {
273 spacing_table
274 .spacings
275 .first()
276 .and_then(|spacings| spacings.first())
277 .copied()
278 .or(Some(0.))
279 } else {
280 routing_layer
282 .spacing
283 .iter()
284 .map(|spacing_rule| spacing_rule.min_spacing)
285 .reduce(|min, x| if x < min { x } else { min })
287 }
288}
289
290fn get_min_spacing_of_routing_layer(
294 routing_layer: &lef_ast::RoutingLayer,
295 parallel_runlength: f64,
296 width: f64,
297) -> Option<f64> {
298 if let Some(spacing_table) = &routing_layer.spacing_table {
299 let row = spacing_table
301 .spacings
302 .iter()
303 .zip(&spacing_table.widths)
304 .filter(|(row, &w)| w <= width)
305 .last()
306 .map(|(row, _)| row);
307 row.and_then(|row| {
308 row.iter()
310 .zip(&spacing_table.parallel_run_lengths)
311 .filter(|(spacing, &run_length)| run_length <= parallel_runlength)
312 .last()
313 .map(|(&spacing, _)| spacing)
314 })
315 } else {
316 get_absolute_min_spacing_of_routing_layer(routing_layer)
318 }
319}
320
321impl<'a, L> rules::MinimumWidth for LEFDesignRuleAdapter<'a, L>
322where
323 L: db::LayoutBase,
324 L::Coord: FromPrimitive,
325{
326 fn min_width(
327 &self,
328 layer_id: &Self::LayerId,
329 shape_length: Option<Self::Distance>,
330 ) -> Option<Self::Distance> {
331 self.layer_mapping
332 .get(layer_id)
333 .and_then(|layer| match layer {
334 Layer::MasterSlice(_) => {
335 unimplemented!("Minimum width for LEF 'masterslice' layers is not implemented.")
336 }
337 Layer::Cut(_) => {
338 None
339 }
341 Layer::Routing(routing_layer) => routing_layer.min_width,
342 })
343 .map(|d| self.lef_distance_to_db(d))
344 }
345}
346
347impl<'a, L> rules::DefaultWidth for LEFDesignRuleAdapter<'a, L>
348where
349 L: db::LayoutBase,
350 L::Coord: FromPrimitive,
351{
352 fn default_width(
353 &self,
354 layer_id: &Self::LayerId,
355 shape_length: Option<Self::Distance>,
356 ) -> Option<Self::Distance> {
357 self.layer_mapping
358 .get(layer_id)
359 .and_then(|layer| match layer {
360 Layer::MasterSlice(_) => {
361 unimplemented!("Default width for LEF 'masterslice' layers is not implemented.")
362 }
363 Layer::Cut(_) => {
364 None
365 }
367 Layer::Routing(routing_layer) => Some(routing_layer.width),
368 })
369 .map(|d| self.lef_distance_to_db(d))
370 }
371}
372
373#[cfg(test)]
374mod tests {
375 use crate::lef_parser::read_lef_chars;
376 use crate::lef_tech_adapter::LEFDesignRuleAdapter;
377 use db::technology::rules::*;
378 use db::traits::*;
379 use libreda_db::prelude as db;
380
381 const LEF_DATA: &'static str = r#"
382VERSION 5.5 ;
383NAMESCASESENSITIVE ON ;
384BUSBITCHARS "[]" ;
385DIVIDERCHAR "/" ;
386
387PROPERTYDEFINITIONS
388 LAYER contactResistance REAL ;
389END PROPERTYDEFINITIONS
390
391UNITS
392 DATABASE MICRONS 1000 ;
393END UNITS
394MANUFACTURINGGRID 0.0025 ;
395LAYER poly
396 TYPE MASTERSLICE ;
397END poly
398
399LAYER contact
400 TYPE CUT ;
401 SPACING 0.075 ;
402 PROPERTY contactResistance 10.5 ;
403END contact
404
405LAYER metal1
406 TYPE ROUTING ;
407 DIRECTION HORIZONTAL ;
408 PITCH 0.19 ;
409 WIDTH 0.065 ;
410 MINWIDTH 0.05 ;
411 SPACING 0.065 ;
412 RESISTANCE RPERSQ 0.38 ;
413
414 SPACINGTABLE
415 PARALLELRUNLENGTH 0.0 1.0
416 WIDTH 0.0 0.1 0.3
417 WIDTH 0.5 0.4 0.5
418 ;
419
420END metal1
421
422LAYER via1
423 TYPE CUT ;
424 SPACING 0.075 ;
425 PROPERTY contactResistance 5.69 ;
426END via1
427
428LAYER metal2
429 TYPE ROUTING ;
430 DIRECTION VERTICAL ;
431 PITCH 0.19 ;
432 WIDTH 0.07 ;
433 SPACING 0.075 ;
434END metal2
435
436LAYER OVERLAP
437 TYPE OVERLAP ;
438END OVERLAP
439
440VIA M2_M1_via DEFAULT
441 LAYER metal1 ;
442 RECT -0.0675 -0.0325 0.0675 0.0325 ;
443 LAYER via1 ;
444 RECT -0.0325 -0.0325 0.0325 0.0325 ;
445 LAYER metal2 ;
446 RECT -0.035 -0.0675 0.035 0.0675 ;
447END M2_M1_via
448
449VIARULE M2_M1 GENERATE
450 LAYER metal1 ;
451 ENCLOSURE 0 0.035 ;
452 LAYER metal2 ;
453 ENCLOSURE 0 0.035 ;
454 LAYER via1 ;
455 RECT -0.0325 -0.0325 0.0325 0.0325 ;
456 SPACING 0.14 BY 0.14 ;
457END M2_M1
458
459VIARULE M1_POLY GENERATE
460 LAYER poly ;
461 ENCLOSURE 0 0 ;
462 LAYER metal1 ;
463 ENCLOSURE 0 0.035 ;
464 LAYER contact ;
465 RECT -0.0325 -0.0325 0.0325 0.0325 ;
466 SPACING 0.14 BY 0.14 ;
467END M1_POLY
468
469SPACING
470 SAMENET metal1 metal1 0.065 ;
471 SAMENET metal2 metal2 0.07 ;
472 SAMENET metal6 metal6 0.14 ;
473 SAMENET metal5 metal5 0.14 ;
474 SAMENET metal4 metal4 0.14 ;
475 SAMENET metal3 metal3 0.07 ;
476 SAMENET metal7 metal7 0.4 ;
477 SAMENET metal8 metal8 0.4 ;
478 SAMENET metal9 metal9 0.8 ;
479 SAMENET metal10 metal10 0.8 ;
480END SPACING
481
482END LIBRARY
483
484 "#;
485
486 fn create_empty_layout() -> (db::Chip, Vec<<db::Chip as db::LayoutIds>::LayerId>) {
487 let mut layout = db::Chip::new();
489 layout.set_dbu(1000);
490
491 let layer1 = layout.create_layer(1, 0);
492 layout.set_layer_name(&layer1, Some("metal1".into()));
493
494 let layer2 = layout.create_layer(2, 0);
495 layout.set_layer_name(&layer2, Some("metal2".into()));
496
497 (layout, vec![layer1, layer2])
498 }
499
500 #[test]
501 fn test_lef_rule_adapter_pitch() {
502 let lef = read_lef_chars(LEF_DATA.chars()).expect("Failed to parse LEF");
503
504 let (layout, layers) = create_empty_layout();
505 let layer1 = &layers[0];
506
507 let rules = LEFDesignRuleAdapter::new(&lef, &layout);
508
509 dbg!(rules.layer_mapping[layer1]);
510
511 assert_eq!(rules.default_pitch(layer1), Some((190, 190)));
513 assert_eq!(rules.default_pitch_preferred_direction(layer1), Some(190));
514 }
515
516 #[test]
517 fn test_lef_rule_adapter_min_width() {
518 let lef = read_lef_chars(LEF_DATA.chars()).expect("Failed to parse LEF");
519
520 let (layout, layers) = create_empty_layout();
521 let layer1 = &layers[0];
522
523 let rules = LEFDesignRuleAdapter::new(&lef, &layout);
524
525 dbg!(rules.layer_mapping[layer1]);
526
527 assert_eq!(rules.min_width(layer1, None), Some(50));
529 }
530
531 #[test]
532 fn test_lef_rule_adapter_default_width() {
533 let lef = read_lef_chars(LEF_DATA.chars()).expect("Failed to parse LEF");
534
535 let (layout, layers) = create_empty_layout();
536 let layer1 = &layers[0];
537
538 let rules = LEFDesignRuleAdapter::new(&lef, &layout);
539
540 dbg!(rules.layer_mapping[layer1]);
541
542 assert_eq!(rules.default_width(layer1, None), Some(65));
544 }
545
546 #[test]
547 fn test_lef_rule_adapter_spacing_table() {
548 let lef = read_lef_chars(LEF_DATA.chars()).expect("Failed to parse LEF");
549
550 let (layout, layers) = create_empty_layout();
551 let layer1 = &layers[0];
552 let layer2 = &layers[1];
553
554 let rules = LEFDesignRuleAdapter::new(&lef, &layout);
555
556 assert_eq!(rules.min_spacing_absolute(layer1), Some(100));
559
560 assert_eq!(rules.min_spacing(layer1, 0, 0), Some(100));
561
562 assert_eq!(rules.min_spacing(layer1, 999, 0), Some(100));
563 assert_eq!(rules.min_spacing(layer1, 1000, 0), Some(300));
564
565 assert_eq!(rules.min_spacing(layer1, 0, 499), Some(100));
566 assert_eq!(rules.min_spacing(&layer1, 0, 500), Some(400));
567 }
568
569 #[test]
570 fn test_lef_rule_adapter_min_spacing() {
571 let lef = read_lef_chars(LEF_DATA.chars()).expect("Failed to parse LEF");
572
573 let (layout, layers) = create_empty_layout();
574 let layer1 = &layers[0];
575 let layer2 = &layers[1];
576
577 let rules = LEFDesignRuleAdapter::new(&lef, &layout);
578
579 dbg!(rules.layer_mapping[layer2]);
580
581 assert_eq!(rules.min_spacing(layer2, 0, 0), Some(75));
583 assert_eq!(rules.min_spacing_absolute(layer2), Some(75));
584 }
585}