open_vaf/ir/hir/
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#![allow(clippy::wildcard_imports)]
11use crate::ir::*;
12use index_vec::*;
13
14use std::ops::Range;
15
16use crate::ast::Parameter;
17use crate::ast::{BinaryOperator, NetType, UnaryOperator, Variable};
18
19use crate::hir_lowering::derivatives::Unknown;
20use crate::symbol::Ident;
21use crate::{Ast, Span};
22use std::mem::take;
23use crate::literals::StringLiteral;
24use crate::ir::ids::IdRange;
25
26//pub mod visitor;
27
28/// An High level (tree) IR representing a Verilog-AMS project;
29/// It provides stable indicies for every Node because the entire Tree is immutable once created;
30/// It uses preallocated constant size arrays for better performance
31/// Compared to an AST all references are resolved to their respective ids here and unnecessary constructs like blocks are ignored
32
33pub struct Hir {
34    pub parameters: IndexVec<ParameterId, AttributeNode<Parameter>>,
35    pub branches: IndexVec<BranchId, AttributeNode<BranchDeclaration>>,
36    pub nets: IndexVec<NetId, AttributeNode<Net>>,
37    pub ports: IndexVec<PortId, Port>,
38    pub variables: IndexVec<VariableId, AttributeNode<Variable>>,
39    pub modules: IndexVec<ModuleId, AttributeNode<Module>>,
40    pub functions: IndexVec<FunctionId, AttributeNode<Function>>,
41    pub disciplines: IndexVec<DisciplineId, AttributeNode<Discipline>>,
42    pub natures: IndexVec<NatureId, AttributeNode<Nature>>,
43    pub expressions: IndexVec<ExpressionId, Node<Expression>>,
44    pub attributes: IndexVec<AttributeId, Attribute>,
45    pub statements: IndexVec<StatementId, Statement>,
46}
47impl Hir {
48    pub(crate) fn init(ast: &mut Ast) -> Self {
49        Self {
50            // The following AST items do change (references are mapped but the data structure doesnt change so we init it like this)
51            parameters: take(&mut ast.parameters),
52            variables: take(&mut ast.variables),
53            attributes: take(&mut ast.attributes),
54
55
56            // We init empty vecs because that doesnt allocate. We will reinit these during AST lowering
57            branches: IndexVec::with_capacity(ast.branches.len()),
58            nets: IndexVec::new(),
59            ports: IndexVec::new(),
60            modules: IndexVec::with_capacity(ast.modules.len()),
61            functions: index_vec![Function::placeholder();ast.functions.len()],
62            disciplines: Default::default(),
63            natures: Default::default(),
64            expressions: IndexVec::with_capacity(ast.expressions.len()),
65            statements: IndexVec::with_capacity(ast.statements.len()),
66        }
67    }
68}
69
70impl_id_type!(BranchId in Hir::branches -> AttributeNode<BranchDeclaration>);
71impl_id_type!(NetId in Hir::nets -> AttributeNode<Net>);
72impl_id_type!(PortId in Hir::ports -> Port);
73impl_id_type!(VariableId in Hir::variables ->  AttributeNode<Variable>);
74impl_id_type!(ModuleId in Hir::modules -> AttributeNode<Module>);
75impl_id_type!(FunctionId in Hir::functions -> AttributeNode<Function>);
76impl_id_type!(DisciplineId in Hir::disciplines -> AttributeNode<Discipline>);
77impl_id_type!(ExpressionId in Hir::expressions -> Node<Expression>);
78impl_id_type!(AttributeId in Hir::attributes -> Attribute);
79impl_id_type!(StatementId in Hir::statements -> Statement);
80impl_id_type!(NatureId in Hir::natures -> AttributeNode<Nature>);
81impl_id_type!(ParameterId in Hir::parameters -> AttributeNode<Parameter>);
82
83#[derive(Clone, Debug)]
84pub struct Function {
85    pub name: Ident,
86    pub args: Vec<FunctionArg>,
87    pub return_variable: VariableId,
88    pub body: Block,
89}
90
91impl Function{
92    pub const fn placeholder()->AttributeNode<Function>{
93        let contents = Self{
94            name: Ident::empty(),
95            args: Vec::new(),
96            return_variable: VariableId::from_raw_unchecked(0),
97            body: IdRange(StatementId::from_raw_unchecked(0)..StatementId::from_raw_unchecked(0)),
98        };
99        AttributeNode{
100            attributes: Attributes{
101                start: AttributeId::from_raw_unchecked(0),
102                len: 0,
103            },
104            source: Span::new_short_empty_span(0),
105            contents,
106        }
107    }
108}
109
110#[derive(Clone, Debug, PartialEq, Eq, Copy)]
111pub struct FunctionArg {
112    pub local_var: VariableId,
113    pub input: bool,
114    pub output: bool,
115}
116
117#[derive(Clone, Copy, Debug)]
118pub struct Discipline {
119    pub name: Ident,
120    pub flow_nature: Option<NatureId>,
121    pub potential_nature: Option<NatureId>,
122    pub continuous: Option<bool>,
123}
124
125#[derive(Copy, Clone)]
126pub struct Nature {
127    pub name: Ident,
128    pub abstol: ExpressionId,
129    pub units: ExpressionId,
130    pub access: Ident,
131    pub idt_nature: NatureId,
132    pub ddt_nature: NatureId,
133}
134
135#[derive(Clone, Debug)]
136pub struct Module {
137    pub name: Ident,
138    pub port_list: IdRange<PortId>,
139    pub analog: Block,
140}
141pub type Block = IdRange<StatementId>;
142#[derive(Clone, Debug)]
143pub struct Condition {
144    pub condition: ExpressionId,
145    pub if_statements: Block,
146    pub else_statements: Block,
147}
148#[derive(Clone, Copy, Debug)]
149pub struct Port {
150    pub input: bool,
151    pub output: bool,
152    pub net: NetId,
153}
154
155#[derive(Clone, Copy, Debug)]
156pub struct BranchDeclaration {
157    pub name: Ident,
158    pub branch: Branch,
159}
160
161#[derive(Copy, Clone, Eq, PartialEq, Debug)]
162pub enum Branch {
163    Port(PortId),
164    Nets(NetId, NetId),
165}
166#[derive(Clone, Copy, Debug)]
167pub struct Net {
168    pub name: Ident,
169    pub discipline: DisciplineId,
170    pub signed: bool,
171    pub net_type: NetType,
172}
173#[derive(Clone, Copy, Eq, PartialEq, Debug)]
174pub enum DisciplineAccess {
175    Potential,
176    Flow,
177}
178
179#[derive(Clone, Debug)]
180pub enum Statement {
181    Condition(AttributeNode<Condition>),
182    ConditionStart { condition_info_and_end: StatementId },
183
184    While(AttributeNode<WhileLoop>),
185    WhileStart { while_info_and_start: StatementId },
186
187    Contribute(Attributes, DisciplineAccess, BranchId, ExpressionId),
188    //  TODO IndirectContribute(),
189    Assignment(Attributes, VariableId, ExpressionId),
190
191    FunctionCall(Attributes, FunctionId, Vec<ExpressionId>),
192}
193
194#[derive(Clone, Debug)]
195pub struct WhileLoop {
196    pub condition: ExpressionId,
197    pub body: Block,
198}
199
200#[derive(Clone, Debug)]
201pub enum Expression {
202    BinaryOperator(ExpressionId, Node<BinaryOperator>, ExpressionId),
203    UnaryOperator(Node<UnaryOperator>, ExpressionId),
204    Condtion(ExpressionId, Span, ExpressionId, Span, ExpressionId),
205    Primary(Primary),
206}
207#[derive(Clone, Debug)]
208pub enum Primary {
209    Integer(i64),
210    UnsignedInteger(u32),
211    Real(f64),
212    String(StringLiteral),
213
214    VariableReference(VariableId),
215    NetReference(NetId),
216    PortReference(PortId),
217    ParameterReference(ParameterId),
218
219    BranchAccess(DisciplineAccess, BranchId),
220    Derivative(ExpressionId, Unknown),
221
222    BuiltInFunctionCall1p(BuiltInFunctionCall1p, ExpressionId),
223    BuiltInFunctionCall2p(BuiltInFunctionCall2p, ExpressionId, ExpressionId),
224    FunctionCall(FunctionId, Vec<ExpressionId>),
225    SystemFunctionCall(SystemFunctionCall<ExpressionId, ExpressionId, PortId, ParameterId>),
226    Noise(NoiseSource<ExpressionId, ()>, Option<StringLiteral>),
227}