# Ideal diode: MTK+callbacks to mimic Verilog-A events?

**URL:** <https://discourse.julialang.org/t/ideal-diode-mtk-callbacks-to-mimic-verilog-a-events/62528>\
**Category:** Modelling & Simulations\
**Tags:** modelingtoolkit, circuits\
**Created:** [June 7, 2021, 4:10pm UTC](https://discourse.julialang.org/t/ideal-diode-mtk-callbacks-to-mimic-verilog-a-events/62528 "2021-06-07T16:10:10Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![MA\_Laforge](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ma_laforge/32/385_2.png) [@MA\_Laforge](https://discourse.julialang.org/u/MA_Laforge)\
**Post date:** [June 7, 2021, 4:10pm UTC](https://discourse.julialang.org/t/ideal-diode-mtk-callbacks-to-mimic-verilog-a-events/62528/1 "2021-06-07T16:10:10Z")

</div>

### Verilog-A-like circuit components

I recently found examples how to use ModelingToolkit.jl to model electrical circuit components in a Verilog-A-esque fashion. Pretty neat!:  
 → [https://github.com/SciML/ModelingToolkit.jl/blob/master/examples/electrical\_components.jl](https://github.com/SciML/ModelingToolkit.jl/blob/master/examples/electrical_components.jl)

Using a similar methodology, I got a Shockley (exponential) diode model working. I’m having a bit of trouble converging on more complex circuits, but I got it to work - which is good!

### Ideal diode (with discontinuities)

I then tried creating an “ideal” diode model using this same methodology, but it won’t simulate very well. I am aware that there are convergence issues when models have discontinuities like this, but Verilog-A seems to be able to manage quite well despite these issues.

Here is my model:

```julia-auto
function Diode(::Ideal; name)
	@named(p = Pin()); @named(n = Pin())
	@variables v(t) i(t)
	eqs = [
		v ~ p.v - n.v #Convenience
		0 ~ p.i + n.i #in = -out
		i ~ p.i #Positive current flows *into* p terminal
		0 ~ IfElse.ifelse(v<0, i, v)
	]

	ODESystem(eqs, t, [v, i], [], systems=[p, n], defaults=Dict(), name=name)
end

```

### VerilogA events

I suspect one thing helping out in VerilogA is the fact that you can use events to trigger a timepoint at the discontinuity (If I remember correctly).

Here is an example of using events from the VerilogAMS Reference manual (v2.4):

```julia-auto
module comparator(cout, inp, inm);
	output cout;
	input inp, inm;
	electrical cout, inp, inm;
	parameter real td = 1n, tr = 1n, tf = 1n;
	real vcout;
	analog begin
		@(cross(V(inp) - V(inm), 0))
		vcout = ((V(inp) > V(inm)) ? 1 : 0);
		V(cout) <+ transition(vcout, td, tr, tf);
	end
endmodule

```

Apparently, the VerilogA `@cross` event is critical to help the simulator produce accurately-timed results with this device. In my experience, this sort of code deals fairly well with discontinuities - as long as the output transitions with finite rise/fall times `(tr, tf)` - which it does thanks to the `transition()` “filter”.

### VerilogA events == MTK+callbacks?

I sort of stumbled on a few videos and docs regarding continuous callbacks that appear to do something similar to VerilogA’s `@cross` events:  
 → [https://diffeq.sciml.ai/stable/features/callback\_functions/#ContinuousCallback-Examples](https://diffeq.sciml.ai/stable/features/callback_functions/#ContinuousCallback-Examples)

### MTK+callbacks only on `solve()`?

One thing I noticed, though is that it only seems to be possible to add callbacks “globally” when you call `solve()`. I find the way you add VerilogA’s `@cross` events to be much more elegant/practical - given that it is specified/registered within the “device” model itself.

Adding callbacks to the `solve()` command feels sort of inelegant/error-prone, etc when compared to the VerilogA events solution.

### Attempt at creating diode “callback”

I tried to build my own callback to trigger a timepoint in my simulation using the docs I found:  
([https://diffeq.sciml.ai/stable/features/callback\_functions/#ContinuousCallback-Examples](https://diffeq.sciml.ai/stable/features/callback_functions/#ContinuousCallback-Examples))

```julia-auto
function condition(sys,t,integrator) # Event @ v = 0
	sys.v ~ 0
end

function affect!(integrator)
	nothing
end
cb = ContinuousCallback(condition,affect!)

```

But I don’t think this is correct. My model is using what I believe is called the “domain-specific language” layer from ModelingToolkit: “`@variables v(t) i(t)`”, etc.

All examples I found in the DifferentialEquations.jl documentation expect you to use the `u` and `du` vectors instead of the more (subjectively) readable `sys` variables.

### Additional/Overall questions

- Am I possibly interpreting things incorrectly?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [June 7, 2021, 4:15pm UTC](https://discourse.julialang.org/t/ideal-diode-mtk-callbacks-to-mimic-verilog-a-events/62528/2 "2021-06-07T16:15:03Z")

</div>

Yeah, this is just missing functionality right now. [https://github.com/SciML/ModelingToolkit.jl/issues/38](https://github.com/SciML/ModelingToolkit.jl/issues/38) is the issue for it (the oldest open issue! 😱). You can use the tricks in [Frequently Asked Questions · ModelingToolkit.jl](https://mtk.sciml.ai/dev/basics/FAQ/) to do it in the front end, but that’s nasty. We do need to support events in the front end.
