open_vaf/ir/
mod.rs

1/*
2 * ******************************************************************************************
3 * Copyright (c) 2019 Pascal Kuthe. This file is part of the OpenVAF project.
4 * It is subject to the license terms in the LICENSE file found in the top-level directory
5 *  of this distribution and at  https://gitlab.com/DSPOM/OpenVAF/blob/master/LICENSE.
6 *  No part of OpenVAF, including this file, may be copied, modified, propagated, or
7 *  distributed except according to the terms contained in the LICENSE file.
8 * *****************************************************************************************
9 */
10
11//here so that ids don't spam the struct section of this module in docs but can still be imported under the normal path
12#[doc(no_inline)]
13pub use ids::AttributeId;
14#[doc(no_inline)]
15pub use ids::BlockId;
16#[doc(no_inline)]
17pub use ids::BranchId;
18#[doc(no_inline)]
19pub use ids::DisciplineId;
20#[doc(no_inline)]
21pub use ids::ExpressionId;
22#[doc(no_inline)]
23pub use ids::FunctionId;
24#[doc(no_inline)]
25pub use ids::IntegerExpressionId;
26#[doc(no_inline)]
27pub use ids::ModuleId;
28#[doc(no_inline)]
29pub use ids::NatureId;
30#[doc(no_inline)]
31pub use ids::NetId;
32#[doc(no_inline)]
33pub use ids::ParameterId;
34#[doc(no_inline)]
35pub use ids::PortId;
36#[doc(no_inline)]
37pub use ids::RealExpressionId;
38#[doc(no_inline)]
39pub use ids::StatementId;
40#[doc(no_inline)]
41pub use ids::StringExpressionId;
42#[doc(no_inline)]
43pub use ids::VariableId;
44
45use crate::ir::ids::IdRange;
46use crate::symbol::Ident;
47use crate::Span;
48use bitflags::_core::fmt::Debug;
49use std::ops::Range;
50
51#[macro_use]
52pub mod ids;
53
54#[macro_use]
55pub mod ast;
56
57pub mod hir;
58
59pub mod mir;
60
61#[macro_use]
62pub mod cfg;
63
64/// A Node of an IR. Contains a Span an addition to whatever that node holds
65#[derive(Clone, Copy, Debug)]
66pub struct Node<T> {
67    pub source: Span,
68    pub contents: T,
69}
70
71impl<T> Node<T> {
72    pub fn new(contents: T, source: Span) -> Self {
73        Self { contents, source }
74    }
75}
76
77impl<T: Copy> Node<T> {
78    pub fn copy_as<X>(self, contents: X) -> Node<X> {
79        Node {
80            source: self.source,
81            contents,
82        }
83    }
84}
85impl<T: Clone> Node<T> {
86    pub fn clone_as<X>(&self, contents: X) -> Node<X> {
87        Node {
88            source: self.source,
89            contents,
90        }
91    }
92}
93
94#[derive(Copy, Clone, Debug)]
95pub struct Attribute {
96    pub name: Ident,
97    pub value: Option<ExpressionId>,
98}
99
100#[derive(Clone, Copy, Debug, PartialEq)]
101pub struct Attributes {
102    pub start: AttributeId,
103    pub len: u8,
104}
105
106impl Attributes {
107    pub fn new(start: AttributeId, end: AttributeId) -> Self {
108        let len = end.index() - start.index();
109        assert!(
110            len < u8::MAX as usize,
111            "Only up to 255 attributes per object are supported"
112        );
113        Self {
114            start,
115            len: len as u8,
116        }
117    }
118
119    #[inline]
120    pub fn as_range(&self) -> Range<AttributeId> {
121        self.start..self.end()
122    }
123
124    #[inline]
125    pub fn end(&self) -> AttributeId {
126        self.start + (self.len as usize)
127    }
128    pub const fn empty() -> Self {
129        Self {
130            start: AttributeId::from_raw_unchecked(0),
131            len: 0,
132        }
133    }
134}
135
136impl IntoIterator for Attributes {
137    type Item = AttributeId;
138    type IntoIter = IdRange<AttributeId>;
139
140    fn into_iter(self) -> Self::IntoIter {
141        IdRange(self.as_range())
142    }
143}
144
145impl Default for Attributes {
146    fn default() -> Self {
147        Self::empty()
148    }
149}
150
151/// A special type of IR Node. Contains a Span and attributes in addition to whatever that node holds
152#[derive(Clone, Copy, Debug)]
153pub struct AttributeNode<T> {
154    pub attributes: Attributes,
155    pub source: Span,
156    pub contents: T,
157}
158
159impl<T: Copy + Clone> AttributeNode<T> {
160    #[inline]
161    pub fn copy_with<X: Clone>(self, f: impl FnOnce(T) -> X) -> AttributeNode<X> {
162        AttributeNode {
163            attributes: self.attributes,
164            source: self.source,
165            contents: f(self.contents),
166        }
167    }
168
169    #[inline]
170    pub fn copy_as<X: Clone>(self, contents: X) -> AttributeNode<X> {
171        AttributeNode {
172            attributes: self.attributes,
173            source: self.source,
174            contents,
175        }
176    }
177}
178impl<T> AttributeNode<T> {
179    #[inline]
180    pub fn map_with<X>(&self, f: impl FnOnce(&T) -> X) -> AttributeNode<X> {
181        AttributeNode {
182            attributes: self.attributes,
183            source: self.source,
184            contents: f(&self.contents),
185        }
186    }
187
188    #[inline]
189    pub fn map<X>(&self, contents: X) -> AttributeNode<X> {
190        AttributeNode {
191            attributes: self.attributes,
192            source: self.source,
193            contents,
194        }
195    }
196}
197
198#[derive(Copy, Clone, Debug)]
199pub enum BuiltInFunctionCall1p {
200    Sqrt,
201    Exp(bool),
202    Ln,
203    Log,
204    Abs,
205    Floor,
206    Ceil,
207
208    Sin,
209    Cos,
210    Tan,
211
212    ArcSin,
213    ArcCos,
214    ArcTan,
215
216    SinH,
217    CosH,
218    TanH,
219
220    ArcSinH,
221    ArcCosH,
222    ArcTanH,
223}
224
225#[derive(Copy, Clone, Debug)]
226pub enum BuiltInFunctionCall2p {
227    Pow,
228    Hypot,
229    Min,
230    Max,
231    ArcTan2,
232}
233
234#[derive(Copy, Clone, Debug)]
235pub enum NoiseSource<Expr, Table> {
236    White(Expr),
237    Flicker(Expr, Expr),
238    Table(Table),
239    TableLog(Table),
240}
241impl<Expr, Table> NoiseSource<Expr, Table> {
242    pub fn fold<NewExpr, NewTable>(
243        self,
244        mut fold_expr: impl FnMut(Expr) -> NewExpr,
245        mut fold_table: impl FnMut(Table) -> NewTable,
246    ) -> NoiseSource<NewExpr, NewTable> {
247        match self {
248            NoiseSource::White(expr) => NoiseSource::White(fold_expr(expr)),
249            NoiseSource::Flicker(expr1, expr2) => {
250                NoiseSource::Flicker(fold_expr(expr1), fold_expr(expr2))
251            }
252            NoiseSource::Table(table) => NoiseSource::Table(fold_table(table)),
253            NoiseSource::TableLog(table) => NoiseSource::TableLog(fold_table(table)),
254        }
255    }
256}
257
258// TODO add system to generalise (dynamically add more)
259// TODO add a way to constant fold these
260#[derive(Clone, Debug)]
261pub enum SystemFunctionCall<RealExpr, StrExpr, Port, Parameter> {
262    Temperature,
263    Vt(Option<RealExpr>),
264    Simparam(StrExpr, Option<RealExpr>),
265    SimparamStr(StrExpr),
266    PortConnected(Port),
267    ParameterGiven(Parameter),
268}
269
270#[derive(Clone, Debug, Copy)]
271pub enum DisplayTaskKind {
272    // stprob, display and write (write does not have a newline after are equivalent. write
273    Convergence(bool),
274    Debug,
275}
276
277#[derive(Clone, Copy, Debug, PartialEq)]
278pub struct NumericalParameterRangeBound<T> {
279    pub inclusive: bool,
280    pub bound: T,
281}
282impl<T: Copy> NumericalParameterRangeBound<T> {
283    pub fn copy_with<N>(self, f: impl FnOnce(T) -> N) -> NumericalParameterRangeBound<N> {
284        NumericalParameterRangeBound {
285            inclusive: self.inclusive,
286            bound: f(self.bound),
287        }
288    }
289
290    pub fn copy_with_ref<N>(self, f: &mut impl FnMut(T) -> N) -> NumericalParameterRangeBound<N> {
291        NumericalParameterRangeBound {
292            inclusive: self.inclusive,
293            bound: f(self.bound),
294        }
295    }
296
297    pub fn try_copy_with<N>(
298        self,
299        f: impl FnOnce(T) -> Option<N>,
300    ) -> Option<NumericalParameterRangeBound<N>> {
301        Some(NumericalParameterRangeBound {
302            inclusive: self.inclusive,
303            bound: f(self.bound)?,
304        })
305    }
306
307    pub fn try_copy_with_ref<N>(
308        self,
309        f: &mut impl FnMut(T) -> Option<N>,
310    ) -> Option<NumericalParameterRangeBound<N>> {
311        Some(NumericalParameterRangeBound {
312            inclusive: self.inclusive,
313            bound: f(self.bound)?,
314        })
315    }
316}
317#[derive(Clone, Debug, PartialEq)]
318pub enum NumericalParameterRangeExclude<T> {
319    Value(T),
320    Range(Range<NumericalParameterRangeBound<T>>),
321}
322
323pub enum FunctionType {
324    Real,
325    Integer,
326}
327
328impl<T: Copy> NumericalParameterRangeExclude<T> {
329    pub fn clone_with<N>(&self, mut f: impl FnMut(T) -> N) -> NumericalParameterRangeExclude<N> {
330        match self {
331            NumericalParameterRangeExclude::Value(val) => {
332                NumericalParameterRangeExclude::Value(f(*val))
333            }
334            NumericalParameterRangeExclude::Range(range) => NumericalParameterRangeExclude::Range(
335                range.start.copy_with_ref(&mut f)..range.end.copy_with_ref(&mut f),
336            ),
337        }
338    }
339    pub fn try_clone_with<N>(
340        &self,
341        mut f: impl FnMut(T) -> Option<N>,
342    ) -> Option<NumericalParameterRangeExclude<N>> {
343        Some(match self {
344            NumericalParameterRangeExclude::Value(val) => {
345                NumericalParameterRangeExclude::Value(f(*val)?)
346            }
347            NumericalParameterRangeExclude::Range(range) => NumericalParameterRangeExclude::Range(
348                range.start.try_copy_with_ref(&mut f)?..range.end.try_copy_with_ref(&mut f)?,
349            ),
350        })
351    }
352}