ra3xdh / qucs_s

Qucs-S is a circuit simulation program with Qt-based GUI
https://ra3xdh.github.io/
GNU General Public License v2.0
834 stars 108 forks source link

Variables are not allowed in PULSE source parameters #90

Closed Evidlo closed 1 year ago

Evidlo commented 2 years ago

I'm trying to do a simple variable substitution from an equation into a device parameter, but it seems like the variable is being completely ignored. I'm on Qucs-S 0.0.23 using ngspice.

out

SPICE output

* Qucs 0.0.23 /tmp/test3.sch
.INCLUDE "/tmp/.mount_qucslvIHaR/usr/share/qucs-s/xspice_cmlib/include/ngspice_mathfunc.inc"
* Qucs 0.0.23  /tmp/test3.sch
.PARAM low=1e-3
.PARAM high=1e-3
V1 out 0 DC 0 PULSE( 0  1 0N 1N 1N 0 2e-09)  AC 0
V2 out2 0 DC 0 PULSE( 0  1 0N 1N 1N 0.001 0.002)  AC 0
.control
echo "" > spice4qucs.cir.noise
echo "" > spice4qucs.cir.pz
let low=1e-3
let high=1e-3
tran 9.90099e-05 0.01 0 
write test3_tran.txt v(out) v(out2) 
destroy all
reset

exit
.endc
.END

It seems like high and low are being ignored on V1 and the default source values are being substituted there.

ra3xdh commented 2 years ago

It is a limitation of the Ngspice. The SIN and PULSE sources are defined as vectors. And variables are not allowed inside the vectors. Also related to #53

Evidlo commented 2 years ago

Do the other engines have this constraint? Which engine do you think is the best?

ra3xdh commented 2 years ago

Do the other engines have this constraint?

Yes, all SPICE engines (XYCE, SpiceOpus) define these sources as vectors.

Which engine do you think is the best?

The Ngspice is the best SPICE engine because of good simulation performance and compatibility with the existing models. Ngspice is set as default simulation kernel since v0.0.23.

holvo commented 2 years ago

Below I will show four methods of changing VSRC pulse source parameters.

substitute vsrc pulse parameters
.param PW=1u PER=2u
V1 1 0 dc 0 pulse (0 1 0 1n 1n {PW} {PER})
.tran 1n 5u

.control
* original data
run
plot V(1)
* substitute via parameters
alterparam PW=0.5u 
alterparam PER=2.2u
reset
run
plot tran2.V(1)+1.2 tran1.V(1)
* substitute directly via vectors pw2 per2
let pw2=1.3u
let per2=1.9u
alter @V1[pulse] = [ 0 1 0 1n 1n $&pw2 $&per2 ]
run
plot tran3.V(1)+2.4 tran2.V(1)+1.2 tran1.V(1)
* substitute again via parameters and vectors pw3, per3
let pw3=1.25u
let per3=1.6u
alterparam PW=$&pw3 
alterparam PER=$&per3
reset
run
plot tran4.V(1)+3.6 tran3.V(1)+2.4 tran2.V(1)+1.2 tran1.V(1)
.endc

.end

What kind of limitations in ngspice do you still envision?

ra3xdh commented 1 year ago

This issue may be resolved using full SPICE definition of the square voltage source. I have also recently added the alterparam support #189 which may help to implement parameter sweep on PULSE source. Closing this.

Baygon-flb commented 4 months ago

Based on @holvo tips i was able to implement a pwm signal simulation for various duty cycle scenarios. The solution follows below. It could be a useful example for anyone who needs to implement a similar simulation.

Include Script:
.param pw=5u
V3 Vin 0 dc 0 pulse (0 5 0 1n 1n {pw} 50u )
.tran 1m 5m

.control
let loops = 9
let pwcur = 5u
repeat $&loops
  reset
  echo $&pwcur
  alterparam pw = $&pwcur
  run
  let pwcur = pwcur + 5u
end
plot tran1.v(pr1) tran2.v(pr1) tran3.v(pr1) tran4.v(pr1) tran5.v(pr1) tran6.v(pr1) tran7.v(pr1) tran8.v(pr1) tran9.v(pr1)
.endc

sweep_pulse

To plot all curves, run the simulation inside QUCS-S:

  1. choose "Save Netlist" at the end of simulation.
  2. Then open a terminal (prompt)
  3. go to the project directory
  4. edit the netlist.cir file and remove the 2nd .control session at the end of netlist.cir script
  5. save the file
  6. so run the command "ngspice netlist.cir".

sweep_pulse_plot

ra3xdh commented 4 months ago

You need not to save netlist and export .INCLUDE script. Qucs-S supports .PARAM definition and full definition of the PULSE source. Use generic voltage source (red one) and paste the PULSE string. The parameter sweep supports the sweeping of .PARAM since the recent versions of Ngspice.

ra3xdh commented 4 months ago

See #189 for solution.

Baygon-flb commented 4 months ago

You need not to save netlist and export .INCLUDE script. Qucs-S supports .PARAM definition and full definition of the PULSE source. Use generic voltage source (red one) and paste the PULSE string. The parameter sweep supports the sweeping of .PARAM since the recent versions of Ngspice.

I had already tried this way. Did not work. Maybe I misunderstood how to do this the right way. The simulation runs without any errors, but shows only one curve in the graphic, that seems to be the curve of last value of sweep sequence.

NETLIST.CIR

.SUBCKT NMOSFETs_IRFZ44N  gnd  _net2 _net1 _net3
MM1 _net9 _net7 _net8 _net8 MMOD_M1 L=100u W=100u 
.MODEL MMOD_M1 NMOS(Is=1e-32 Vt0=3.56214 Lambda=0 Kp=39.3974 Cgso=1.25255e-05 Cgdo=2.2826e-07 Rs=0 Rd=0 Ld=0 Cbd=0 Cbs=0 Cgbo=0 Gamma=0 Phi=0.6) 
RRS _net8 _net3 0.0133305
DD1 _net3 _net1 DMOD_D1 
.MODEL DMOD_D1 D(Is=9.64635e-13 Rs=0.00967689 N=1.01377 Bv=55 Ibv=0.00025 Eg=1.08658 Xti=2.9994 Tt=1e-07 Cj0=1.39353e-09 Vj=0.5 M=0.42532 Fc=0.5) 
RRDS _net3 _net1 2.2E+06
RRD _net9 _net1 0.0001
RRG _net2 _net7 2.20235
DD2 _net4 _net5 DMOD_D2 
.MODEL DMOD_D2 D(Is=1e-32 N=50 Cj0=1.52875e-09 Vj=0.5 M=0.584414 Fc=1e-08 Rs=0 Eg=1.11 Xti=3 Tt=0 Bv=0 Ibv=1mA) 
DD3 gnd _net5 DMOD_D3 
.MODEL DMOD_D3 D(Is=1e-10 N=0.408752 Rs=3e-06 Eg=1.11 Xti=3 Tt=0 Cj0=0 Bv=0 Ibv=1mA M=0.5 Vj=0.7) 
RRL _net5 _net10 1
FFI2 _net7 _net9 VFI2 -1
VFI2 _net4 gnd DC 0
EEV16 _net10 gnd _net9 _net7 1
CCAP _net11 _net10 2.06741E-09
FFI1 _net7 _net9 VFI1 -1
VFI1 _net11 _net6 DC 0
RRCAP _net6 _net10 1
DD4 gnd _net6 DMOD_D4 
.MODEL DMOD_D4 D(Is=1e-10 N=0.408752 Eg=1.11 Xti=3 Tt=0 Cj0=0 Rs=0 Bv=0 Ibv=1mA M=0.5 Vj=0.7) 
.ENDS

.INCLUDE "/usr/local/qucs-s/share/qucs-s/xspice_cmlib/include/ngspice_mathfunc.inc"
.PARAM pw = 0
D_6A05_1 _net0 VDC DMOD_D_6A05_1 AREA=1.0 Temp=26.85
.MODEL DMOD_D_6A05_1 D (Is=5.24e-08 N=1.7 Cj0=6e-11 M=0.333 Vj=0.7 Fc=0.5 Rs=0.007 Tt=2.88e-06 Kf=0 Af=1 Bv=50 Ibv=1e-05 Xti=3 Eg=1.11 Tcv=0 Trs=0 Ttt1=0 Ttt2=0 Tm1=0 Tm2=0 Tnom=26.85 )
V1 VDC 0 DC 12
L1 _net0 _net1  100U 
C1 _net1 VDC  330U 
R1 _net1 VDC  1 tc1=0.0 tc2=0.0 
EPr1 Pr1 0 VDC _net1 1.0
RPr1Pr1 Pr1 0 1E8
RPr1VDC VDC _net1 1E8
XIRFZ44N 0  _net2 _net0 0 NMOSFETs_IRFZ44N
R2 Vin _net2  10 tc1=0.0 tc2=0.0 
_//here is the line produced by Spice Voltage source (red one), that one you told to use._
**V2 Vin  0  dc 0 pulse (0 5 0 1n 1n $&pw 50u ) ac 0**  
.control

op
print v(Pr1) v(VDC) v(Vin)   > spice4qucs.dc1.ngspice.dc.print
destroy all
reset

let number_pw = 0
echo "STEP tr1.pw" > spice4qucs.tr1.cir.res
foreach  pw_act 5e-06 1e-05 1.5e-05 2e-05 2.5e-05 3e-05 3.5e-05 4e-05 4.5e-05 5e-05 
alterparam pw = $pw_act
reset
tran 0.00025 0.005 0 
write spice4qucs.tr1._swp.plot v(Pr1) v(VDC) v(Vin)
set appendwrite
echo "$&number_pw  $pw_act" >> spice4qucs.tr1.cir.res
let number_pw = number_pw + 1
end
unset appendwrite
destroy all
reset

exit
.endc
.END

Simulation configs: image

Graphics:

image

ra3xdh commented 4 months ago

Have you tried the similar syntax as shown on the screenshot? Everything works without netlist export. image