pascalkuthe / OpenVAF

An innovative Verilog-A compiler
https://openvaf.semimod.de/
GNU General Public License v3.0
113 stars 15 forks source link

absdelay creates unexpected results #106

Open ChrisDaunt1984 opened 6 months ago

ChrisDaunt1984 commented 6 months ago

The absdelay function does not seem to work as I understand it is supposed to. Consider the following time_delay module

`include "constants.vams"
`include "disciplines.vams"

module time_delay(in, out);

  inout in, out;
  electrical in, out;

  parameter real t_delay = 1.0e-11; // Total delay time (s)

  real v_delayed;

  analog begin
  v_delayed = absdelay(V(in), t_delay, 1.0E-9);
  V(out) <+ v_delayed;
  end

endmodule

After compiling and running in Spectre and then passing a 20 GHz signal though the module, I get the following where one signal is delayed in the time domain by the value specified.

image

Compiling the module in OpenVAF and running the same in NGSpice results in the following where the signal is not quite delayed at the start and results in an attenuation of the signal. I have tried playing around with different time steps/resolutions etc. Any idea what is going on here?

image

kdotom commented 1 month ago

I ran a test on your VA module and got the same result as you under many configurations. I'm tracing through the source to see where the operation itself is defined.

The function appears to be in the BuiltIn list as generated by the generate_builtins function. I believe this is where the actual absdelay implementation lives.

My rust is a bit rusty, but it appears to be commented out in the latest source. I don't know how that translates to the version of the code that we're using to compile the .va file. All that said, variables like "resist_val" and "react_val" may be what provides the delay in a different way than expected. That said, this is my hypothesis for a function I didn't write in a language I don't know, so take that with a grain of salt. I'll try to parse the code, but if anyone has an analytical version of what's going on, that may be helpful.

metroid120 commented 1 month ago

I agree that this is where the implementation lives. It looks to me like OpenVAF uses an RC network for the implementation, which explains the attenuation.

The challenge is that the Verilog-A has to be translated to something that fits into Spice, e.g. there needs to be a "stamp" that works for DC, AC and transient. Also note that the original developer, who was left the project, wrote "TODO" next to the function.

The executable you have corresponds to the source code available in the main branch. You can test your hypothesis, by modifying the source, compiling OpenVAF and seeing if it has impact on the solution. I'd love to help more, but lack time. E.g. multiply "react_val" with 10 and see if the outcome changes.

For compiling I recommend you use the Dockerfile available here. This is based on a small contribution from my side.

ChrisDaunt1984 commented 1 month ago

Hi

If it needs to mapped to something that fits into spice, I ended up creating a time delay spice block using a transmission line and some VCCS blocks like so. I placed a switch in my verilog-a code so that the delay can be used in other simulators

image

BTW - Going down this rabbit hole, I found there are some guidelines in the verilog-a reference documentation as technically, the delay can be modified in each time step if the max_delay is specified, otherwise the same delay is used for the whole simulation. This can be problematic for harmonic balance simulation so should default to a constant time delay in that case