The Designer's Guide Community Forum https://designers-guide.org/forum/YaBB.pl Design Languages >> Verilog-AMS >> zi_zp() is inaccurate in Cadence Spectre https://designers-guide.org/forum/YaBB.pl?num=1557999612 Message started by cheap_salary on May 16th, 2019, 2:40am

Title: zi_zp() is inaccurate in Cadence Spectre
Post by cheap_salary on May 16th, 2019, 2:40am

We can evaluate frequency characteristics of z-domain transfer function, H(z) by using Verilog-A in Cadence Spectre.

Assume H(z) = (1-z^-1)^3 = 1 -3*z^-1 +3*z^-2 -1*z^-3
Here we have three options as expression in Verilog-A.

(1) zi_nd(V(Input), {1, -3, 3, -1}, {1}, Tsample);
(2) zi_zp(V(Input), {1,0, 1,0, 1,0}, {0,0}, Tsample);
(3) zi_zd(V(Input), {1,0, 1,0, 1,0}, {1}, Tsample);

However, only (1) can give accurate result.
See attached figure.
out1 is a result of Spectre primitive, zvcvs.
out2 is a result of (2).

Why can not (2) and (3) give accurate result ?

This is true for H(z) = (1-z^-1)^1 = 1 -1*z^-1
(1) zi_nd(V(Input), {1, -1}, {1}, Tsample);
(2) zi_zp(V(Input), {1,0}, {0,0}, Tsample);
(3) zi_zd(V(Input), {1,0}, {1}, Tsample);

My Cadence Spectre is Version 17.1.0.307.isr6 64bit -- 4 Jul 2018

"test_my_zi_nd.scs"
Code:
 ahdl_include "./my_zi_nd.va"// Generated for: spectre// Generated on: May 16 13:01:03 2019// Design library name: My_Tools_TestBenches// Design cell name: test_my_zi_nd// Design view name: schematicsimulator lang=spectreglobal 0parameters fsample=36M// Library name: My_Tools_TestBenches// Cell name: test_my_zi_nd// View name: schematicV1 (net1 0) vsource mag=1 type=dcE1 (out1 0 net1 0) zvcvs ts=1/fsample gain=1.0 \polyarg=inversez sxz=none \numer=[ 1 -3 3 -1 ] denom=[ 1 0 0 0 ]V2 (net2 0) vsource mag=1 type=dcI2 (net2 out2) my_zi_nd fsample=fsamplesimulatorOptions options psfversion="1.1.0" reltol=1e-3 vabstol=1e-6 \    iabstol=1e-12 temp=25.0 tnom=27 scalem=1.0 scale=1.0 gmin=1e-12 \    rforce=1 maxnotes=5 maxwarns=5 digits=5 cols=80 pivrel=1e-3 \    sensfile="../psf/sens.output"ac ac start=1k stop=100M dec=101 annotate=status designParamVals info what=parameters where=rawfilesaveOptions options save=allpub

"my_zi_nd.va"
Code:
 `include "constants.vams"`include "disciplines.vams"module my_zi_nd(Input, Output);inout Input, Output;voltage Input, Output;parameter real fsample = 1.0 from (0.0:inf);real Tsample;analog begin   @(initial_step) begin      Tsample = 1.0 / fsample;   end //initial_step   //H(z) = (1-z^-1)^3 = 1 -3*z^-1 +3*z^-2 -1*z^-3   //V(Output) <+ zi_nd(V(Input), {1, -3, 3, -1}, {1}, Tsample);   V(Output) <+ zi_zp(V(Input), {1,0, 1,0, 1,0}, {0,0}, Tsample);   //V(Output) <+ zi_zd(V(Input), {1,0, 1,0, 1,0}, {1}, Tsample);end //analogendmodule

 Title: Re: zi_zp() is inaccurate in Cadence Spectre Post by Geoffrey_Coram on May 16th, 2019, 7:47am This doesn't answer your question, but what about zi_np?(4) zi_np(V(Input), {1, -3, 3, -1}, {0,0}, Tsample);

 Title: Re: zi_zp() is inaccurate in Cadence Spectre Post by Ken Kundert on May 16th, 2019, 4:50pm Have you looked at the time domain waveforms?

Title: Re: zi_zp() is inaccurate in Cadence Spectre
Post by cheap_salary on May 17th, 2019, 6:08am

Synopsys HSPICE can give accurate results for any expression.
//H(z) = (1-z^-1)^3 = 1 -3*z^-1 +3*z^-2 -1*z^-3
(1) zi_nd(V(Input), {1, -3, 3, -1}, {1}, Tsample);
(2) zi_zp(V(Input), {1,0, 1,0, 1,0}, {0,0}, Tsample);
(3) zi_zd(V(Input), {1,0, 1,0, 1,0}, {1}, Tsample);
(4) zi_np(V(Input), {1, -3, 3, -1}, {0,0}, Tsample);

Cadence Spectre can not give accurate results for (2) and (3).
But this is a limited case, FIR form.
(1) and (4) are also suspicious in Cadence Spectre.

All of (1)-(4) can not give correct result for more general transfer function which has both zeros and poles in Cadence Spectre.

We can not trust frequency characteristics of zi_xx() of Verilog-A in Cadence Spectre at all.

"my_zi_xx.va"
Code:
 `include "constants.vams"`include "disciplines.vams"module my_zi_xx(Input, Output);inout Input, Output;voltage Input, Output;parameter real fsample = 1.0 from (0.0:inf);parameter integer ix = 1 from [1:4];//pragma protect//pragma protect beginvoltage n1, n2, n3, n4;real Tsample;analog begin   @(initial_step) Tsample = 1.0 / fsample;   //H(z) = (1-z^-1)^3 = 1 -3*z^-1 +3*z^-2 -1*z^-3   V(n1) <+ zi_nd(V(Input), {1, -3, 3, -1}, {1}, Tsample);   V(n2) <+ zi_zp(V(Input), {1,0, 1,0, 1,0}, {0,0}, Tsample);   V(n3) <+ zi_zd(V(Input), {1,0, 1,0, 1,0}, {1}, Tsample);   V(n4) <+ zi_np(V(Input), {1, -3, 3, -1}, {0,0}, Tsample);   case(ix)      1 : V(Output) <+ V(n1);      2 : V(Output) <+ V(n2);      3 : V(Output) <+ V(n3);      4 : V(Output) <+ V(n4);   endcaseend //analogendmodule//pragma protect end

"test_my_zi_xx.spi"
Code:
 .hdl "./my_zi_xx.va"** Generated for: hspiceD** Generated on: May 17 13:16:30 2019** Design library name: My_Tools_TestBenches** Design cell name: test_my_zi_xx** Design view name: schematic.PARAM ix=1 fsample=10e6.PROBE AC+    V(out) VP(out).AC DEC 101 1e3 100e6.TEMP 25.0.OPTION+    LIST=3+    ARTIST=2+    INGOLD=2+    PARHIER=LOCAL+    POST_VERSION=2001+    PSF=2+    RUNLVL=6** Library name: My_Tools_TestBenches** Cell name: test_my_zi_xx** View name: schematicv0 in 0 AC 1xi0 in out my_zi_xx fsample=fsample ix=ix.END

"test_my_zi_xx.scs"
Code:
 ahdl_include "./my_zi_xx.va"// Generated for: spectre// Generated on: May 17 13:22:40 2019// Design library name: My_Tools_TestBenches// Design cell name: test_my_zi_xx// Design view name: schematicsimulator lang=spectreglobal 0parameters ix=1 fsample=10M// Library name: My_Tools_TestBenches// Cell name: test_my_zi_xx// View name: schematicV0 (in 0) vsource mag=1 type=dcI0 (in out) my_zi_xx fsample=fsample ix=ixsimulatorOptions options psfversion="1.1.0" reltol=1e-3 vabstol=1e-6 \    iabstol=1e-12 temp=25.0 tnom=27 scalem=1.0 scale=1.0 gmin=1e-12 \    rforce=1 maxnotes=5 maxwarns=5 digits=5 cols=80 pivrel=1e-3 \    sensfile="../psf/sens.output" ac ac start=1k stop=100M dec=101 annotate=status designParamVals info what=parameters where=rawfilesave out saveOptions options save=selected

 Title: Re: zi_zp() is inaccurate in Cadence Spectre Post by cheap_salary on May 17th, 2019, 6:10am Spectre Result.

 Title: Re: zi_zp() is inaccurate in Cadence Spectre Post by Geoffrey_Coram on May 21st, 2019, 5:09am Have you tried these using the native dependent source? Something likez1 (3 0 1 0) zvcvs numer=[1 -3 3 -1] denom=Is there a problem with the z-transform implementation, or only with the translation of the Verilog-A to native?Years ago, I was looking into the Laplace transform implementations, and I seem to recall it was easy to convert ZP to ND, but not vice-versa. Or was it that, if you have complex poles, it's hard to verify that you have the conjugate pairs in floating-point math?

Title: Re: zi_zp() is inaccurate in Cadence Spectre
Post by cheap_salary on May 21st, 2019, 5:19am

Geoffrey_Coram wrote on May 21st, 2019, 5:09am:
 Have you tried these using the native dependent source? Something likez1 (3 0 1 0) zvcvs numer=[1 -3 3 -1] denom=
See https://designers-guide.org/forum/YaBB.pl?num=1557999612/0#0

Geoffrey_Coram wrote on May 21st, 2019, 5:09am:
 Or was it that, if you have complex poles,it's hard to verify that you have the conjugate pairs in floating-point math?
It can not be, since Spectre can not give accurate result even for first order.
See https://designers-guide.org/forum/YaBB.pl?num=1557999612/0#0

Title: Re: zi_zp() is inaccurate in Cadence Spectre
Post by Geoffrey_Coram on May 21st, 2019, 5:27am

Sorry, I just re-read the original post:

Quote:
 out1 is a result of Spectre primitive, zvcvs.out2 is a result of (2).

But out1 was the zvcvs using numer and denom; what about using zvcvs with zeros and poles?

 Title: Re: zi_zp() is inaccurate in Cadence Spectre Post by Ken Kundert on May 21st, 2019, 6:57pm Have you looked at the time domain waveforms?

Title: Re: zi_zp() is inaccurate in Cadence Spectre
Post by cheap_salary on May 22nd, 2019, 4:08am

Geoffrey_Coram wrote on May 21st, 2019, 5:27am:
 But out1 was the zvcvs using numer and denom;what about using zvcvs with zeros and poles?
Both can give correct result.
So we can trust Spectre Primitive, zvcvs.

However a frequency characteristics of zi_xx() is very suspicious in Verilog-A of Cadence Spectre.
https://designers-guide.org/forum/YaBB.pl?num=1298380482

H(z) = (1 -1*z^-1) / (1 +1*z^-1 +0.5*z^-2)
zeros = {0, 1}
poles = {-0.5+j*0.5, -0.5-j*0.5}

"test_zvcvs.scs"
Code:
 simulator lang=spectreglobal 0parameters fsample=10MV0 (in 0) vsource mag=1 type=dcE1 (out1 0 in 0) zvcvs ts=1/fsample gain=1.0 \polyarg=inversez sxz=none \numer=[ 1 -1 ] denom=[ 1 1 0.5 ]E2 (out2 0 in 0) zvcvs ts=1/fsample gain=1.0 \sxz=none \zeros=[ 0 0 1 0 ] poles=[ -0.5 0.5 -0.5 -0.5 ]simulatorOptions options psfversion="1.1.0" reltol=1e-3 vabstol=1e-6 \    iabstol=1e-12 temp=25.0 tnom=27 scalem=1.0 scale=1.0 gmin=1e-12 \    rforce=1 maxnotes=5 maxwarns=5 digits=5 cols=80 pivrel=1e-3 \    sensfile="../psf/sens.output"ac ac start=1k stop=100M dec=101 annotate=statussaveOptions options save=allpub

Title: Re: zi_zp() is inaccurate in Cadence Spectre
Post by cheap_salary on May 22nd, 2019, 4:20am

Ken Kundert wrote on May 21st, 2019, 6:57pm:
 Have you looked at the time domain waveforms?
I don't use zi_xx() for time domain application, since it is not valuable at all for actual operation.
https://designers-guide.org/forum/YaBB.pl?num=1361756819/3#3

zi_xx() has value only for AC-Analysis, since we have no option for periodic frequency characteristics except for zi_xx().

 Title: Re: zi_zp() is inaccurate in Cadence Spectre Post by Ken Kundert on May 22nd, 2019, 6:23pm Before you decide that the simulator is broken, you should actually verify that you are using the function properly.  You are not seeing the nulls at multiples of the clock frequency, that suggests there is some feedthrough. Where is it coming from?  Looking at the results in the time domain might given you some understanding of what is going wrong.Working in the frequency domain is convenient, but it can hide many issues. When things go wrong, it is generally a good idea to take a look at the time domain results.-Ken

 Title: Re: zi_zp() is inaccurate in Cadence Spectre Post by Ken Kundert on May 22nd, 2019, 6:28pm I don't understand your comment about zi_xx() not being useful in the time domain, and your reference does not seem to mention to zi_xx() filters at all.Why would you use them in the frequency domain if their results are useless in the time domain?-Ken

 Title: Re: zi_zp() is inaccurate in Cadence Spectre Post by Geoffrey_Coram on May 24th, 2019, 11:02am Are these the corresponding zvcvs elements?I5 (out5 0 in 0) zvcvs ts=1/fsample numer=[1 -3 3 -1] denom=I6 (out6 0 in 0) zvcvs ts=1/fsample zeros=[1 0  1 0  1 0] poles=[0 0]I7 (out7 0 in 0) zvcvs ts=1/fsample zeros=[1 0  1 0  1 0] denom=I8 (out8 0 in 0) zvcvs ts=1/fsample numer=[1 -3 3 -1] poles=[0 0]I must be doing something wrong, because the simulator fails to converge when I6 is in, and the ac waveforms for I7 and I8 are flat 1.0 (0dB).

 Title: Re: zi_zp() is inaccurate in Cadence Spectre Post by Geoffrey_Coram on May 24th, 2019, 11:03am I tried a time-domain simulation with a sine source, and the waveforms all looked the same.(When I compared those waveforms to the zvcvs I5, the latter had sharper transitions.)