libreda_lefdef/
common.rs

1// Copyright (c) 2021-2021 Thomas Kramer.
2// SPDX-FileCopyrightText: 2022 Thomas Kramer <code@tkramer.ch>
3//
4// SPDX-License-Identifier: AGPL-3.0-or-later
5
6//! Data types and parser functions used for both LEF and DEF.
7
8use crate::stream_parser::{LefDefLexer, LefDefParseError};
9use itertools::PeekingNext;
10use libreda_stream_parser::{tokenize, Tokenized};
11use std::fmt;
12use std::str::FromStr;
13
14/// Data type of a property value.
15#[derive(Clone, Debug)]
16pub enum PropertyType {
17    /// Integer number.
18    Integer,
19    /// Floating point number.
20    Real,
21    /// String.
22    String,
23}
24
25impl FromStr for PropertyType {
26    type Err = ();
27
28    fn from_str(input: &str) -> Result<Self, Self::Err> {
29        match input {
30            "INTEGER" => Ok(Self::Integer),
31            "REAL" => Ok(Self::Real),
32            "STRING" => Ok(Self::String),
33            _ => Err(()),
34        }
35    }
36}
37
38impl fmt::Display for PropertyType {
39    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40        match self {
41            Self::Integer => f.write_str("INTEGER"),
42            Self::Real => f.write_str("REAL"),
43            Self::String => f.write_str("STRING"),
44        }
45    }
46}
47
48/// Value of a LEF/DEF property.
49#[derive(Clone, Debug)]
50pub enum PropertyValue {
51    /// Integer.
52    Int(i32),
53    /// Floating point number.
54    Real(f64),
55    /// Quoted ASCII string.
56    String(String),
57}
58
59impl fmt::Display for PropertyValue {
60    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61        match self {
62            PropertyValue::Int(v) => write!(f, "{}", v),
63            PropertyValue::Real(v) => write!(f, "{}", v),
64            PropertyValue::String(v) => write!(f, r#""{}""#, v),
65        }
66    }
67}
68
69/// Read a point of the form `( x y )`, `x y` or `( x , y )`.
70pub fn read_point<T: FromStr, I>(
71    tokens: &mut Tokenized<I, LefDefLexer>,
72) -> Result<(T, T), LefDefParseError>
73where
74    I: Iterator<Item = char> + PeekingNext,
75{
76    // Points should be declared in parenthesis. This is not always the case though.
77    let uses_parentheses = tokens.test_str("(")?;
78    let x: T = tokens.take_and_parse()?;
79    tokens.test_str(",")?;
80    let y: T = tokens.take_and_parse()?;
81    if uses_parentheses {
82        tokens.expect_str(")")?;
83    }
84
85    Ok((x, y))
86}
87
88/// Read a polygon. Does not expect 'POLYGON' token at the beginning.
89pub fn read_polygon<T: FromStr, I>(
90    tokens: &mut Tokenized<I, LefDefLexer>,
91) -> Result<Vec<(T, T)>, LefDefParseError>
92where
93    I: Iterator<Item = char> + PeekingNext,
94{
95    // Read points until ';'.
96    let mut points = Vec::new();
97    loop {
98        if tokens.test_str(";")? {
99            break;
100        } else {
101            points.push(read_point(tokens)?);
102        }
103    }
104
105    Ok(points)
106}
107
108/// Read a rectangle of the form `( x1 y1 ) ( x2 y2 )`.
109pub fn read_rect<T: FromStr, I>(
110    tokens: &mut Tokenized<I, LefDefLexer>,
111) -> Result<((T, T), (T, T)), LefDefParseError>
112where
113    I: Iterator<Item = char> + PeekingNext,
114{
115    let p1 = read_point(tokens)?;
116    let p2 = read_point(tokens)?;
117
118    Ok((p1, p2))
119}
120
121/// Macro orientations that can be used by the placer.
122#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
123pub struct Symmetry {
124    /// Mirroring macro at x-axis.
125    x: bool,
126    /// Mirroring macro at y-axis.
127    y: bool,
128    /// Rotating by 90 degrees. Intended for pad cells only.
129    r90: bool,
130}
131
132impl Symmetry {
133    /// Create a new symmetry definition.
134    pub fn new(x: bool, y: bool, r90: bool) -> Self {
135        Self { x, y, r90 }
136    }
137
138    /// Mirror symmetry at x-axis.
139    pub fn x() -> Self {
140        Self::new(true, false, false)
141    }
142    /// Mirror symmetry at y-axis.
143    pub fn y() -> Self {
144        Self::new(false, true, false)
145    }
146    /// Rotation by 90 degrees.
147    pub fn r90() -> Self {
148        Self::new(false, false, true)
149    }
150
151    /// Take the union of the both symmetry definitions.
152    pub fn union(self, other: Self) -> Self {
153        Self {
154            x: self.x | other.x,
155            y: self.y | other.y,
156            r90: self.r90 | other.r90,
157        }
158    }
159}
160
161impl FromStr for Symmetry {
162    type Err = ();
163
164    fn from_str(input: &str) -> Result<Self, Self::Err> {
165        match input {
166            "X" => Ok(Self::x()),
167            "Y" => Ok(Self::y()),
168            "R90" => Ok(Self::r90()),
169            _ => Err(()),
170        }
171    }
172}
173
174impl fmt::Display for Symmetry {
175    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176        if self.x {
177            f.write_str("X")?;
178        }
179        if self.y {
180            f.write_str("Y")?;
181        }
182        if self.r90 {
183            f.write_str("R90")?;
184        }
185
186        Ok(())
187    }
188}
189
190/// Antenna rule definitions.
191#[derive(Clone, Debug, Default)]
192pub struct AntennaRules {
193    /// Antenna model.
194    model: (),
195    area_ratio: (),
196    diff_area_ration: (),
197    cum_area_ratio: (),
198    cum_diff_area_ratio: (),
199    // ...
200}
201
202/// Orientation, consists of rotation and mirroring.
203#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
204pub enum Orient {
205    /// North.
206    N,
207    /// South.
208    S,
209    /// East.
210    E,
211    /// West.
212    W,
213    /// Flipped North.
214    FN,
215    /// Flipped South.
216    FS,
217    /// FLipped East.
218    FE,
219    /// Flipped West.
220    FW,
221}
222
223impl Default for Orient {
224    fn default() -> Self {
225        Self::N
226    }
227}
228
229impl Orient {
230    /// Decompose into a non-flipped orientation and a flag telling whether the orientation is flipped
231    /// or not.
232    /// Flipping is applied after rotation. Flips happen about the y-axis (switching left-right).
233    ///
234    /// Returns `(orientation, is_flipped)`.
235    pub fn decomposed(&self) -> (Self, bool) {
236        match self {
237            Orient::FN => (Orient::N, true),
238            Orient::FS => (Orient::S, true),
239            Orient::FE => (Orient::E, true),
240            Orient::FW => (Orient::W, true),
241            other => (*other, false),
242        }
243    }
244
245    /// Returns the flipped orientation.
246    /// For example turns a `N` into a `FN`.
247    pub fn flipped(&self) -> Self {
248        use Orient::*;
249        match self {
250            N => FN,
251            S => FS,
252            E => FE,
253            W => FW,
254            FN => N,
255            FS => S,
256            FE => E,
257            FW => W,
258        }
259    }
260}
261
262impl FromStr for Orient {
263    type Err = ();
264
265    fn from_str(input: &str) -> Result<Self, Self::Err> {
266        match input {
267            "N" => Ok(Self::N),
268            "S" => Ok(Self::S),
269            "E" => Ok(Self::E),
270            "W" => Ok(Self::W),
271            "FN" => Ok(Self::FN),
272            "FS" => Ok(Self::FS),
273            "FE" => Ok(Self::FE),
274            "FW" => Ok(Self::FW),
275            _ => Err(()),
276        }
277    }
278}
279
280impl fmt::Display for Orient {
281    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
282        match self {
283            Self::N => f.write_str("N"),
284            Self::S => f.write_str("S"),
285            Self::E => f.write_str("E"),
286            Self::W => f.write_str("W"),
287            Self::FN => f.write_str("FN"),
288            Self::FS => f.write_str("FS"),
289            Self::FE => f.write_str("FE"),
290            Self::FW => f.write_str("FW"),
291        }
292    }
293}
294
295/// Signal direction of a pin.
296#[derive(Copy, Clone, Debug, PartialEq, Eq)]
297pub enum PinDirection {
298    /// INPUT
299    Input,
300    /// OUTPUT. Is TRISTATE when the boolean flag is set.
301    Output(bool),
302    /// INOUT: Both input and output.
303    Inout,
304    /// FEEDTHRU: Pin crosses the cell. Direct electrical connection.
305    Feedthru,
306}
307
308impl FromStr for PinDirection {
309    type Err = ();
310
311    fn from_str(input: &str) -> Result<Self, Self::Err> {
312        match input {
313            "INPUT" => Ok(Self::Input),
314            "OUTPUT" => Ok(Self::Output(false)),
315            "INOUT" => Ok(Self::Inout),
316            "FEEDTHRU" => Ok(Self::Feedthru),
317            _ => Err(()),
318        }
319    }
320}
321
322impl fmt::Display for PinDirection {
323    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
324        match self {
325            Self::Input => f.write_str("INPUT"),
326            Self::Output(false) => f.write_str("OUTPUT"),
327            Self::Output(true) => f.write_str("OUTPUT TRISTATE"),
328            Self::Inout => f.write_str("INOUT"),
329            Self::Feedthru => f.write_str("FEEDTHRU"),
330        }
331    }
332}