1#![allow(unused_variables)]
10
11use crate::common::*;
12use crate::def_ast::*;
13use crate::stream_parser::LefDefLexer;
14pub use crate::stream_parser::LefDefParseError;
15use itertools::PeekingNext;
16use libreda_db::prelude as db;
17use libreda_stream_parser::{tokenize, Tokenized};
18use std::collections::BTreeMap;
19use std::io::Read;
20use std::str::FromStr;
21
22#[derive(Copy, Clone, Default, Debug)]
24pub struct DEFReaderConfig {
25 pub ignore_non_fatal_errors: bool,
27}
28
29pub fn read_def_bytes<R: Read>(reader: &mut R) -> Result<DEF, LefDefParseError> {
31 read_def_chars(reader.bytes().map(|b| b.unwrap() as char))
32}
33
34pub fn read_def_bytes_with_config<R: Read>(
36 config: &DEFReaderConfig,
37 reader: &mut R,
38) -> Result<DEF, LefDefParseError> {
39 read_def_chars_with_config(config, reader.bytes().map(|b| b.unwrap() as char))
40}
41
42pub fn read_def_chars<I>(chars: I) -> Result<DEF, LefDefParseError>
45where
46 I: Iterator<Item = char>,
47{
48 read_def_chars_with_config(&DEFReaderConfig::default(), chars)
49}
50
51pub fn read_def_chars_with_config<I>(
53 config: &DEFReaderConfig,
54 chars: I,
55) -> Result<DEF, LefDefParseError>
56where
57 I: Iterator<Item = char>,
58{
59 let mut line_num = 1;
60 let mut char_num = 1; let line_count = chars.inspect(|&c| {
64 char_num += 1;
65 if c == '\n' {
66 line_num += 1;
67 char_num = 0;
68 }
69 });
70
71 let result = read_def_impl(config, line_count);
72
73 if result.is_err() {
74 log::error!("DEF error on line: {} (at {})", line_num, char_num);
75 }
76
77 result
78}
79
80fn read_regular_wiring<I: Iterator<Item = char> + PeekingNext>(
83 tk: &mut Tokenized<I, LefDefLexer>,
84) -> Result<RegularWiring, LefDefParseError> {
85 let wiring_class: WiringClass = tk.take_and_parse()?;
86
87 let mut wiring = RegularWiring {
88 class: wiring_class,
89 wiring: vec![],
90 };
91
92 loop {
94 let layer_name = tk.take_str()?;
95
96 let mut wiring_statement = RegularWiringStatement {
97 start_layer_name: layer_name,
98 style_num: 0,
99 taper_rule: None,
100 routing_points: vec![],
101 };
102
103 if tk.test_str("TAPER")? {
104 } else if tk.test_str("TAPERRULE")? {
105 wiring_statement.taper_rule = Some(tk.take_str()?);
106 }
107
108 if tk.test_str("STYLE")? {
109 wiring_statement.style_num = tk.take_and_parse()?;
110 }
111
112 let mut prev_point: Option<(db::Coord, db::Coord)> = None;
115
116 fn read_path_point<T: FromStr + Copy, I: Iterator<Item = char> + PeekingNext>(
119 tk: &mut Tokenized<I, LefDefLexer>,
120 prev_point: &Option<(T, T)>,
121 ) -> Result<((T, T), Option<T>), LefDefParseError> {
122 tk.expect_str("(")?;
124 let x = if tk.test_str("*")? {
125 prev_point
127 .ok_or(LefDefParseError::Other(
128 "x-coordinate not yet defined. Cannot use '*'.",
129 ))?
130 .0
131 } else {
132 tk.take_and_parse()?
134 };
135 let y = if tk.test_str("*")? {
136 prev_point
138 .ok_or(LefDefParseError::Other(
139 "x-coordinate not yet defined. Cannot use '*'.",
140 ))?
141 .1
142 } else {
143 tk.take_and_parse()?
145 };
146
147 let ext_value = if !tk.test_str(")")? {
148 let ext_value = tk.take_and_parse()?;
150 tk.expect_str(")")?;
151 Some(ext_value)
152 } else {
153 None
154 };
155
156 Ok(((x, y), ext_value))
157 }
158
159 let (p, extvalue) = read_path_point(tk, &prev_point)?;
161 wiring_statement.routing_points.push(RoutingPoint::Point {
162 point: p.into(),
163 ext_value: None,
164 mask_num: None,
165 });
166 prev_point = Some(p);
167
168 while !tk.peeking_test_str(";")? && !tk.peeking_test_str("NEW")? {
171 let mut mask_num: Option<u8> = None;
172 let mut via_mask_num: Option<ViaMaskNum> = None;
173
174 if tk.test_str("VIRTUAL")? {
175 let (p, _extvalue) = read_path_point(tk, &prev_point)?;
177 prev_point = Some(p);
179 wiring_statement
180 .routing_points
181 .push(RoutingPoint::Virtual(p.into()));
182 } else {
183 let mut expect_via = false;
184 if tk.test_str("MASK")? {
185 if tk.current_token_str().map(|s| s.len()) == Some(3) {
186 via_mask_num = Some(tk.take_and_parse()?);
188 expect_via = true;
189 } else {
190 mask_num = Some(tk.take_and_parse()?);
192 }
193 }
194
195 if expect_via || !tk.peeking_test_str("(")? {
196 if !expect_via && tk.test_str("RECT")? {
197 tk.expect_str("(")?;
199 let delta_x1: db::Coord = tk.take_and_parse()?;
200 let delta_y1: db::Coord = tk.take_and_parse()?;
201 let delta_x2: db::Coord = tk.take_and_parse()?;
202 let delta_y2: db::Coord = tk.take_and_parse()?;
203 tk.expect_str(")")?;
204
205 let d1 = db::Vector::new(delta_x1, delta_y1);
206 let d2 = db::Vector::new(delta_x2, delta_y2);
207
208 let current_point: db::Point<_> = prev_point
209 .ok_or_else(|| LefDefParseError::Other("Appearance of 'RECT' in a route but no current path point is defined.".into()))?
210 .into();
211
212 let rect = db::Rect::new(current_point + d1, current_point + d2);
213 todo!("Store the rectangle");
214 wiring_statement
215 .routing_points
216 .push(RoutingPoint::Rect { rect, mask_num });
217 } else {
218 let via_name = tk.take_str()?;
220 let orient: Option<Orient> = if !tk.peeking_test_str("NEW")?
221 && !tk.peeking_test_str(";")?
222 && !tk.peeking_test_str("(")?
223 && !tk.peeking_test_str("+")?
224 {
225 Some(tk.take_and_parse()?)
226 } else {
227 None
228 };
229
230 wiring_statement.routing_points.push(RoutingPoint::Via {
231 via_name,
232 orient,
233 via_mask_num,
234 });
235 }
236 } else {
237 let (p, ext_value) = read_path_point(tk, &prev_point)?;
238 prev_point = Some(p.into());
239
240 wiring_statement.routing_points.push(RoutingPoint::Point {
241 point: p.into(),
242 ext_value,
243 mask_num,
244 });
245 }
246 }
247 }
248
249 wiring.wiring.push(wiring_statement);
251
252 if !tk.test_str("NEW")? {
253 break;
254 } else {
255 }
257 }
258
259 return Ok(wiring);
260}
261
262fn read_vias<I: Iterator<Item = char> + PeekingNext>(
264 tk: &mut Tokenized<I, LefDefLexer>,
265) -> Result<BTreeMap<String, ViaDefinition>, LefDefParseError> {
266 let mut via_definitions: BTreeMap<String, ViaDefinition> = Default::default();
267
268 tk.expect_str("VIAS")?;
269 let num_vias: u32 = tk.take_and_parse()?;
270 tk.expect_str(";")?;
271
272 while tk.test_str("-")? {
273 let via_name = tk.take_str()?;
274
275 while tk.test_str("+")? {
276 if tk.test_str("VIARULE")? {
277 return Err(LefDefParseError::NotImplemented("VIAS/VIARULE"));
278 } else {
279 let mut via_geometries = Vec::new();
280
281 if tk.test_str("RECT")? {
282 let layer = tk.take_str()?;
283 let mask_num = if tk.test_str("MASK")? {
284 Some(tk.take_and_parse()?)
285 } else {
286 None
287 };
288 let (p1, p2) = read_rect(tk)?;
289 let rect = db::Rect::new(p1, p2);
290 via_geometries.push(ViaGeometry {
291 layer,
292 mask_num,
293 shape: RectOrPolygon::Rect(rect),
294 });
295 } else if tk.test_str("POLYGON")? {
296 let layer = tk.take_str()?;
297 let mask_num = if tk.test_str("MASK")? {
298 Some(tk.take_and_parse()?)
299 } else {
300 None
301 };
302 let points: Vec<(db::Coord, _)> = read_polygon(tk)?;
303 let points = points.into_iter().map(|p| p.into()).collect();
304 let polygon = db::SimplePolygon::new(points);
305 via_geometries.push(ViaGeometry {
306 layer,
307 mask_num,
308 shape: RectOrPolygon::Polygon(polygon),
309 });
310 } else {
311 return Err(LefDefParseError::UnexpectedToken(
312 "RECT, POLYGON".into(),
313 tk.take_str()?,
314 ));
315 }
316
317 let via_def = ViaDefinition::ViaGeometry(via_geometries);
318 via_definitions.insert(via_name.clone(), via_def);
319 }
320 }
321 tk.expect_str(";")?;
322 }
323
324 tk.expect_str("END")?;
325 tk.expect_str("VIAS")?;
326
327 Ok(via_definitions)
328}
329
330fn read_def_impl<I>(config: &DEFReaderConfig, chars: I) -> Result<DEF, LefDefParseError>
332where
333 I: Iterator<Item = char>,
334{
335 let mut design = DEF::default();
336
337 let mut tk = tokenize(chars, LefDefLexer {});
339 tk.advance();
340
341 loop {
342 if tk.test_str("END")? {
343 tk.expect_str("DESIGN")?;
345 break;
346 } else if tk.test_str("VERSION")? {
347 let version = tk.take_str()?;
348 design.version = Some(version);
349 tk.expect_str(";")?;
350 } else if tk.test_str("BUSBITCHARS")? {
351 let chars = tk.take_str()?;
352
353 if chars.len() == 2 {
354 let start = chars.chars().nth(0).unwrap();
355 let end = chars.chars().nth(1).unwrap();
356
357 if start == end {
358 log::error!("Bus bit chars cannot be equal: {}", start);
359 return Err(LefDefParseError::IllegalBusBitChars(start, end));
360 }
361
362 log::debug!("Bus bit chars: '{}' '{}'", start, end);
363 design.busbitchars = (start, end);
364 } else {
365 return Err(LefDefParseError::InvalidCharacter); }
367
368 tk.expect_str(";")?;
369 } else if tk.test_str("NAMESCASESENSITIVE")? {
370 tk.expect_str("ON")
371 .map_err(|_| LefDefParseError::Other("Support only NAMESCASESENSITIVE ON."))?;
372 tk.expect_str(";")?;
374 } else if tk.test_str("DIVIDERCHAR")? {
375 let divchar = tk.take_str()?;
376
377 if divchar.len() == 1 {
378 design.dividerchar = divchar.chars().nth(0).unwrap();
379 log::debug!("Divider char: '{}'", design.dividerchar);
380 } else {
381 return Err(LefDefParseError::InvalidCharacter); }
383
384 tk.expect_str(";")?;
385 } else if tk.test_str("DESIGN")? {
386 let design_name = tk.take_str()?;
387 tk.expect_str(";")?;
388 design.design_name = Some(design_name);
389 } else if tk.test_str("TECHNOLOGY")? {
390 let tech_name = tk.take_str()?;
391 tk.expect_str(";")?;
392 design.technology = Some(tech_name);
393 } else if tk.test_str("UNITS")? {
394 tk.expect_str("DISTANCE")?;
395 tk.expect_str("MICRONS")?;
396 let units = tk.take_and_parse()?;
397 tk.expect_str(";")?;
398 design.units = units;
399 } else if tk.test_str("HISTORY")? {
400 let mut text = String::new();
401 while !tk.test_str(";")? {
403 if let Some(s) = tk.current_token_str() {
404 if !text.is_empty() {
405 text.push(' '); }
407 text.extend(s.chars());
408 }
409 tk.advance();
410 }
411 design.history.push(text);
412 } else if tk.test_str("PROPERTYDEFINITIONS")? {
413 loop {
414 if tk.test_str("END")? {
415 tk.expect_str("PROPERTYDEFINITIONS")?;
416 break;
417 } else {
418 let property_object_type: DEFPropertyObjectType = tk.take_and_parse()?;
419 let property_name = tk.take_str()?;
420 let property_type: PropertyType = tk.take_and_parse()?;
421
422 let mut range = None;
424 let mut default_value = None;
425 match property_type {
426 PropertyType::Integer => {
427 if tk.test_str("RANGE")? {
428 let min = tk.take_and_parse()?;
430 let max = tk.take_and_parse()?;
431
432 range = Some((PropertyValue::Int(min), PropertyValue::Int(max)));
433 }
434
435 if !tk.peeking_test_str(";")? {
436 let default = tk.take_and_parse()?;
437 default_value = Some(PropertyValue::Int(default));
438 }
439 tk.expect_str(";")?;
440 }
441 PropertyType::Real => {
442 if tk.test_str("RANGE")? {
443 let min = tk.take_and_parse()?;
445 let max = tk.take_and_parse()?;
446
447 range = Some((PropertyValue::Real(min), PropertyValue::Real(max)));
448 }
449 if !tk.peeking_test_str(";")? {
450 let default = tk.take_and_parse()?;
451 default_value = Some(PropertyValue::Real(default));
452 }
453 }
454 PropertyType::String => {
455 if !tk.peeking_test_str(";")? {
458 let default = tk.take_str()?;
459 default_value = Some(PropertyValue::String(default));
460 }
461 }
462 }
463 tk.expect_str(";")?;
464
465 let property_definition = DEFPropertyDefinition {
466 object_type: property_object_type,
467 property_type,
468 range,
469 default_value,
470 };
471
472 design
474 .property_definitions
475 .insert(property_name, property_definition);
476 }
477 }
478 log::warn!("Skipping PROPERTYDEFINITIONS.");
479 } else if tk.test_str("DIEAREA")? {
480 let points = read_polygon(&mut tk)?;
482 let points: Vec<db::Point<db::SInt>> = points.into_iter().map(|p| p.into()).collect();
483
484 let die_area = if points.len() < 2 {
485 log::error!("DIEAREA must consist of two or more points.");
487 return Err(LefDefParseError::Other(
488 "Illegal die area. Must have two or more vertices.",
489 ));
490 } else if points.len() == 2 {
491 let rect: db::Rect<db::SInt> = db::Rect::new(points[0], points[1]);
493 let poly = db::SimpleRPolygon::from(rect);
494 poly
495 } else {
496 let poly = db::SimpleRPolygon::try_new(&points);
498 if poly.is_none() {
499 log::error!("DIEAREA polygon is not rectilinear.");
500 }
501 if config.ignore_non_fatal_errors {
502 poly.unwrap_or(db::SimpleRPolygon::empty())
503 } else {
504 poly.ok_or(LefDefParseError::Other(
505 "DIEAREA polygon is not rectilinear.",
506 ))?
507 }
508 };
509 design.die_area = Some(die_area);
510 } else if tk.test_str("ROW")? {
511 let row_name = tk.take_str()?;
512 let site_name = tk.take_str()?;
513 let orig_x: db::Coord = tk.take_and_parse()?;
514 let orig_y: db::Coord = tk.take_and_parse()?;
515 let site_orient: Orient = tk.take_and_parse()?;
517 let mut step_pattern = RowStepPattern::default();
518 if tk.test_str("DO")? {
519 step_pattern.num_x = tk.take_and_parse()?;
520 tk.expect_str("BY")?;
521 step_pattern.num_y = tk.take_and_parse()?;
522 if tk.test_str("STEP")? {
523 let step_x = tk.take_and_parse()?;
524 let step_y = tk.take_and_parse()?;
525 step_pattern.step = Some((step_x, step_y));
526 }
527 }
528 let mut properties = BTreeMap::new();
530 while tk.test_str("+")? {
531 tk.expect_str("PROPERTY")?;
532 while !tk.peeking_test_str("+")? {
533 if let Some((name, value)) =
534 read_def_property(&mut design.property_definitions, &mut tk)?
535 {
536 properties.insert(name, value);
538 }
539 }
540 }
541
542 let row = Row {
544 site_name,
545 orig: (orig_x, orig_y),
546 site_orient,
547 step_pattern,
548 properties,
549 };
550
551 tk.expect_str(";")?;
552
553 design.rows.insert(row_name, row);
555 } else if tk.test_str("TRACKS")? {
556 let is_horizontal = tk.test_str("Y")?;
557 if !is_horizontal {
558 tk.expect_str("X")?;
559 }
560 let start = tk.take_and_parse()?;
562 tk.expect_str("DO")?;
563 let num_tracks = tk.take_and_parse()?;
564 tk.expect_str("STEP")?;
565 let step = tk.take_and_parse()?; let mask = if tk.test_str("MASK")? {
568 let mask_num = tk.take_and_parse()?;
569 let same_mask = tk.test_str("SAMEMASK")?;
570 Some((mask_num, same_mask))
571 } else {
572 None
573 };
574
575 let mut layers = Vec::new();
576 if tk.test_str("LAYER")? {
577 while !tk.peeking_test_str(";")? {
578 let layer_name = tk.take_str()?;
580 layers.push(layer_name);
581 }
582 }
583
584 tk.expect_str(";")?;
585
586 let tracks = Tracks {
587 is_horizontal,
588 start,
589 num_tracks,
590 step,
591 mask,
592 layers,
593 };
594
595 design.tracks.push(tracks);
597 } else if tk.test_str("GCELLGRID")? {
598 let is_horizontal = tk.test_str("Y")?;
599 if !is_horizontal {
600 tk.expect_str("X")?;
601 }
602
603 let start: db::SInt = tk.take_and_parse()?;
605 tk.expect_str("DO")?;
606 let num_tracks: u32 = tk.take_and_parse()?;
607 tk.expect_str("STEP")?;
608 let space: db::SInt = tk.take_and_parse()?; tk.expect_str(";")?;
611
612 design.gcell_grid.push(());
614 } else if tk.peeking_test_str("VIAS")? {
615 design.vias = read_vias(&mut tk)?;
616 } else if tk.test_str("STYLES")? {
617 return Err(LefDefParseError::NotImplemented("STYLES"));
618 } else if tk.test_str("NONDEFAULTRULES")? {
619 return Err(LefDefParseError::NotImplemented("NONDEFAULTRULES"));
620 } else if tk.test_str("REGIONS")? {
621 let _num_regions: u32 = tk.take_and_parse()?;
622
623 while tk.test_str("-")? {
624 let mut region = Region::default();
625 let region_name = tk.take_str()?;
626 while !tk.peeking_test_str("+")? {
627 let p1 = read_point(&mut tk)?;
629 let p2 = read_point(&mut tk)?;
630 let rect: db::Rect<db::SInt> = db::Rect::new(p1, p2);
631 region.regions.push(rect);
632 }
633
634 while tk.test_str("+")? {
635 if tk.test_str("TYPE")? {
636 region.region_type = Some(tk.take_and_parse()?);
637 } else if tk.test_str("PROPERTY")? {
638 while !tk.peeking_test_str("+")? {
639 if let Some((name, value)) =
640 read_def_property(&mut design.property_definitions, &mut tk)?
641 {
642 }
644 }
645 }
646 }
647
648 design.regions.insert(region_name, region);
649 }
650
651 tk.expect_str("END")?;
652 tk.expect_str("REGIONS")?;
653 } else if tk.test_str("COMPONENTMASKSHIFT")? {
654 return Err(LefDefParseError::NotImplemented("COMPONENTMASKSHIFT"));
655 } else if tk.test_str("COMPONENTS")? {
656 let num_components: u32 = tk.take_and_parse()?;
657 design.components.reserve(num_components as usize);
658 tk.expect_str(";")?;
659
660 while tk.test_str("-")? {
661 let mut component = Component::default();
662
663 component.name = tk.take_str()?;
664 component.model_name = tk.take_str()?;
665
666 while tk.test_str("+")? {
667 if tk.test_str("EEQMASTER")? {
668 component.eeq_master = Some(tk.take_str()?);
669 } else if tk.test_str("SOURCE")? {
670 component.source = tk.take_and_parse()?;
671 } else if tk.test_str("FIXED")? {
672 let point: (db::SInt, db::SInt) = read_point(&mut tk)?;
674 let orient: Orient = tk.take_and_parse()?;
675 component.position = Some((point.into(), orient, true));
676 } else if tk.test_str("COVER")? {
677 let point: (db::SInt, db::SInt) = read_point(&mut tk)?;
679 let orient: Orient = tk.take_and_parse()?;
680 component.position = Some((point.into(), orient, true));
681 } else if tk.test_str("PLACED")? {
682 let point: (db::SInt, db::SInt) = read_point(&mut tk)?;
684 let orient: Orient = tk.take_and_parse()?;
685 component.position = Some((point.into(), orient, false));
686 } else if tk.test_str("UNPLACED")? {
687 component.position = None;
689 } else if tk.test_str("HALO")? {
690 let soft = tk.test_str("SOFT")?;
691 let left = tk.take_and_parse()?;
692 let bottom = tk.take_and_parse()?;
693 let right = tk.take_and_parse()?;
694 let top = tk.take_and_parse()?;
695 component.halo = Some((soft, left, bottom, right, top));
696 } else if tk.test_str("ROUTEHALO")? {
697 let halo_dist: db::SInt = tk.take_and_parse()?;
698 let min_layer = tk.take_str()?;
699 let max_layer = tk.take_str()?;
700 } else if tk.test_str("WEIGHT")? {
702 component.weight = tk.take_and_parse()?;
706 } else if tk.test_str("REGION")? {
707 let region_name = tk.take_str()?;
712
713 if let Some(region) = design.regions.get(®ion_name) {
714 component.region = Some(region_name);
716 } else {
717 log::error!(
719 "Ignore region statement. No such region: '{}'",
720 ®ion_name
721 );
722 }
723 } else if tk.test_str("PROPERTY")? {
724 while !tk.peeking_test_str("+")? {
725 if let Some((name, value)) =
726 read_def_property(&mut design.property_definitions, &mut tk)?
727 {
728 component.properties.insert(name, value);
730 }
731 }
732 } else {
733 return Err(LefDefParseError::UnknownToken(
734 tk.current_token_str().unwrap(),
735 ));
736 }
737 }
738
739 tk.expect_str(";")?;
740
741 design.components.push(component);
742 }
743 tk.expect_str("END")?;
744 tk.expect_str("COMPONENTS")?;
745 } else if tk.test_str("PINS")? {
746 let num_pins: usize = tk.take_and_parse()?;
747 tk.expect_str(";")?;
748
749 while tk.test_str("-")? {
750 let mut pin = Pin::default();
751 pin.pin_name = tk.take_str()?;
752 tk.expect_str("+")?;
753 tk.expect_str("NET")?;
754 pin.net_name = tk.take_str()?;
755
756 let mut current_port: Option<PinPort> = None;
757
758 while tk.test_str("+")? {
759 if tk.test_str("SPECIAL")? {
760 pin.special = true;
761 } else if tk.test_str("DIRECTION")? {
762 pin.direction = Some(tk.take_and_parse()?);
763 } else if tk.test_str("NETEXPR")? {
764 pin.net_expr = Some(tk.take_str()?);
765 } else if tk.test_str("SUPPLYSENSITIVITY")? {
766 pin.supply_sensitivity = Some(tk.take_str()?);
767 } else if tk.test_str("GROUNDSENSITIVITY")? {
768 pin.ground_sensitivity = Some(tk.take_str()?);
769 } else if tk.test_str("USE")? {
770 pin.signal_use = tk.take_and_parse()?;
771 } else if tk.test_str("PORT")? {
772 if let Some(port) = current_port.take() {
773 pin.ports.push(port);
774 };
775 current_port = Some(PinPort::default()); let port = current_port.as_mut().unwrap();
777 } else if tk.test_str("LAYER")? {
778 let layer_name = tk.take_str()?;
779
780 let mask_num = if tk.test_str("MASK")? {
781 Some(tk.take_and_parse()?)
782 } else {
783 None
784 };
785
786 let mut spacing_or_width = None;
787 if tk.test_str("SPACING")? {
788 let min_spacing = tk.take_and_parse()?;
789 spacing_or_width =
790 Some(SpacingOrDesignRuleWidth::MinSpacing(min_spacing));
791 }
792 if tk.test_str("DESIGNRULEWIDTH")? {
793 let effective_width = tk.take_and_parse()?;
794 spacing_or_width =
795 Some(SpacingOrDesignRuleWidth::DesignRuleWidth(effective_width));
796 }
797
798 let p1: (db::SInt, db::SInt) = read_point(&mut tk)?;
799 let p2: (db::SInt, db::SInt) = read_point(&mut tk)?;
800 let rect = db::Rect::new(p1, p2);
801
802 current_port
803 .get_or_insert(Default::default())
804 .port_statements
805 .push(PinPortStatement::Layer {
806 layer_name,
807 mask_num,
808 spacing_or_width,
809 rect,
810 });
811 } else if tk.test_str("POLYGON")? {
812 let layer_name = tk.take_str()?;
813
814 let mask_num = if tk.test_str("MASK")? {
815 Some(tk.take_and_parse()?)
816 } else {
817 None
818 };
819
820 let mut spacing_or_width = None;
821 if tk.test_str("SPACING")? {
822 let min_spacing = tk.take_and_parse()?;
823 spacing_or_width =
824 Some(SpacingOrDesignRuleWidth::MinSpacing(min_spacing));
825 }
826 if tk.test_str("DESIGNRULEWIDTH")? {
827 let effective_width = tk.take_and_parse()?;
828 spacing_or_width =
829 Some(SpacingOrDesignRuleWidth::DesignRuleWidth(effective_width));
830 }
831
832 let points = read_polygon(&mut tk)?;
833 let polygon = points.into_iter().collect();
834
835 current_port
836 .get_or_insert(Default::default())
837 .port_statements
838 .push(PinPortStatement::Polygon {
839 layer_name,
840 mask_num,
841 spacing_or_width,
842 polygon,
843 });
844 } else if tk.test_str("VIA")? {
845 let port = current_port.as_mut().unwrap();
846
847 let via_name = tk.take_str()?;
848
849 let mask_num = if tk.test_str("MASK")? {
850 Some(tk.take_and_parse()?)
853 } else {
854 None
855 };
856
857 let location: (db::SInt, db::SInt) = read_point(&mut tk)?;
858
859 current_port
860 .get_or_insert(Default::default())
861 .port_statements
862 .push(PinPortStatement::Via {
863 via_name,
864 mask_num,
865 location: location.into(),
866 });
867 } else if tk.test_str("ANTENNAPINPARTIALMETALAREA")? {
868 return Err(LefDefParseError::NotImplemented(
869 "ANTENNAPINPARTIALMETALAREA",
870 ));
871 } else if tk.test_str("ANTENNAPINPARTIALMETALSIDEAREA")? {
872 return Err(LefDefParseError::NotImplemented(
873 "ANTENNAPINPARTIALMETALSIDEAREA",
874 ));
875 } else if tk.test_str("ANTENNAPINPARTIALCUTAREA")? {
876 return Err(LefDefParseError::NotImplemented("ANTENNAPINPARTIALCUTAREA"));
877 } else if tk.test_str("ANTENNAPINDIFFAREA")? {
878 return Err(LefDefParseError::NotImplemented("ANTENNAPINDIFFAREA"));
879 } else if tk.test_str("ANTENNAPINDIFFAREA")? {
880 return Err(LefDefParseError::NotImplemented("ANTENNAPINDIFFAREA"));
881 } else if tk.test_str("ANTENNAMODEL")? {
882 return Err(LefDefParseError::NotImplemented("ANTENNAMODEL"));
883 } else if tk.test_str("ANTENNAPINGATEAREA")? {
884 return Err(LefDefParseError::NotImplemented("ANTENNAPINGATEAREA"));
885 } else if tk.test_str("ANTENNAPINMAXAREACAR")? {
886 return Err(LefDefParseError::NotImplemented("ANTENNAPINMAXAREACAR"));
887 } else if tk.test_str("ANTENNAPINMAXSIDEAREACAR")? {
888 return Err(LefDefParseError::NotImplemented("ANTENNAPINMAXSIDEAREACAR"));
889 } else if tk.test_str("ANTENNAPINMAXCUTCAR")? {
890 return Err(LefDefParseError::NotImplemented("ANTENNAPINMAXCUTCAR"));
891 } else {
892 return Err(LefDefParseError::UnexpectedToken(
893 "".to_string(),
894 tk.current_token_str().unwrap(),
895 ));
896 }
897 }
898
899 if let Some(port) = current_port.take() {
901 pin.ports.push(port);
902 };
903
904 design.pins.push(pin);
905 }
906
907 if design.pins.len() != num_pins {
908 log::debug!(
909 "Mismatch in announced number of pins ({}) and actual number of pins ({}).",
910 num_pins,
911 design.pins.len()
912 );
913 }
914
915 tk.expect_str("END")?;
916 tk.expect_str("PINS")?;
917 } else if tk.test_str("PINPROPERTIES")? {
918 return Err(LefDefParseError::NotImplemented("PINPROPERTIES"));
919 } else if tk.test_str("BLOCKAGES")? {
920 let num_blockages: u32 = tk.take_and_parse()?;
921 design.blockages.reserve(num_blockages as usize);
922 tk.expect_str(";")?;
923
924 while tk.test_str("-")? {
925 if tk.test_str("LAYER")? {
926 let mut blk = LayerBlockage::default();
927 blk.layer = tk.take_str()?;
928
929 while tk.test_str("+")? {
930 if tk.test_str("SLOTS")? {
931 blk.slots = true;
932 } else if tk.test_str("FILLS")? {
933 blk.fills = true;
934 } else if tk.test_str("PUSHDOWN")? {
935 blk.pushdown = true;
936 } else if tk.test_str("EXCEPTPGNET")? {
937 blk.except_pg_net = true;
938 } else if tk.test_str("COMPONENT")? {
939 blk.component = Some(tk.take_str()?);
940 } else if tk.test_str("SPACING")? {
941 let spacing = tk.take_and_parse()?;
942 blk.spacing_or_designrule_width =
943 Some(SpacingOrDesignRuleWidth::MinSpacing(spacing));
944 } else if tk.test_str("DESIGNRULEWIDTH")? {
945 let width = tk.take_and_parse()?;
946 blk.spacing_or_designrule_width =
947 Some(SpacingOrDesignRuleWidth::DesignRuleWidth(width));
948 } else if tk.test_str("MASK")? {
949 let mask_num = tk.take_and_parse()?;
950 blk.mask_num = Some(mask_num);
951 } else {
952 return Err(LefDefParseError::UnexpectedToken(
953 "SLOTS, FILLS, PUSHDOWN, EXCEPTPGNET, SPACING, DESIGNRULEWIDTH or MASK".to_string(),
954 tk.current_token_str().unwrap(),
955 ));
956 }
957 }
958
959 while !tk.test_str(";")? {
960 if tk.test_str("RECT")? {
961 let (p1, p2) = read_rect(&mut tk)?;
962 let rect = db::Rect::new(p1, p2);
963 blk.blockage_shapes.push(RectOrPolygon::Rect(rect));
964 } else if tk.test_str("POLYGON")? {
965 let points = read_polygon(&mut tk)?;
966 let poly = db::SimplePolygon::from(points);
967 blk.blockage_shapes.push(RectOrPolygon::Polygon(poly));
968 } else {
969 return Err(LefDefParseError::UnexpectedToken(
970 "RECT or POLYGON".to_string(),
971 tk.current_token_str().unwrap(),
972 ));
973 }
974 }
975 design.blockages.push(Blockage::LayerBlockage(blk));
976 } else if tk.test_str("PLACEMENT")? {
977 let mut blk = PlacementBlockage::default();
978 while tk.test_str("+")? {
979 if tk.test_str("SOFT")? {
980 blk.blockage_type = Some(PlacementBlockageType::Soft);
981 } else if tk.test_str("PARTIAL")? {
982 let max_density = tk.take_and_parse()?;
983 blk.blockage_type = Some(PlacementBlockageType::Partial(max_density));
984 } else if tk.test_str("PUSHDOWN")? {
985 blk.pushdown = true;
986 } else if tk.test_str("COMPONENT")? {
987 blk.component = Some(tk.take_str()?);
988 } else {
989 return Err(LefDefParseError::UnexpectedToken(
990 "SOFT, PARTIAL, PUSHDOWN or COMPONENT".to_string(),
991 tk.current_token_str().unwrap(),
992 ));
993 }
994 }
995
996 while !tk.test_str(";")? {
997 tk.expect_str("RECT")?;
998 let (p1, p2) = read_rect(&mut tk)?;
999 let rect = db::Rect::new(p1, p2);
1000 blk.rects.push(rect);
1001 }
1002
1003 design.blockages.push(Blockage::PlacementBlockage(blk));
1004 } else {
1005 return Err(LefDefParseError::UnexpectedToken(
1006 "LAYER of PLACEMENT".to_string(),
1007 tk.current_token_str().unwrap(),
1008 ));
1009 }
1010 }
1011 tk.expect_str("END")?;
1012 tk.expect_str("BLOCKAGES")?;
1013 } else if tk.test_str("SLOTS")? {
1014 return Err(LefDefParseError::NotImplemented("SLOTS"));
1015 } else if tk.test_str("FILLS")? {
1016 return Err(LefDefParseError::NotImplemented("FILLS"));
1017 } else if tk.test_str("SPECIALNETS")? {
1018 return Err(LefDefParseError::NotImplemented("SPECIALNETS"));
1019 } else if tk.test_str("NETS")? {
1020 let _num_nets: u32 = tk.take_and_parse()?;
1021 tk.expect_str(";")?;
1022 while tk.test_str("-")? {
1025 let mut net = Net::default();
1026
1027 if tk.test_str("MUSTJOIN")? {
1028 let component_name = tk.take_str()?;
1029 let pin_name = tk.take_str()?;
1030
1031 net.mustjoin = Some(Mustjoin {
1032 component_name,
1033 pin_name,
1034 })
1035 } else {
1036 net.name = Some(tk.take_str()?);
1037
1038 while tk.test_str("(")? {
1039 let term = if tk.test_str("PIN")? {
1040 let pin_name = tk.take_str()?;
1041 NetTerminal::IoPin(pin_name)
1042 } else {
1043 let component_name = tk.take_str()?;
1044 let pin_name = tk.take_str()?;
1045 NetTerminal::ComponentPin {
1046 component_name,
1047 pin_name,
1048 }
1049 };
1050
1051 if tk.test_str("+")? {
1052 tk.expect_str("SYNTHESIZED")?;
1053 }
1055
1056 net.terminals.push(term);
1057
1058 tk.expect_str(")")?;
1059 }
1060
1061 while tk.test_str("+")? {
1062 if tk.test_str("SHIELDNET")? {
1063 net.shield_nets.push(tk.take_str()?);
1064 } else if tk.test_str("VPIN")? {
1065 return Err(LefDefParseError::NotImplemented("VPIN"));
1067 } else if tk.test_str("SUBNET")? {
1068 return Err(LefDefParseError::NotImplemented("SUBNET"));
1070 } else if tk.test_str("XTALK")? {
1071 net.xtalk_class = tk.take_and_parse()?;
1072 } else if tk.test_str("NONDEFAULTRULE")? {
1073 net.non_default_rule = Some(tk.take_str()?);
1074 } else if tk.peeking_test_str("COVER")?
1075 || tk.peeking_test_str("FIXED")?
1076 || tk.peeking_test_str("ROUTED")?
1077 || tk.peeking_test_str("NOSHIELD")?
1078 {
1079 let wiring = read_regular_wiring(&mut tk)?;
1082
1083 net.regular_wiring.push(wiring);
1085 } else if tk.test_str("SOURCE")? {
1086 net.source = tk.take_and_parse()?;
1087 } else if tk.test_str("FIXEDBUMP")? {
1088 net.fixed_bump = true;
1089 } else if tk.test_str("FREQUENCY")? {
1090 net.frequency = Some(tk.take_and_parse()?);
1091 } else if tk.test_str("ORIGINAL")? {
1092 net.original = Some(tk.take_str()?);
1093 } else if tk.test_str("USE")? {
1094 net.net_use = tk.take_and_parse()?;
1095 } else if tk.test_str("PATTERN")? {
1096 net.pattern = tk.take_and_parse()?;
1097 } else if tk.test_str("ESTCAP")? {
1098 net.est_cap = Some(tk.take_and_parse()?);
1099 } else if tk.test_str("WEIGHT")? {
1100 net.weight = tk.take_and_parse()?;
1101 } else if tk.test_str("PROPERTY")? {
1102 while !tk.peeking_test_str("+")? && !tk.peeking_test_str(";")? {
1103 if let Some((name, value)) =
1104 read_def_property(&mut design.property_definitions, &mut tk)?
1105 {
1106 net.properties.insert(name, value);
1108 }
1109 }
1110 } else {
1111 return Err(LefDefParseError::UnexpectedToken(
1112 "".to_string(),
1113 tk.current_token_str().unwrap(),
1114 ));
1115 }
1116 }
1117 }
1118 tk.expect_str(";")?; design.nets.push(net);
1121 }
1122
1123 tk.expect_str("END")?;
1124 tk.expect_str("NETS")?;
1125 } else if tk.test_str("SCANCHAINS")? {
1127 return Err(LefDefParseError::NotImplemented("SCANCHAINS"));
1128 } else if tk.test_str("GROUPS")? {
1129 let _num_groups: u32 = tk.take_and_parse()?;
1130
1131 while tk.test_str("-")? {
1135 let group_name = tk.take_str()?;
1136 let mut group = Group::default();
1137
1138 while !tk.peeking_test_str("+")? {
1140 let component = tk.take_str()?;
1141 group.component_names.push(component);
1142 }
1143
1144 while tk.test_str("+")? {
1145 if tk.test_str("REGION")? {
1146 let region_name = tk.take_str()?;
1147 group.region_name = Some(region_name);
1148 } else if tk.test_str("PROPERTY")? {
1149 while !tk.peeking_test_str("+")? {
1150 if let Some((name, value)) =
1151 read_def_property(&mut design.property_definitions, &mut tk)?
1152 {
1153 group.properties.insert(name, value);
1155 }
1156 }
1157 } else {
1158 return Err(LefDefParseError::UnexpectedToken(
1159 "REGION or PROPERTY".to_string(),
1160 tk.current_token_str().unwrap(),
1161 ));
1162 }
1163 }
1164
1165 design.groups.entry(group_name).or_default().push(group);
1167 }
1168
1169 tk.expect_str("END")?;
1170 tk.expect_str("GROUPS")?;
1171 } else if tk.test_str("BEGINEXT")? {
1172 tk.skip_until_str("ENDEXT")?;
1174 } else {
1175 return Err(LefDefParseError::UnknownToken(
1176 tk.current_token_str().unwrap(),
1177 ));
1178 }
1179 }
1180
1181 Ok(design)
1182}
1183
1184#[test]
1185fn test_read_def() {
1186 let data = r#"
1187VERSION 5.7 ;
1188DIVIDERCHAR "/" ;
1189BUSBITCHARS "[]" ;
1190DESIGN test_design ;
1191UNITS DISTANCE MICRONS 2000 ;
1192TECHNOLOGY FreePDK45 ;
1193
1194HISTORY This is a test. ;
1195HISTORY This is an other test. ;
1196
1197
1198PROPERTYDEFINITIONS
1199 COMPONENTPIN designRuleWidth REAL ;
1200 DESIGN testProperty REAL 0.123 ;
1201 DESIGN testProperty2 STRING "as df" ;
1202END PROPERTYDEFINITIONS
1203
1204DIEAREA ( 0 0 ) ( 10000 10000 ) ;
1205
1206COMPONENTS 3 ;
1207 - _1_ BUF_X2 ;
1208 - _2_ BUF_X2 ;
1209 - _3_ BUF_X2 ;
1210END COMPONENTS
1211
1212BLOCKAGES 3 ;
1213 - LAYER metal1
1214 RECT ( -100 200 ) ( 0 100 )
1215 RECT ( -200 200 ) ( 300 500 ) ;
1216
1217 - LAYER metal2 + PUSHDOWN + COMPONENT comp1 + EXCEPTPGNET + SPACING 10
1218 RECT ( -100 200 ) ( 0 100 )
1219 RECT ( -200 200 ) ( 300 500 ) ;
1220
1221 - PLACEMENT
1222 RECT ( -100 200 ) ( 0 100 )
1223 RECT ( -200 200 ) ( 300 500 ) ;
1224
1225 - PLACEMENT
1226 RECT ( -100 200 ) ( 0 100 )
1227 RECT ( -200 200 ) ( 300 500 ) ;
1228
1229 - LAYER metal3
1230 RECT ( -100 200 ) ( 0 100 )
1231 RECT ( -200 200 ) ( 300 500 ) ;
1232
1233END BLOCKAGES
1234
1235PINS 2 ;
1236- IN + NET IN
1237 + DIRECTION INPUT
1238- OUT + NET OUT
1239 + DIRECTION OUTPUT
1240END PINS
1241
1242NETS 6 ;
1243- IN ( PIN IN ) ;
1244- OUT ( PIN OUT ) ;
1245- net1 ( _1_ A ) ;
1246
1247# With more attributes:
1248
1249- net2 ( _2_ A ) ( _3_ B + SYNTHESIZED ) ( PIN OUT ) + SHIELDNET shieldnet1
1250 + XTALK 1
1251 + NONDEFAULTRULE nondefaultrule1
1252 + SOURCE TEST
1253 + FIXEDBUMP
1254 + FREQUENCY 1000000
1255 + ORIGINAL originalNet
1256 + USE ANALOG
1257 + PATTERN BALANCED
1258 + ESTCAP 0.123
1259 + WEIGHT 2
1260 + PROPERTY testProperty 3.14 testProperty2 someText
1261 + PROPERTY testProperty 3.14 testProperty2 someText
1262 ;
1263
1264# Net with simple wiring.
1265
1266- net2 ( _1_ A ) ( _2_ A )
1267 + ROUTED metal1 ( 0 0 ) ( 10 0 )
1268 ;
1269
1270- net3 ( _1_ A ) ( _2_ A )
1271 + ROUTED metal1 ( 0 0 ) ( 10 0 ) ( * 10 ) ( * 20 )
1272 NEW metal2 ( 0 0 ) ( 10 0 )
1273 ;
1274
1275
1276# Nets with vias.
1277- net4 ( _1_ A ) ( _2_ A )
1278 + ROUTED metal1 ( 0 0 ) ( 10 0 ) VIA12 ( * 20 ) ( 40 * )
1279 NEW metal2 ( 0 0 ) ( 10 0 )
1280 ;
1281
1282# Multi patterning
1283- net4 ( _1_ A ) ( _2_ A )
1284 + ROUTED metal1 ( 0 0 ) MASK 1 ( 10 0 ) MASK 012 VIA12 ( * 20 ) MASK 2 ( 40 * )
1285 NEW metal2 ( 0 0 ) MASK 1 ( 10 0 )
1286 ;
1287
1288END NETS
1289
1290BEGINEXT
1291 test 123 ;
1292ENDEXT
1293
1294END DESIGN
1295"#;
1296
1297 let result = read_def_chars(data.chars());
1298
1299 dbg!(&result);
1300
1301 assert!(result.is_ok());
1302}
1303
1304pub fn read_def_property<I>(
1310 property_definitions: &mut BTreeMap<String, DEFPropertyDefinition>,
1311 tk: &mut Tokenized<I, LefDefLexer>,
1312) -> Result<Option<(String, PropertyValue)>, LefDefParseError>
1313where
1314 I: Iterator<Item = char> + PeekingNext,
1315{
1316 let property_name = tk.take_str()?;
1317
1318 let property_def = property_definitions.get(&property_name);
1319
1320 if let Some(property_def) = property_def {
1321 let prop_value = match property_def.property_type {
1322 PropertyType::Integer => PropertyValue::Int(tk.take_and_parse()?),
1323 PropertyType::Real => PropertyValue::Real(tk.take_and_parse()?),
1324 PropertyType::String => PropertyValue::String(tk.take_str()?),
1325 };
1326
1327 Ok(Some((property_name, prop_value)))
1329 } else {
1330 log::error!("Property is not defined: '{}'", &property_name);
1331 tk.advance(); Ok(None)
1334 }
1335}