From 99c26777df76d6dd94038e56dd73cdb824a3f39c Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Fri, 31 May 2024 14:29:08 -0400 Subject: [PATCH 01/25] Fix for crash when compiling module with no parameters. See https://github.com/pascalkuthe/OpenVAF/issues/103 --- openvaf/mir_llvm/src/context.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvaf/mir_llvm/src/context.rs b/openvaf/mir_llvm/src/context.rs index cf4f71ff..953d8259 100644 --- a/openvaf/mir_llvm/src/context.rs +++ b/openvaf/mir_llvm/src/context.rs @@ -80,7 +80,7 @@ impl<'a, 'll> CodegenCx<'a, 'll> { } pub fn const_str_uninterned(&self, lit: &str) -> &'ll Value { - let lit = self.literals.get(lit).unwrap(); + let lit = self.literals.get(lit).unwrap_or_default(); self.const_str(lit) } From fdf04734f0bd58024588b5aa28a82cc0a72d9aee Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Wed, 19 Jun 2024 16:33:02 -0400 Subject: [PATCH 02/25] Fix for crash when compiling module with no parameters. See https://github.com/pascalkuthe/OpenVAF/issues/103 --- openvaf/mir_llvm/src/context.rs | 2 +- openvaf/osdi/src/lib.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/openvaf/mir_llvm/src/context.rs b/openvaf/mir_llvm/src/context.rs index 953d8259..cf4f71ff 100644 --- a/openvaf/mir_llvm/src/context.rs +++ b/openvaf/mir_llvm/src/context.rs @@ -80,7 +80,7 @@ impl<'a, 'll> CodegenCx<'a, 'll> { } pub fn const_str_uninterned(&self, lit: &str) -> &'ll Value { - let lit = self.literals.get(lit).unwrap_or_default(); + let lit = self.literals.get(lit).unwrap(); self.const_str(lit) } diff --git a/openvaf/osdi/src/lib.rs b/openvaf/osdi/src/lib.rs index 397cc9f9..089a586b 100644 --- a/openvaf/osdi/src/lib.rs +++ b/openvaf/osdi/src/lib.rs @@ -240,6 +240,7 @@ impl OsdiModule<'_> { literals.get_or_intern_static("Multiplier (Verilog-A $mfactor)"); literals.get_or_intern_static("deg"); literals.get_or_intern_static("m"); + literals.get_or_intern_static(""); for param in self.info.params.values() { for alias in ¶m.alias { From bf3432f216c2c84c474a5a6d502339dbbb697454 Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Fri, 21 Jun 2024 18:18:30 -0400 Subject: [PATCH 03/25] fix typo (modulle->module) --- openvaf/hir_def/src/builtin.rs | 2 +- openvaf/hir_def/src/nameres/collect.rs | 4 ++-- sourcegen/src/hir_builtins.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openvaf/hir_def/src/builtin.rs b/openvaf/hir_def/src/builtin.rs index 52febc13..871cda5a 100644 --- a/openvaf/hir_def/src/builtin.rs +++ b/openvaf/hir_def/src/builtin.rs @@ -370,7 +370,7 @@ pub fn insert_builtin_scope(dst: &mut IndexMap) dst.insert(kw::slew, BuiltIn::slew.into()); dst.insert(kw::transition, BuiltIn::transition.into()); } -pub fn insert_modulle_builtin_scope(dst: &mut IndexMap) { +pub fn insert_module_builtin_scope(dst: &mut IndexMap) { dst.insert(sysfun::mfactor, ParamSysFun::mfactor.into()); dst.insert(sysfun::xposition, ParamSysFun::xposition.into()); dst.insert(sysfun::yposition, ParamSysFun::yposition.into()); diff --git a/openvaf/hir_def/src/nameres/collect.rs b/openvaf/hir_def/src/nameres/collect.rs index 25d724d2..320586cf 100644 --- a/openvaf/hir_def/src/nameres/collect.rs +++ b/openvaf/hir_def/src/nameres/collect.rs @@ -8,7 +8,7 @@ use syntax::name::Name; use super::diagnostics::DefDiagnostic; use super::{DefMap, DefMapSource, LocalScopeId, Scope, ScopeDefItem, ScopeOrigin}; -use crate::builtin::insert_modulle_builtin_scope; +use crate::builtin::insert_module_builtin_scope; use crate::db::HirDefDB; use crate::item_tree::{ BlockScopeItem, Function, FunctionItem, ItemTree, ItemTreeId, ItemTreeNode, Module, ModuleItem, @@ -256,7 +256,7 @@ impl DefCollector<'_> { let module = &self.tree[item_tree]; self.insert_scope(parent_scope, scope, module.name.clone(), module_id); - insert_modulle_builtin_scope(&mut self.map.scopes[scope].declarations); + insert_module_builtin_scope(&mut self.map.scopes[scope].declarations); for item in &module.items { match *item { diff --git a/sourcegen/src/hir_builtins.rs b/sourcegen/src/hir_builtins.rs index e058f4fa..3f81c762 100644 --- a/sourcegen/src/hir_builtins.rs +++ b/sourcegen/src/hir_builtins.rs @@ -295,7 +295,7 @@ fn generate_builtins() { } - pub fn insert_modulle_builtin_scope(dst: &mut IndexMap){ + pub fn insert_module_builtin_scope(dst: &mut IndexMap){ #(dst.insert(sysfun::#params,ParamSysFun::#params.into());)* } }; From 67c3644492bdb555f0b50921bd7cda715cda0d8e Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Fri, 21 Jun 2024 18:20:18 -0400 Subject: [PATCH 04/25] fix typo --- openvaf/osdi/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvaf/osdi/src/lib.rs b/openvaf/osdi/src/lib.rs index 089a586b..6689323d 100644 --- a/openvaf/osdi/src/lib.rs +++ b/openvaf/osdi/src/lib.rs @@ -54,7 +54,7 @@ pub fn compile( mir }) .collect(); - let name = dst.file_stem().expect("destition is a file").to_owned(); + let name = dst.file_stem().expect("destination is a file").to_owned(); let mut paths: Vec = (0..modules.len() * 4) .map(|i| { From 2b5ed2a25ad4eb94627b394bbecb970b9a76056c Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Fri, 21 Jun 2024 18:20:37 -0400 Subject: [PATCH 05/25] remove obsolete comment --- openvaf/osdi/src/eval.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/openvaf/osdi/src/eval.rs b/openvaf/osdi/src/eval.rs index 0fae8dc7..43e5ac55 100644 --- a/openvaf/osdi/src/eval.rs +++ b/openvaf/osdi/src/eval.rs @@ -123,7 +123,6 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { hi } } - // TODO support abstime ParamKind::Current(CurrentKind::Port(_)) => cx.const_real(0.0), ParamKind::Abstime => { let loc = MemLoc::struct_gep( From b5bfc0ee8e98c4c5faa75b8732b8618dd22cb6b0 Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Fri, 21 Jun 2024 18:21:07 -0400 Subject: [PATCH 06/25] ensure mfactor isn't optimized away see https://github.com/pascalkuthe/OpenVAF/issues/119 --- openvaf/sim_back/src/dae/builder.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/openvaf/sim_back/src/dae/builder.rs b/openvaf/sim_back/src/dae/builder.rs index c5132a12..1f49351f 100644 --- a/openvaf/sim_back/src/dae/builder.rs +++ b/openvaf/sim_back/src/dae/builder.rs @@ -545,6 +545,7 @@ impl<'a> Builder<'a> { matches!(self.system.unknowns[unknown], SimUnknownKind::KirchoffLaw(_)); residual.map_vals(|val| ensure_optbarrier(val, is_kirchoff)); } + ensure_optbarrier(mfactor, false); for noise_src in &mut self.system.noise_sources { noise_src.map_vals(|val| ensure_optbarrier(val, false)); From 88b88566f84faf789eeae9d59c1fa8e1db41f7f4 Mon Sep 17 00:00:00 2001 From: Geoffrey Coram Date: Fri, 21 Jun 2024 18:25:41 -0400 Subject: [PATCH 07/25] Update README.md to point to this repository instead of pascalkuthe Signed-off-by: Geoffrey Coram --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4a80712a..6948c47e 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ Some working minimal examples (in rust) can be found in `melange/core/test.rs`. The official docker image contains everything required for compiling OpenVAF. To build OpenVAF using the official docker containers, simply run the following commands: ``` shell -git clone https://github.com/pascalkuthe/OpenVAF.git && cd OpenVAF +git clone https://github.com/gjcoram/OpenVAF.git && cd OpenVAF # On REHL distros and fedora replace docker with podman # on all commands below. docker pull ghcr.io/pascalkuthe/ferris_ci_build_x86_64-unknown-linux-gnu:latest From a1cf7cdc2d3715bbb20b8b8e96ffe4673ad3f071 Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Fri, 21 Jun 2024 18:48:59 -0400 Subject: [PATCH 08/25] support 'ceil' ($ceil, floor, and $floor are already supported) --- openvaf/hir_def/src/builtin.rs | 1 + sourcegen/src/hir_builtins.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/openvaf/hir_def/src/builtin.rs b/openvaf/hir_def/src/builtin.rs index 871cda5a..858c8a4f 100644 --- a/openvaf/hir_def/src/builtin.rs +++ b/openvaf/hir_def/src/builtin.rs @@ -247,6 +247,7 @@ pub fn insert_builtin_scope(dst: &mut IndexMap) dst.insert(kw::atan, BuiltIn::atan.into()); dst.insert(kw::atan2, BuiltIn::atan2.into()); dst.insert(kw::atanh, BuiltIn::atanh.into()); + dst.insert(kw::ceil, BuiltIn::ceil.into()); dst.insert(kw::cos, BuiltIn::cos.into()); dst.insert(kw::cosh, BuiltIn::cosh.into()); dst.insert(kw::exp, BuiltIn::exp.into()); diff --git a/sourcegen/src/hir_builtins.rs b/sourcegen/src/hir_builtins.rs index 3f81c762..57e7b008 100644 --- a/sourcegen/src/hir_builtins.rs +++ b/sourcegen/src/hir_builtins.rs @@ -91,6 +91,7 @@ const BUILTINS: [&str; 25] = [ "atan", "atan2", "atanh", + "ceil", "cos", "cosh", "exp", From 9b0c59b65322dfc716d213d74d2556811a6bd536 Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Fri, 21 Jun 2024 21:50:59 -0400 Subject: [PATCH 09/25] fix crash for $limit() with 1 arg see https://github.com/pascalkuthe/OpenVAF/issues/133 --- openvaf/hir_ty/src/inference.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) mode change 100644 => 100755 openvaf/hir_ty/src/inference.rs diff --git a/openvaf/hir_ty/src/inference.rs b/openvaf/hir_ty/src/inference.rs old mode 100644 new mode 100755 index 6ebed7fa..5c134b31 --- a/openvaf/hir_ty/src/inference.rs +++ b/openvaf/hir_ty/src/inference.rs @@ -598,7 +598,9 @@ impl Ctx<'_> { } BuiltIn::limit => { - infere_args = &args[0..2]; + if args.len() >= 2 { + infere_args = &args[0..2]; + } Cow::Borrowed(TiSlice::from_ref(info.signatures)) } @@ -787,11 +789,13 @@ impl Ctx<'_> { self.result.diagnostics.push(InferenceDiagnostic::ExpectedProbe { e: probe }) } - if let Some(Ty::UserFunction(func)) = self.result.expr_types.get(args[1]).cloned() { + if args.len() == 1 { + // only one argument (no limit function specified) + } else if let Some(Ty::UserFunction(func)) = self.result.expr_types.get(args[1]).cloned() { debug_assert_eq!(sig, LIMIT_USER_FUNCTION); let fun_info = self.db.function_data(func); - // user-function needs two extra arguments but $limit also accepts two accepts that are + // user-function needs two extra arguments but $limit also accepts two arguments that are // not passed directly to the function so these must just be equal if fun_info.args.len() != args.len() { self.result.diagnostics.push(InferenceDiagnostic::ArgCntMismatch { From c78eac3b109ba0815cb76ad756d39616debd3659 Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Fri, 5 Jul 2024 16:27:22 -0400 Subject: [PATCH 10/25] Work-around for singular matrix issue with single-node voltage contribution See https://github.com/pascalkuthe/OpenVAF/issues/135 --- openvaf/sim_back/src/util.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvaf/sim_back/src/util.rs b/openvaf/sim_back/src/util.rs index 2651e9d1..13ad1195 100644 --- a/openvaf/sim_back/src/util.rs +++ b/openvaf/sim_back/src/util.rs @@ -49,7 +49,7 @@ pub fn add(cursor: &mut FuncCursor, dst: &mut Value, val: Value, negate: bool) { match (*dst, val) { (_, F_ZERO) => (), (F_ZERO, _) if negate => *dst = cursor.ins().fneg(val), - (F_ZERO, _) => *dst = val, +// (F_ZERO, _) => *dst = val, // why no cursor.ins()? (old, _) if negate => *dst = cursor.ins().fsub(old, val), (old, _) => *dst = cursor.ins().fadd(old, val), } From 1efe32994375cdf2cf31d3ef721b43d83d54f44e Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Sat, 6 Jul 2024 16:25:13 -0400 Subject: [PATCH 11/25] parse '{} for string parameter ranges See https://github.com/pascalkuthe/OpenVAF/issues/131 --- openvaf/parser/src/grammar/items.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) mode change 100644 => 100755 openvaf/parser/src/grammar/items.rs diff --git a/openvaf/parser/src/grammar/items.rs b/openvaf/parser/src/grammar/items.rs old mode 100644 new mode 100755 index f1e65e51..28152a7b --- a/openvaf/parser/src/grammar/items.rs +++ b/openvaf/parser/src/grammar/items.rs @@ -121,7 +121,16 @@ fn constraint(p: &mut Parser) { m.abandon(p); return; } - range_or_expr(p); + if p.eat(T!["'{"]) || p.eat(T!['{']) { + // array range (for string parameters) + expr(p); + while p.eat(T![,]) { + expr(p); + } + p.expect(T!['}']); + } else { + range_or_expr(p); + } m.complete(p, CONSTRAINT); } From 1dcfe1d53f77714fd82a929d8562e64cb5a78d04 Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Mon, 8 Jul 2024 16:53:33 -0400 Subject: [PATCH 12/25] Pull cdc66d8fb2a3bcb735dedb8e273490afeadda4f0 from https://github.com/arpadbuermen/OpenVAF to address $mfactor issue for flow probes See https://github.com/pascalkuthe/OpenVAF/issues/107 --- openvaf/hir_lower/src/expr.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openvaf/hir_lower/src/expr.rs b/openvaf/hir_lower/src/expr.rs index b75fc607..87a39e9b 100644 --- a/openvaf/hir_lower/src/expr.rs +++ b/openvaf/hir_lower/src/expr.rs @@ -9,7 +9,7 @@ use hir::signatures::{ NATURE_ACCESS_NODE_GND, NATURE_ACCESS_PORT_FLOW, REAL_EQ, REAL_OP, SIMPARAM_DEFAULT, SIMPARAM_NO_DEFAULT, STR_EQ, }; -use hir::{Body, BuiltIn, Expr, ExprId, Literal, ParamSysFun, Ref, ResolvedFun, Type}; +use hir::{Body, BuiltIn, Expr, ExprId, Literal, Ref, ResolvedFun, Type}; use mir::builder::InstBuilder; use mir::{Opcode, Value, FALSE, F_ZERO, GRAVESTONE, INFINITY, TRUE, ZERO}; use mir_build::RetBuilder; @@ -564,8 +564,9 @@ impl BodyLoweringCtx<'_, '_, '_> { CurrentKind::Port(self.body.into_port_flow(args[0])) )) }; - let mfactor = self.ctx.use_param(ParamKind::ParamSysFun(ParamSysFun::mfactor)); - return self.ctx.ins().fdiv(res, mfactor); + //let mfactor = self.ctx.use_param(ParamKind::ParamSysFun(ParamSysFun::mfactor)); + //return self.ctx.ins().fdiv(res, mfactor); + return res; } BuiltIn::potential => { match_signature! { From 477e71c8b2fcf146d0e0ff2cb7a67580c2241669 Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Mon, 8 Jul 2024 16:55:36 -0400 Subject: [PATCH 13/25] Fix $mfactor scaling for potential noise contributions See https://github.com/pascalkuthe/OpenVAF/issues/137 --- openvaf/sim_back/src/dae/builder.rs | 38 ++++++++++++++++------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/openvaf/sim_back/src/dae/builder.rs b/openvaf/sim_back/src/dae/builder.rs index 1f49351f..4b5a7bcd 100644 --- a/openvaf/sim_back/src/dae/builder.rs +++ b/openvaf/sim_back/src/dae/builder.rs @@ -10,7 +10,7 @@ use mir::builder::InstBuilder; use mir::cursor::{Cursor, FuncCursor}; use mir::{ strip_optbarrier, Block, ControlFlowGraph, DominatorTree, Inst, KnownDerivatives, Unknown, - Value, FALSE, F_ONE, F_ZERO, TRUE, + Value, FALSE, F_ZERO, TRUE, }; use mir_autodiff::auto_diff; use typed_index_collections::TiVec; @@ -118,7 +118,7 @@ impl<'a> Builder<'a> { /// Return a list of all parameters that read from one of the simulation /// unknowns and therefore need to be considered during matrix construction. /// These need to be conrtsucted from the list of parameters instead of the list - /// of sim unknowns because voltage probes access to node voltages at the same time: + /// of sim unknowns because voltage probes access two node voltages at the same time: /// /// V(x, y) = V(x) - V(y) /// @@ -473,19 +473,27 @@ impl<'a> Builder<'a> { contrib: &Contribution, hi: SimUnknownKind, lo: Option, - mfactor: Value, + is_current: bool, ) { let hi = self.ensure_unknown(hi); let lo = lo.map(|lo| self.ensure_unknown(lo)); + let mfactor = self + .intern + .ensure_param(&mut self.cursor, ParamKind::ParamSysFun(ParamSysFun::mfactor)); self.system.noise_sources.extend(contrib.noise.iter().map(|src| { - let factor = match (mfactor, src.factor) { - (F_ONE, fac) | (fac, F_ONE) => fac, - (mfactor, mut factor) => { - update_optbarrier(self.cursor.func, &mut factor, |val, cursor| { - cursor.ins().fmul(mfactor, val) - }); - factor - } + let mut ofactor = src.factor; + let factor = if is_current { + // multiply power by mfactor for noise current (flow) + update_optbarrier(self.cursor.func, &mut ofactor, |val, cursor| { + cursor.ins().fmul(mfactor, val) + }); + ofactor + } else { + // divide power by mfactor for noise voltage (potential) + update_optbarrier(self.cursor.func, &mut ofactor, |val, cursor| { + cursor.ins().fdiv(val, mfactor) + }); + ofactor }; NoiseSource { name: src.name, kind: src.kind.clone(), hi, lo, factor } })) @@ -499,18 +507,14 @@ impl<'a> Builder<'a> { if let Some(lo) = lo { get_residual!(self, lo).add_contribution(contrib, &mut self.cursor, true); } - // TODO(perf): avoid mfactor for internal nodes? - let mfactor = self - .intern - .ensure_param(&mut self.cursor, ParamKind::ParamSysFun(ParamSysFun::mfactor)); - self.add_noise(contrib, hi, lo, mfactor); + self.add_noise(contrib, hi, lo, true); } fn add_source_equation(&mut self, contrib: &Contribution, eq_val: Value, dst: BranchWrite) { let residual = get_residual!(self, SimUnknownKind::Current(dst.into())); residual.add_contribution(contrib, &mut self.cursor, false); residual.add(&mut self.cursor, true, contrib.unknown.unwrap()); - self.add_noise(contrib, SimUnknownKind::Current(dst.into()), None, F_ONE); + self.add_noise(contrib, SimUnknownKind::Current(dst.into()), None, false); let (hi, lo) = dst.nodes(self.db); let hi = SimUnknownKind::KirchoffLaw(hi); let lo = lo.map(SimUnknownKind::KirchoffLaw); From cce826cf6978d75ec45578177a1b3ac1399bc2d9 Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Tue, 9 Jul 2024 16:14:11 -0400 Subject: [PATCH 14/25] Fix is_zero() for Ieee64; note 1.0 has a zero mantissa! See https://github.com/pascalkuthe/OpenVAF/issues/138 --- lib/stdx/src/ieee64.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/stdx/src/ieee64.rs b/lib/stdx/src/ieee64.rs index 635a14ed..ca0e0a2c 100644 --- a/lib/stdx/src/ieee64.rs +++ b/lib/stdx/src/ieee64.rs @@ -312,9 +312,9 @@ impl Ieee64 { f64::from_bits(self.0).is_finite() } - /// Get the bitwise representation. + /// Check if the value is 0.0 or -0.0 + /// (note that other values have a 0 mantissa!) pub fn is_zero(self) -> bool { - // IEEE number is zero if mantissa is zero - (self.0 & 0x000FFFFFFFFFFFFF) == 0 + self.0 == 0x0000000000000000 || self.0 == 0x8000000000000000 } } From 457ee3f7d5d9010d9c94ed1981bece11d8efdabe Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Tue, 9 Jul 2024 18:00:31 -0400 Subject: [PATCH 15/25] Fix issue with $limit and user-defined functions See https://github.com/pascalkuthe/OpenVAF/commit/42026b18d7bed94f15358cfb11aedb704cc7810d but note this is a different change --- openvaf/hir/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvaf/hir/src/lib.rs b/openvaf/hir/src/lib.rs index 1417728e..f9e668ae 100644 --- a/openvaf/hir/src/lib.rs +++ b/openvaf/hir/src/lib.rs @@ -227,7 +227,7 @@ impl Function { } pub fn arg(self, idx: usize, db: &CompilationDB) -> FunctionArg { - debug_assert!(db.function_data(self.id).args.len() <= idx); + debug_assert!(idx < db.function_data(self.id).args.len()); FunctionArg { fun_id: self.id, arg_id: idx.into() } } pub fn args(self, db: &CompilationDB) -> impl Iterator + Clone { From a8108a55454d203f52ae684c5c6b05547da27d9d Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Tue, 9 Jul 2024 18:04:58 -0400 Subject: [PATCH 16/25] Fix typos --- openvaf/basedb/src/ast_id_map.rs | 2 +- openvaf/basedb/src/lints.rs | 4 ++-- openvaf/hir/src/attributes.rs | 2 +- openvaf/hir/src/declarations.rs | 2 +- openvaf/hir/src/rec_declarations.rs | 2 +- openvaf/hir_def/src/lib.rs | 2 +- openvaf/hir_lower/src/ctx.rs | 2 +- openvaf/hir_lower/src/expr.rs | 8 ++++---- openvaf/osdi/build.rs | 2 +- openvaf/sim_back/src/node_collapse.rs | 2 +- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/openvaf/basedb/src/ast_id_map.rs b/openvaf/basedb/src/ast_id_map.rs index b971475e..f6d20cb2 100644 --- a/openvaf/basedb/src/ast_id_map.rs +++ b/openvaf/basedb/src/ast_id_map.rs @@ -117,7 +117,7 @@ impl AstIdMap { // Compared to rust analyzer the parent mapping was added here for lint attribute // resolution // TODO does this hurt caching in any way. Probably not: - // if the parent changes then something before changed aswell and the item is moved anyway) + // if the parent changes then something before changed as well and the item is moved anyway) bdfs(node, |it, parent| has_id_map_entry(it.kind()).then(|| res.alloc(it, parent))); res } diff --git a/openvaf/basedb/src/lints.rs b/openvaf/basedb/src/lints.rs index 310d8243..97f62691 100644 --- a/openvaf/basedb/src/lints.rs +++ b/openvaf/basedb/src/lints.rs @@ -7,8 +7,8 @@ use vfs::FileId; use crate::{BaseDB, ErasedAstId}; -/// Lints can be set to different levls -/// This enum represents these levls +/// Lints can be set to different levels +/// This enum represents these levels #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum LintLevel { /// Lints set to allow will not be displayed diff --git a/openvaf/hir/src/attributes.rs b/openvaf/hir/src/attributes.rs index a59b3155..f0f9d4ed 100644 --- a/openvaf/hir/src/attributes.rs +++ b/openvaf/hir/src/attributes.rs @@ -21,7 +21,7 @@ impl AstCache { /// # Returns /// /// The (unescaped) string literal assigned to `attribute`. If `attribute` - /// doesn't exits or is not a string literal `None` is returned instead + /// doesn't exist or is not a string literal `None` is returned instead pub(crate) fn resolve_attribute(&self, attribute: &str, id: ErasedAstId) -> Option { let idx = self.id_map.get_attr(id, attribute)?; let ast = self.id_map.get_syntax(id).to_node(self.ast.syntax()); diff --git a/openvaf/hir/src/declarations.rs b/openvaf/hir/src/declarations.rs index e5aae97d..5b59e40c 100644 --- a/openvaf/hir/src/declarations.rs +++ b/openvaf/hir/src/declarations.rs @@ -19,7 +19,7 @@ struct Scope { } impl Scope { fn new(def_map: Arc, scope: LocalScopeId, block: Option<(Name, ScopeDef)>) -> Scope { - // safety: def_map is a immultable/an arc that will live atleast as long as the scop + // safety: def_map is a immutable/an arc that will live at least as long as the scope let iter = unsafe { transmute(def_map[scope].declarations.iter()) }; Scope { _def_map: def_map, iter, def: block } } diff --git a/openvaf/hir/src/rec_declarations.rs b/openvaf/hir/src/rec_declarations.rs index ad47ba5b..06cfe385 100644 --- a/openvaf/hir/src/rec_declarations.rs +++ b/openvaf/hir/src/rec_declarations.rs @@ -19,7 +19,7 @@ struct Scope { } impl Scope { fn new(def_map: Arc, scope: LocalScopeId, block: Option<(Name, ScopeDef)>) -> Scope { - // safety: def_map is a immultable/an arc that will live atleast as long as the scop + // safety: def_map is a immutable/an arc that will live at least as long as the scope let iter: indexmap::map::Iter<'_, Name, nameres::ScopeDefItem> = def_map[scope].declarations.iter(); let iter = unsafe { transmute(iter) }; diff --git a/openvaf/hir_def/src/lib.rs b/openvaf/hir_def/src/lib.rs index 59fb5cf3..1518bb8b 100644 --- a/openvaf/hir_def/src/lib.rs +++ b/openvaf/hir_def/src/lib.rs @@ -210,7 +210,7 @@ impl BlockLoc { tree.block_scope(self.ast) .name .clone() - .expect("BlockLocs are only cerated for named Blocks") + .expect("BlockLocs are only created for named Blocks") } } diff --git a/openvaf/hir_lower/src/ctx.rs b/openvaf/hir_lower/src/ctx.rs index b9766286..958c6132 100644 --- a/openvaf/hir_lower/src/ctx.rs +++ b/openvaf/hir_lower/src/ctx.rs @@ -220,7 +220,7 @@ impl<'a, 'c> LoweringCtx<'a, 'c> { val } - pub fn implicit_eqation(&mut self, kind: ImplicitEquationKind) -> (ImplicitEquation, Value) { + pub fn implicit_equation(&mut self, kind: ImplicitEquationKind) -> (ImplicitEquation, Value) { let equation = self.intern.implicit_equations.push_and_get_key(kind); let place = self.dec_place(PlaceKind::CollapseImplicitEquation(equation)); self.func.def_var(place, FALSE); diff --git a/openvaf/hir_lower/src/expr.rs b/openvaf/hir_lower/src/expr.rs index 87a39e9b..028de163 100644 --- a/openvaf/hir_lower/src/expr.rs +++ b/openvaf/hir_lower/src/expr.rs @@ -664,12 +664,12 @@ impl BodyLoweringCtx<'_, '_, '_> { } BuiltIn::finish | BuiltIn::stop => GRAVESTONE, - /* TODO: absdealy + /* TODO: absdelay BuiltIn::absdelay => { let arg = self.lower_expr(args[0]); let mut delay = self.lower_expr(args[1]); - let (eq1, res) = self.ctx.implicit_eqation(ImplicitEquationKind::Absdelay); - let (eq2, intermediate) = self.ctx.implicit_eqation(ImplicitEquationKind::Absdelay); + let (eq1, res) = self.ctx.implicit_equation(ImplicitEquationKind::Absdelay); + let (eq2, intermediate) = self.ctx.implicit_equation(ImplicitEquationKind::Absdelay); if signature == ABSDELAY_MAX { let max_delay = self.lower_expr(args[2]); let use_delay = self.ctx.ins().fle(delay, max_delay); @@ -700,7 +700,7 @@ impl BodyLoweringCtx<'_, '_, '_> { } fn lower_integral(&mut self, kind: IdtKind, args: &[ExprId]) -> Value { - let (equation, val) = self.ctx.implicit_eqation(ImplicitEquationKind::Idt(kind)); + let (equation, val) = self.ctx.implicit_equation(ImplicitEquationKind::Idt(kind)); let mut enable_integral = self.ctx.use_param(ParamKind::EnableIntegration); let residual = if kind.has_ic() { diff --git a/openvaf/osdi/build.rs b/openvaf/osdi/build.rs index 33d3c6d3..39210cbd 100644 --- a/openvaf/osdi/build.rs +++ b/openvaf/osdi/build.rs @@ -16,7 +16,7 @@ fn tracked_env_var_os + Display>(key: K) -> Option { fn main() { // If we're just running `check`, there's no need to actually compute the stdlib just - // popualte dummys + // populate dummies let no_gen = tracked_env_var_os("RUST_CHECK").is_some(); let sh = Shell::new().unwrap(); let osdi_dir = stdx::project_root().join("openvaf").join("osdi"); diff --git a/openvaf/sim_back/src/node_collapse.rs b/openvaf/sim_back/src/node_collapse.rs index ca7eaf3d..737db910 100644 --- a/openvaf/sim_back/src/node_collapse.rs +++ b/openvaf/sim_back/src/node_collapse.rs @@ -55,7 +55,7 @@ impl NodeCollapse { }); if let Some(source_pair) = source_pair { // careful, if we insert extra derivatives for currents then we need to - // check that we are not overwritign that list here + // check that we are not overwriting that list here let pair = pairs.ensure((unknown, None)).0; extra_pairs[source_pair].insert(pair, pairs.len()); } From eba98085456c91b7c6c52a0cffd27cf0baf4c26b Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Wed, 10 Jul 2024 12:41:14 -0400 Subject: [PATCH 17/25] Remove unused code and unused imports --- openvaf/hir/src/body.rs | 3 +-- openvaf/mir/src/dominators.rs | 10 ---------- openvaf/mir/src/write.rs | 15 --------------- openvaf/mir_opt/src/simplify_cfg.rs | 21 +-------------------- 4 files changed, 2 insertions(+), 47 deletions(-) mode change 100644 => 100755 openvaf/mir/src/dominators.rs mode change 100644 => 100755 openvaf/mir/src/write.rs mode change 100644 => 100755 openvaf/mir_opt/src/simplify_cfg.rs diff --git a/openvaf/hir/src/body.rs b/openvaf/hir/src/body.rs index 1c31a1a6..4437a6c8 100644 --- a/openvaf/hir/src/body.rs +++ b/openvaf/hir/src/body.rs @@ -6,8 +6,7 @@ use hir_ty::db::HirTyDB; use hir_ty::inference; use hir_ty::types::{Signature, Ty}; -pub use hir_def::expr::Event; -pub use hir_def::{expr::CaseCond, BuiltIn, Case, ExprId, Literal, ParamSysFun, StmtId, Type}; +pub use hir_def::{expr::Event, BuiltIn, Case, ExprId, Literal, ParamSysFun, StmtId, Type}; pub use syntax::ast::{BinaryOp, UnaryOp}; use crate::{Branch, CompilationDB, Node}; diff --git a/openvaf/mir/src/dominators.rs b/openvaf/mir/src/dominators.rs old mode 100644 new mode 100755 index dfcec313..224c848b --- a/openvaf/mir/src/dominators.rs +++ b/openvaf/mir/src/dominators.rs @@ -9,16 +9,6 @@ use bitset::SparseBitMatrix; use stdx::packed_option::PackedOption; use typed_index_collections::{TiSlice, TiVec}; -trait CfgREVERSE { - type Successors; - type Predecessors; - - fn successors(cfg: &ControlFlowGraph, bb: Block) -> Self::Successors; - fn predecessors(cfg: &ControlFlowGraph, bb: Block) -> Self::Successors; -} - -trait ToIter {} - #[derive(Debug, Clone, PartialEq, Eq)] struct DomTreeNode { /// Number of this node in a (reverse) post-order traversal of the CFG, starting from 1. diff --git a/openvaf/mir/src/write.rs b/openvaf/mir/src/write.rs old mode 100644 new mode 100755 index f394b6ef..d2b70925 --- a/openvaf/mir/src/write.rs +++ b/openvaf/mir/src/write.rs @@ -345,21 +345,6 @@ impl<'a> fmt::Display for DisplayValues<'a> { } } -struct DisplayValuesWithDelimiter<'a>(&'a [Value], char); - -impl<'a> fmt::Display for DisplayValuesWithDelimiter<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - for (i, val) in self.0.iter().enumerate() { - if i == 0 { - write!(f, "{}", val)?; - } else { - write!(f, "{}{}", self.1, val)?; - } - } - Ok(()) - } -} - /// A lasso resolver that always returns `""`. /// Mainly useful for debugging pub struct DummyResolver; diff --git a/openvaf/mir_opt/src/simplify_cfg.rs b/openvaf/mir_opt/src/simplify_cfg.rs old mode 100644 new mode 100755 index 13934cff..63669b3e --- a/openvaf/mir_opt/src/simplify_cfg.rs +++ b/openvaf/mir_opt/src/simplify_cfg.rs @@ -1,8 +1,7 @@ -use std::hash::{Hash, Hasher}; use std::iter::repeat; use bitset::BitSet; -use mir::{Block, ControlFlowGraph, Function, InstructionData, Value, ValueDef, FALSE, TRUE}; +use mir::{Block, ControlFlowGraph, Function, InstructionData, ValueDef, FALSE, TRUE}; #[cfg(test)] mod tests; @@ -634,21 +633,3 @@ impl<'a> SimplifyCfg<'a> { } } } - -#[derive(Clone)] -struct ResolvedPhi { - vals: I, -} -impl + Clone> Hash for ResolvedPhi { - fn hash(&self, state: &mut H) { - for val in self.vals.clone() { - val.hash(state) - } - } -} -impl + Clone> PartialEq for ResolvedPhi { - fn eq(&self, other: &Self) -> bool { - self.vals.clone().eq(other.vals.clone()) - } -} -impl + Clone> Eq for ResolvedPhi {} From 04cb1fbf72448eb4f29797a8dccd72aa62b87aa0 Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Thu, 11 Jul 2024 15:28:52 -0400 Subject: [PATCH 18/25] Support `undef See https://github.com/pascalkuthe/OpenVAF/issues/124 --- .../basedb/src/diagnostics/preprocessor_error.rs | 10 ++++++++++ openvaf/preprocessor/src/diagnostics.rs | 2 ++ openvaf/preprocessor/src/parser.rs | 2 ++ openvaf/preprocessor/src/processor.rs | 13 +++++++++++++ 4 files changed, 27 insertions(+) mode change 100644 => 100755 openvaf/basedb/src/diagnostics/preprocessor_error.rs mode change 100644 => 100755 openvaf/preprocessor/src/parser.rs mode change 100644 => 100755 openvaf/preprocessor/src/processor.rs diff --git a/openvaf/basedb/src/diagnostics/preprocessor_error.rs b/openvaf/basedb/src/diagnostics/preprocessor_error.rs old mode 100644 new mode 100755 index 54f4d0ea..308ff2b5 --- a/openvaf/basedb/src/diagnostics/preprocessor_error.rs +++ b/openvaf/basedb/src/diagnostics/preprocessor_error.rs @@ -41,6 +41,16 @@ impl Diagnostic for PreprocessorDiagnostic { message: "macro not found here".to_owned(), }]) } + PreprocessorDiagnostic::MacroNotDefined { span, .. } => { + let span = span.to_file_span(&sm); + + Report::warning().with_labels(vec![Label { + style: LabelStyle::Primary, + file_id: span.file, + range: span.range.into(), + message: "macro not defined here".to_owned(), + }]) + } PreprocessorDiagnostic::MacroRecursion { .. } => todo!(), PreprocessorDiagnostic::FileNotFound { span, .. } => { let labels = if let Some(span) = span { diff --git a/openvaf/preprocessor/src/diagnostics.rs b/openvaf/preprocessor/src/diagnostics.rs index 896e32e1..6e8f1744 100644 --- a/openvaf/preprocessor/src/diagnostics.rs +++ b/openvaf/preprocessor/src/diagnostics.rs @@ -9,6 +9,7 @@ use crate::sourcemap::CtxSpan; pub enum PreprocessorDiagnostic { MacroArgumentCountMismatch { expected: usize, found: usize, span: CtxSpan }, MacroNotFound { name: String, span: CtxSpan }, + MacroNotDefined { name: String, span: CtxSpan }, MacroRecursion { name: String, span: CtxSpan }, FileNotFound { file: String, error: io::ErrorKind, span: Option }, InvalidTextFormat { span: Option, file: VfsPath, err: InvalidTextFormatErr }, @@ -23,6 +24,7 @@ impl_display! { match PreprocessorDiagnostic{ MacroArgumentCountMismatch { expected, found, ..} => "argument mismatch expected {} but found {}!", expected, found; MacroNotFound{name,..} => "macro '`{}' has not been declared", name; + MacroNotDefined{name,..} => "cannot undefine macro '`{}'", name; MacroRecursion { name,..} => "macro '`{}' was called recursively",name; FileNotFound { file, error, .. } => "failed to read '{}': {}", file, std::io::Error::from(*error); InvalidTextFormat { file, ..} => "failed to read {}: file contents are not valid text", file; diff --git a/openvaf/preprocessor/src/parser.rs b/openvaf/preprocessor/src/parser.rs old mode 100644 new mode 100755 index ca4b260d..acee37d6 --- a/openvaf/preprocessor/src/parser.rs +++ b/openvaf/preprocessor/src/parser.rs @@ -304,6 +304,7 @@ impl<'a, 'd> Parser<'a, 'd> { "`else" => CompilerDirective::Else, "`elsif" => CompilerDirective::ElseIf, "`endif" => CompilerDirective::EndIf, + "`undef" => CompilerDirective::Undef, _ => CompilerDirective::Macro, } } @@ -330,5 +331,6 @@ pub enum CompilerDirective { Else, ElseIf, EndIf, + Undef, Macro, } diff --git a/openvaf/preprocessor/src/processor.rs b/openvaf/preprocessor/src/processor.rs old mode 100644 new mode 100755 index 54b9c558..82b3a007 --- a/openvaf/preprocessor/src/processor.rs +++ b/openvaf/preprocessor/src/processor.rs @@ -235,6 +235,19 @@ impl<'a> Processor<'a> { p.bump(); parse_condition(p, err, self, true); } + CompilerDirective::Undef => { + p.bump(); + let name = p.current_text(); + if self.macros.contains_key(name) { + self.macros.remove(name); + } else { + err.push(PreprocessorDiagnostic::MacroNotDefined { + name: name.to_owned(), + span: p.current_span() + }) + } + p.bump(); + } CompilerDirective::Macro => { let (call, range) = parse_macro_call(p, err, &[], &mut self.source_map, p.end()); From 47df3de153a2b976def504ca0d59cb91d9047f3a Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Thu, 11 Jul 2024 16:14:58 -0400 Subject: [PATCH 19/25] Ignore `resetall (rather than erroring out) See https://github.com/pascalkuthe/OpenVAF/issues/124 --- openvaf/basedb/src/diagnostics/preprocessor_error.rs | 10 ++++++++++ openvaf/preprocessor/src/diagnostics.rs | 2 ++ openvaf/preprocessor/src/parser.rs | 2 ++ openvaf/preprocessor/src/processor.rs | 8 ++++++++ 4 files changed, 22 insertions(+) diff --git a/openvaf/basedb/src/diagnostics/preprocessor_error.rs b/openvaf/basedb/src/diagnostics/preprocessor_error.rs index 308ff2b5..61a91042 100755 --- a/openvaf/basedb/src/diagnostics/preprocessor_error.rs +++ b/openvaf/basedb/src/diagnostics/preprocessor_error.rs @@ -52,6 +52,16 @@ impl Diagnostic for PreprocessorDiagnostic { }]) } PreprocessorDiagnostic::MacroRecursion { .. } => todo!(), + PreprocessorDiagnostic::UnsupportedCompDir { span, .. } => { + let span = span.to_file_span(&sm); + + Report::warning().with_labels(vec![Label { + style: LabelStyle::Primary, + file_id: span.file, + range: span.range.into(), + message: "directive ignored".to_owned(), + }]) + } PreprocessorDiagnostic::FileNotFound { span, .. } => { let labels = if let Some(span) = span { let span = span.to_file_span(&sm); diff --git a/openvaf/preprocessor/src/diagnostics.rs b/openvaf/preprocessor/src/diagnostics.rs index 6e8f1744..5a840df4 100644 --- a/openvaf/preprocessor/src/diagnostics.rs +++ b/openvaf/preprocessor/src/diagnostics.rs @@ -11,6 +11,7 @@ pub enum PreprocessorDiagnostic { MacroNotFound { name: String, span: CtxSpan }, MacroNotDefined { name: String, span: CtxSpan }, MacroRecursion { name: String, span: CtxSpan }, + UnsupportedCompDir { name: String, span: CtxSpan }, FileNotFound { file: String, error: io::ErrorKind, span: Option }, InvalidTextFormat { span: Option, file: VfsPath, err: InvalidTextFormatErr }, UnexpectedEof { expected: &'static str, span: CtxSpan }, @@ -26,6 +27,7 @@ impl_display! { MacroNotFound{name,..} => "macro '`{}' has not been declared", name; MacroNotDefined{name,..} => "cannot undefine macro '`{}'", name; MacroRecursion { name,..} => "macro '`{}' was called recursively",name; + UnsupportedCompDir { name,.. } => "unsupported compiler directive {}",name; FileNotFound { file, error, .. } => "failed to read '{}': {}", file, std::io::Error::from(*error); InvalidTextFormat { file, ..} => "failed to read {}: file contents are not valid text", file; UnexpectedEof { expected ,..} => "unexpected EOF, expected {}",expected; diff --git a/openvaf/preprocessor/src/parser.rs b/openvaf/preprocessor/src/parser.rs index acee37d6..707fe630 100755 --- a/openvaf/preprocessor/src/parser.rs +++ b/openvaf/preprocessor/src/parser.rs @@ -305,6 +305,7 @@ impl<'a, 'd> Parser<'a, 'd> { "`elsif" => CompilerDirective::ElseIf, "`endif" => CompilerDirective::EndIf, "`undef" => CompilerDirective::Undef, + "`resetall" => CompilerDirective::ResetAll, _ => CompilerDirective::Macro, } } @@ -332,5 +333,6 @@ pub enum CompilerDirective { ElseIf, EndIf, Undef, + ResetAll, Macro, } diff --git a/openvaf/preprocessor/src/processor.rs b/openvaf/preprocessor/src/processor.rs index 82b3a007..4950edcd 100755 --- a/openvaf/preprocessor/src/processor.rs +++ b/openvaf/preprocessor/src/processor.rs @@ -248,6 +248,14 @@ impl<'a> Processor<'a> { } p.bump(); } + CompilerDirective::ResetAll => { + let name = p.current_text(); + err.push(PreprocessorDiagnostic::UnsupportedCompDir { + name: name.to_owned(), + span: p.current_span() + }); + p.bump(); + } CompilerDirective::Macro => { let (call, range) = parse_macro_call(p, err, &[], &mut self.source_map, p.end()); From f170b6e80d7ffc8bae6de0bdbe8fe25051ece879 Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Sun, 14 Jul 2024 18:55:10 -0400 Subject: [PATCH 20/25] Fix macro call argument issue See https://github.com/pascalkuthe/OpenVAF/issues/140 --- openvaf/preprocessor/src/processor.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/openvaf/preprocessor/src/processor.rs b/openvaf/preprocessor/src/processor.rs index 4950edcd..e87b8f5f 100755 --- a/openvaf/preprocessor/src/processor.rs +++ b/openvaf/preprocessor/src/processor.rs @@ -6,6 +6,7 @@ use ahash::AHashMap; use stdx::{impl_debug_display, impl_idx_from}; use text_size::{TextRange, TextSize}; use tokens::parser::SyntaxKind; +use tokens::SyntaxKind::{L_PAREN, R_PAREN}; // use tracing::{debug, debug_span, trace}; use typed_index_collections::{TiSlice, TiVec}; use vfs::{FileId, VfsPath}; @@ -166,12 +167,23 @@ impl<'a> Processor<'a> { }) .collect(); - if new_args.len() == def.arg_cnt { + if new_args.len() == def.arg_cnt || def.arg_cnt == 0 { let ctx = self.source_map.add_ctx(def.span.to_file_span(&self.source_map), span); for ParsedToken { kind, range } in &def.body { let span = CtxSpan { range: range - def.span.range.start(), ctx }; self.process_macro_token(kind, span, &new_args, dst, errors) } + if new_args.len() > def.arg_cnt { + // macro definition has no arguments, but some were parsed as part of the call + // so put the arguments back + dst.push( Token { kind:L_PAREN, span } ); + for arg in new_args { + for tok in arg { + dst.push(tok) + } + } + dst.push( Token { kind:R_PAREN, span } ); + } } else { errors.push(MacroArgumentCountMismatch { expected: def.arg_cnt, From ddfb16c92a5a5a3f7634ba69e8eedbf6e5efb306 Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Mon, 30 Sep 2024 15:36:29 -0400 Subject: [PATCH 21/25] fix typos (Optimiziation -> Optimization) --- openvaf/sim_back/src/context.rs | 10 +++++----- openvaf/sim_back/src/lib.rs | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) mode change 100644 => 100755 openvaf/sim_back/src/lib.rs diff --git a/openvaf/sim_back/src/context.rs b/openvaf/sim_back/src/context.rs index e0d78d2a..d2746e35 100644 --- a/openvaf/sim_back/src/context.rs +++ b/openvaf/sim_back/src/context.rs @@ -25,7 +25,7 @@ pub(crate) struct Context<'a> { } #[derive(PartialEq, Eq, Debug)] -pub enum OptimiziationStage { +pub enum OptimizationStage { Initial, PostDerivative, Final, @@ -65,13 +65,13 @@ impl<'a> Context<'a> { } } - pub fn optimize(&mut self, stage: OptimiziationStage) -> GVN { - if stage == OptimiziationStage::Initial { + pub fn optimize(&mut self, stage: OptimizationStage) -> GVN { + if stage == OptimizationStage::Initial { dead_code_elimination(&mut self.func, &self.output_values); } sparse_conditional_constant_propagation(&mut self.func, &self.cfg); inst_combine(&mut self.func); - if stage == OptimiziationStage::Final { + if stage == OptimizationStage::Final { simplify_cfg(&mut self.func, &mut self.cfg); } else { simplify_cfg_no_phi_merge(&mut self.func, &mut self.cfg); @@ -83,7 +83,7 @@ impl<'a> Context<'a> { gvn.solve(&mut self.func); gvn.remove_unnecessary_insts(&mut self.func, &self.dom_tree); - if stage == OptimiziationStage::Final { + if stage == OptimizationStage::Final { let mut control_dep = SparseBitMatrix::new_square(0); self.dom_tree.compute_postdom_frontiers(&self.cfg, &mut control_dep); aggressive_dead_code_elimination( diff --git a/openvaf/sim_back/src/lib.rs b/openvaf/sim_back/src/lib.rs old mode 100644 new mode 100755 index da68267e..9f77b066 --- a/openvaf/sim_back/src/lib.rs +++ b/openvaf/sim_back/src/lib.rs @@ -7,7 +7,7 @@ use stdx::impl_debug_display; pub use module_info::{collect_modules, ModuleInfo}; -use crate::context::{Context, OptimiziationStage}; +use crate::context::{Context, OptimizationStage}; use crate::dae::DaeSystem; use crate::init::Initialization; use crate::node_collapse::NodeCollapse; @@ -61,7 +61,7 @@ impl<'a> CompiledModule<'a> { let mut cx = Context::new(db, literals, module); cx.compute_outputs(true); cx.compute_cfg(); - cx.optimize(OptimiziationStage::Initial); + cx.optimize(OptimizationStage::Initial); debug_assert!(cx.func.validate()); let topology = Topology::new(&mut cx); @@ -69,7 +69,7 @@ impl<'a> CompiledModule<'a> { let mut dae_system = DaeSystem::new(&mut cx, topology); debug_assert!(cx.func.validate()); cx.compute_cfg(); - let gvn = cx.optimize(OptimiziationStage::PostDerivative); + let gvn = cx.optimize(OptimizationStage::PostDerivative); dae_system.sparsify(&mut cx); debug_assert!(cx.func.validate()); From be547cdd972d47752df9c156ed6e8aebe9193f72 Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Mon, 30 Sep 2024 15:42:43 -0400 Subject: [PATCH 22/25] arpadbuermen's fix for psp glitch problem, see https://github.com/pascalkuthe/OpenVAF/issues/120 --- openvaf/mir_autodiff/src/builder.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openvaf/mir_autodiff/src/builder.rs b/openvaf/mir_autodiff/src/builder.rs index 63cdd5bb..7f7ebe23 100644 --- a/openvaf/mir_autodiff/src/builder.rs +++ b/openvaf/mir_autodiff/src/builder.rs @@ -499,7 +499,8 @@ impl<'a, 'u> DerivativeBuilder<'a, 'u> { // Technically not required but makes code look nicer.. // exp(x) -> exp(x) - Opcode::Exp => res, + //Opcode::Exp => res, + Opcode::Exp => self.ins().exp(arg0), // hypot(x,y) -> (x' + y')/2hypot(x,y) // sqrt(x) -> 1/2sqrt(x) From 9fdd1918f39c5d2ae47e622cb14bf3f111905135 Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Mon, 28 Oct 2024 10:50:38 -0400 Subject: [PATCH 23/25] merge commit from arpadbuermen for noise mfactor issue https://github.com/pascalkuthe/OpenVAF/issues/137 --- openvaf/sim_back/src/dae/builder.rs | 191 ++++++++++++++++++++++------ 1 file changed, 153 insertions(+), 38 deletions(-) diff --git a/openvaf/sim_back/src/dae/builder.rs b/openvaf/sim_back/src/dae/builder.rs index 4b5a7bcd..3f7b3485 100644 --- a/openvaf/sim_back/src/dae/builder.rs +++ b/openvaf/sim_back/src/dae/builder.rs @@ -10,7 +10,7 @@ use mir::builder::InstBuilder; use mir::cursor::{Cursor, FuncCursor}; use mir::{ strip_optbarrier, Block, ControlFlowGraph, DominatorTree, Inst, KnownDerivatives, Unknown, - Value, FALSE, F_ZERO, TRUE, + Value, FALSE, F_ZERO, TRUE, F_ONE }; use mir_autodiff::auto_diff; use typed_index_collections::TiVec; @@ -24,13 +24,19 @@ use crate::SimUnknownKind; impl Residual { fn add(&mut self, cursor: &mut FuncCursor, negate: bool, mut val: Value) { + // Cursor points at MIR function + // Go back and skip all optbarriers to get the first actual instruction producing val val = strip_optbarrier(&cursor, val); + // Add or subtract val to resistive residual value, replace resistive value by result add(cursor, &mut self.resist, val, negate); } fn add_contribution(&mut self, contrib: &Contribution, cursor: &mut FuncCursor, negate: bool) { let mut add = |residual: &mut Value, contrib| { + // Cursor points at MIR function + // Go back and skip all optbarriers to get the first actual instruction producing contrib let contrib = strip_optbarrier(&mut *cursor, contrib); + // Add/subtract contrib to/from residual, replace residual with result add(cursor, residual, contrib, negate) }; add(&mut self.resist, contrib.resist); @@ -117,7 +123,7 @@ impl<'a> Builder<'a> { /// Return a list of all parameters that read from one of the simulation /// unknowns and therefore need to be considered during matrix construction. - /// These need to be conrtsucted from the list of parameters instead of the list + /// These need to be constructed from the list of parameters instead of the list /// of sim unknowns because voltage probes access two node voltages at the same time: /// /// V(x, y) = V(x) - V(y) @@ -327,37 +333,42 @@ impl<'a> Builder<'a> { pub(super) fn build_branch(&mut self, branch: BranchWrite, contributions: &BranchInfo) { let current = branch.into(); + // contributions.is_voltage_src is a Value that is used for choosing the branch type (voltage, current) match contributions.is_voltage_src { + // If it is constant FALSE; this is a current branch FALSE => { // if the current of the branch is probed we need to create an extra // branch let requires_unknown = self.intern.is_param_live(&self.cursor, &ParamKind::Current(current)); + let contrib = self.current_branch(contributions); if requires_unknown { self.add_source_equation( - &contributions.current_src, + &contrib, contributions.current_src.unknown.unwrap(), branch, ); } else { - self.add_kirchoff_law(&contributions.current_src, branch); + self.add_kirchoff_law(&contrib, branch); } } + // If it is constant TRUE; this is a voltage branch TRUE => { // branches only used for node collapsing look like pure current // sources, make sure to ignore these branches let requires_unknown = self.intern.is_param_live(&self.cursor, &ParamKind::Current(current)); if requires_unknown || !contributions.voltage_src.is_trivial() { + let contrib = self.voltage_branch(contributions); self.add_source_equation( - &contributions.voltage_src, + &contrib, contributions.current_src.unknown.unwrap(), branch, ); } } - // switch branch + // Otherwise this is a switch branch _ => { let requires_current_unknown = !self .cursor @@ -376,6 +387,7 @@ impl<'a> Builder<'a> { || requires_current_unknown || !contributions.voltage_src.is_trivial() { + // An actual switch branch let start_bb = self.cursor.current_block().unwrap(); let voltage_src_bb = self.cursor.layout_mut().append_new_block(); let next_block = self.cursor.layout_mut().append_new_block(); @@ -384,11 +396,25 @@ impl<'a> Builder<'a> { self.cfg.add_edge(start_bb, next_block); self.cfg.add_edge(voltage_src_bb, next_block); + // Debugging + // println!("start bb {:?}", start_bb); + // println!("voltage src bb {:?}", voltage_src_bb); + // println!("next block {:?}", next_block); + // println!("cursor at {:?}", self.cursor.position()); + + // Get expression (condition) that determines if branch acts as a voltage source + // Skip trailing optbarriers let is_voltage_src = strip_optbarrier(&self.cursor, contributions.is_voltage_src); + // Insert branch command (after?) condition + // If condition is true, jump to voltage_src_bb block + // If false go to next_block self.cursor.ins().br(is_voltage_src, voltage_src_bb, next_block); + // Go to the end of voltage_src_bb block self.cursor.goto_bottom(voltage_src_bb); + // Insert jump command to next_block self.cursor.ins().jump(next_block); + // Go to the end of next_block self.cursor.goto_bottom(next_block); let contrib = self.switch_branch(contributions, voltage_src_bb, start_bb); self.add_source_equation( @@ -397,7 +423,9 @@ impl<'a> Builder<'a> { branch, ) } else { - self.add_kirchoff_law(&contributions.current_src, branch); + // Not a real switch branch + let contrib = self.current_branch(contributions); + self.add_kirchoff_law(&contrib, branch); } } }; @@ -411,6 +439,83 @@ impl<'a> Builder<'a> { ); } + fn mfactor_multiply(&mut self, mfactor: Value, srcfactor : Value) -> Value { + match (mfactor, srcfactor) { + // Leave srcfactor unchanged if mfactor is 1 + // Replace src.factor with mfactor if src.factor is 1 + (F_ONE, fac) | (fac, F_ONE) => fac, + // Neither mfactor nor factor is 1 + (mfactor, srcfactor) => { + self.cursor + .ins() + .fmul(srcfactor, mfactor) + } + } + } + + fn mfactor_divide(&mut self, mfactor: Value, srcfactor : Value) -> Value { + match (mfactor, srcfactor) { + // Leave srcfactor unchanged if mfactor is 1 + (F_ONE, fac) => fac, + // Neither mfactor nor factor is 1 + (mfactor, srcfactor) => { + self.cursor + .ins() + .fdiv(srcfactor, mfactor) + } + } + } + + fn current_branch( + &mut self, + BranchInfo { current_src, .. }: &BranchInfo, + ) -> Contribution { + let mfactor = self + .intern + .ensure_param(&mut self.cursor, ParamKind::ParamSysFun(ParamSysFun::mfactor)); + let mut noise = Vec::with_capacity(current_src.noise.len()); + let current_noise = current_src.noise.iter().map(|src| { + let mut src = src.clone(); + src.factor = self.mfactor_multiply(mfactor, src.factor); + src + }); + noise.extend(current_noise); + + Contribution { + unknown: current_src.unknown, + resist: current_src.resist, + react: current_src.react, + resist_small_signal: current_src.resist_small_signal, + react_small_signal: current_src.resist_small_signal, + noise, + } + } + + fn voltage_branch( + &mut self, + BranchInfo { voltage_src, .. }: &BranchInfo, + ) -> Contribution { + let mfactor = self + .intern + .ensure_param(&mut self.cursor, ParamKind::ParamSysFun(ParamSysFun::mfactor)); + let mut noise = Vec::with_capacity(voltage_src.noise.len()); + let voltage_noise = voltage_src.noise.iter().map(|src| { + let mut src = src.clone(); + src.factor = self.mfactor_divide(mfactor, src.factor); + src + }); + noise.extend(voltage_noise); + + Contribution { + unknown: voltage_src.unknown, + resist: voltage_src.resist, + react: voltage_src.react, + resist_small_signal: voltage_src.resist_small_signal, + react_small_signal: voltage_src.resist_small_signal, + noise, + } + } + fn switch_branch( &mut self, BranchInfo { voltage_src, current_src, .. }: &BranchInfo, @@ -428,9 +533,13 @@ impl<'a> Builder<'a> { .phi(&[(current_bb, current_src_val), (voltage_bb, voltage_src_val)]) } }; + let voltage = voltage_src.unknown.unwrap(); let current = current_src.unknown.unwrap(); let unknown = select(voltage, current); + // Build noise phi commands + // Voltage noise, for each noise add a phi instruction that joins the values for + // the case the switch branch behaves as a voltage source (source value) and as a current source (0) let mut noise = Vec::with_capacity(voltage_src.noise.len() + current_src.noise.len()); let voltage_noise = voltage_src.noise.iter().map(|src| { let mut src = src.clone(); @@ -438,24 +547,47 @@ impl<'a> Builder<'a> { src }); noise.extend(voltage_noise); + // Current noise, for each noise add a phi instruction that joins the values for + // the case the switch branch behaves as a voltage source (0) and as a current source (source value) let current_noise = current_src.noise.iter().map(|src| { let mut src = src.clone(); src.factor = select(F_ZERO, src.factor); src }); noise.extend(current_noise); + // Build remaining phi commands + let phi_resist = select(voltage_src.resist, current_src.resist); + let phi_react = select(voltage_src.react, current_src.react); + let phi_resist_ss = select( + voltage_src.resist_small_signal, + current_src.resist_small_signal + ); + let phi_react_ss = select( + voltage_src.react_small_signal, + current_src.react_small_signal + ); + // Scale noise + // Must do this after all phi commands + // because all phi commands must be listed at block beginning + let mfactor = self + .intern + .ensure_param(&mut self.cursor, ParamKind::ParamSysFun(ParamSysFun::mfactor)); + for ii in 0..voltage_src.noise.len() + current_src.noise.len() { + if ii < voltage_src.noise.len() { + // Voltage noise + noise[ii].factor = self.mfactor_divide(mfactor, noise[ii].factor); + } else { + // Current noise + noise[ii].factor = self.mfactor_multiply(mfactor, noise[ii].factor); + } + } + Contribution { unknown: Some(unknown), - resist: select(voltage_src.resist, current_src.resist), - react: select(voltage_src.react, current_src.react), - resist_small_signal: select( - voltage_src.resist_small_signal, - current_src.resist_small_signal, - ), - react_small_signal: select( - voltage_src.react_small_signal, - current_src.react_small_signal, - ), + resist: phi_resist, + react: phi_react, + resist_small_signal: phi_resist_ss, + react_small_signal: phi_react_ss, noise, } } @@ -473,29 +605,11 @@ impl<'a> Builder<'a> { contrib: &Contribution, hi: SimUnknownKind, lo: Option, - is_current: bool, ) { let hi = self.ensure_unknown(hi); let lo = lo.map(|lo| self.ensure_unknown(lo)); - let mfactor = self - .intern - .ensure_param(&mut self.cursor, ParamKind::ParamSysFun(ParamSysFun::mfactor)); self.system.noise_sources.extend(contrib.noise.iter().map(|src| { - let mut ofactor = src.factor; - let factor = if is_current { - // multiply power by mfactor for noise current (flow) - update_optbarrier(self.cursor.func, &mut ofactor, |val, cursor| { - cursor.ins().fmul(mfactor, val) - }); - ofactor - } else { - // divide power by mfactor for noise voltage (potential) - update_optbarrier(self.cursor.func, &mut ofactor, |val, cursor| { - cursor.ins().fdiv(val, mfactor) - }); - ofactor - }; - NoiseSource { name: src.name, kind: src.kind.clone(), hi, lo, factor } + NoiseSource { name: src.name, kind: src.kind.clone(), hi, lo, src.factor } })) } @@ -507,14 +621,15 @@ impl<'a> Builder<'a> { if let Some(lo) = lo { get_residual!(self, lo).add_contribution(contrib, &mut self.cursor, true); } - self.add_noise(contrib, hi, lo, true); + self.add_noise(contrib, hi, lo); } fn add_source_equation(&mut self, contrib: &Contribution, eq_val: Value, dst: BranchWrite) { let residual = get_residual!(self, SimUnknownKind::Current(dst.into())); residual.add_contribution(contrib, &mut self.cursor, false); residual.add(&mut self.cursor, true, contrib.unknown.unwrap()); - self.add_noise(contrib, SimUnknownKind::Current(dst.into()), None, false); + self.add_noise(contrib, SimUnknownKind::Current(dst.into()), None); + let (hi, lo) = dst.nodes(self.db); let hi = SimUnknownKind::KirchoffLaw(hi); let lo = lo.map(SimUnknownKind::KirchoffLaw); From 061fc50c1e06fa5246d9ee4d236679d445bd1801 Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Wed, 30 Oct 2024 11:21:38 -0400 Subject: [PATCH 24/25] fix glitch in last commit --- openvaf/sim_back/src/dae/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvaf/sim_back/src/dae/builder.rs b/openvaf/sim_back/src/dae/builder.rs index 3f7b3485..6d10a2f9 100644 --- a/openvaf/sim_back/src/dae/builder.rs +++ b/openvaf/sim_back/src/dae/builder.rs @@ -609,7 +609,7 @@ impl<'a> Builder<'a> { let hi = self.ensure_unknown(hi); let lo = lo.map(|lo| self.ensure_unknown(lo)); self.system.noise_sources.extend(contrib.noise.iter().map(|src| { - NoiseSource { name: src.name, kind: src.kind.clone(), hi, lo, src.factor } + NoiseSource { name: src.name, kind: src.kind.clone(), hi, lo, factor: src.factor } })) } From 634f8d2575b9708782b7efd7732741d052ff75da Mon Sep 17 00:00:00 2001 From: "Geoffrey.Coram" Date: Wed, 30 Oct 2024 11:22:04 -0400 Subject: [PATCH 25/25] fix typos --- lib/stdx/src/ieee64.rs | 2 +- openvaf/hir_lower/src/callbacks.rs | 2 +- openvaf/sim_back/src/dae/tests.rs | 6 +++--- openvaf/sim_back/src/init/tests.rs | 6 +++--- openvaf/sim_back/src/topology/test.rs | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/stdx/src/ieee64.rs b/lib/stdx/src/ieee64.rs index ca0e0a2c..0aae3fa3 100644 --- a/lib/stdx/src/ieee64.rs +++ b/lib/stdx/src/ieee64.rs @@ -312,7 +312,7 @@ impl Ieee64 { f64::from_bits(self.0).is_finite() } - /// Check if the value is 0.0 or -0.0 + /// Check if the value is +0.0 or -0.0 /// (note that other values have a 0 mantissa!) pub fn is_zero(self) -> bool { self.0 == 0x0000000000000000 || self.0 == 0x8000000000000000 diff --git a/openvaf/hir_lower/src/callbacks.rs b/openvaf/hir_lower/src/callbacks.rs index 3d952a0f..c80e3b9f 100644 --- a/openvaf/hir_lower/src/callbacks.rs +++ b/openvaf/hir_lower/src/callbacks.rs @@ -123,7 +123,7 @@ impl CallBackKind { has_sideeffects: false, }, CallBackKind::FlickerNoise { name, .. } => FunctionSignature { - name: format!("flickr_noise({name:?})"), + name: format!("flicker_noise({name:?})"), params: 2, returns: 1, has_sideeffects: false, diff --git a/openvaf/sim_back/src/dae/tests.rs b/openvaf/sim_back/src/dae/tests.rs index 8e2dd618..fedcece2 100644 --- a/openvaf/sim_back/src/dae/tests.rs +++ b/openvaf/sim_back/src/dae/tests.rs @@ -7,7 +7,7 @@ use indoc::indoc; use lasso::Rodeo; use stdx::{integration_test_dir, openvaf_test_data}; -use crate::context::{Context, OptimiziationStage}; +use crate::context::{Context, OptimizationStage}; use crate::dae::DaeSystem; use crate::topology; @@ -18,11 +18,11 @@ fn run_test(src: &str) { let mut context = Context::new(&db, &mut literals, &module); context.compute_outputs(true); context.compute_cfg(); - context.optimize(OptimiziationStage::Initial); + context.optimize(OptimizationStage::Initial); let topology = topology::Topology::new(&mut context); let mut dae_system = DaeSystem::new(&mut context, topology); context.compute_cfg(); - context.optimize(OptimiziationStage::Final); + context.optimize(OptimizationStage::Final); dae_system.sparsify(&mut context); let name = module.module.name(&db); let test_dir = openvaf_test_data("dae"); diff --git a/openvaf/sim_back/src/init/tests.rs b/openvaf/sim_back/src/init/tests.rs index e54a2024..e109a0f2 100644 --- a/openvaf/sim_back/src/init/tests.rs +++ b/openvaf/sim_back/src/init/tests.rs @@ -7,7 +7,7 @@ use indoc::indoc; use lasso::Rodeo; use stdx::{integration_test_dir, openvaf_test_data}; -use crate::context::{Context, OptimiziationStage}; +use crate::context::{Context, OptimizationStage}; use crate::dae::DaeSystem; use crate::init::Initialization; use crate::topology::Topology; @@ -19,13 +19,13 @@ fn run_test(src: &str) { let mut cx = Context::new(&db, &mut literals, &module); cx.compute_outputs(true); cx.compute_cfg(); - cx.optimize(OptimiziationStage::Initial); + cx.optimize(OptimizationStage::Initial); let topology = Topology::new(&mut cx); let mut dae_system = DaeSystem::new(&mut cx, topology); cx.compute_cfg(); - let gvn = cx.optimize(OptimiziationStage::PostDerivative); + let gvn = cx.optimize(OptimizationStage::PostDerivative); dae_system.sparsify(&mut cx); cx.refresh_op_dependent_insts(); diff --git a/openvaf/sim_back/src/topology/test.rs b/openvaf/sim_back/src/topology/test.rs index a608fbc2..7a9ff1d3 100644 --- a/openvaf/sim_back/src/topology/test.rs +++ b/openvaf/sim_back/src/topology/test.rs @@ -6,7 +6,7 @@ use lasso::Rodeo; use mir::Function; use stdx::openvaf_test_data; -use crate::context::{Context, OptimiziationStage}; +use crate::context::{Context, OptimizationStage}; use crate::topology::Topology; fn compile(src: &str) -> (Function, Topology, String) { @@ -16,7 +16,7 @@ fn compile(src: &str) -> (Function, Topology, String) { let mut context = Context::new(&db, &mut literals, &module); context.compute_outputs(true); context.compute_cfg(); - context.optimize(OptimiziationStage::Initial); + context.optimize(OptimizationStage::Initial); let topology = Topology::new(&mut context); assert!(context.func.validate()); (context.func, topology, module.module.name(&db))