# zi_zp() is inaccurate in Cadence Spectre

1. ## zi_zp() is inaccurate in Cadence Spectre

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^-3
(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: schematic
simulator lang=spectre
global 0
parameters fsample=36M

// Library name: My_Tools_TestBenches
// Cell name: test_my_zi_nd
// View name: schematic

V1 (net1 0) vsource mag=1 type=dc
E1 (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=dc
I2 (net2 out2) my_zi_nd fsample=fsample

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" checklimitdest=psf

ac ac start=1k stop=100M dec=101 annotate=status

designParamVals info what=parameters where=rawfile
saveOptions 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);

voltage order_3;

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(order_3) <+ zi_nd(V(Input), {1, -3, 3, -1}, {1}, Tsample);
V(order_3) <+ zi_zp(V(Input), {1,0, 1,0, 1,0}, {0,0}, Tsample);
//V(order_3) <+ zi_zd(V(Input), {1,0, 1,0, 1,0}, {1}, Tsample);

V(Output) <+ V(order_3);
end //analog

endmodule```

•

2. ## Re: zi_zp() is inaccurate in Cadence Spectre

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 tranfer 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 begin
voltage 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);
endcase
end //analog

endmodule
//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: schematic
v0 in 0 AC 1
xi0 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: schematic
simulator lang=spectre
global 0
parameters ix=1 fsample=10M

// Library name: My_Tools_TestBenches
// Cell name: test_my_zi_xx
// View name: schematic
V0 (in 0) vsource mag=1 type=dc
I0 (in out) my_zi_xx fsample=fsample ix=ix
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=status
designParamVals info what=parameters where=rawfile
save out
saveOptions options save=selected```

--[[ ]]--