$display("unsigned out(%%d): %0d", outSumUs); $display("unsigned out(%%b): %b", outSumUs); end endmodule
xcelium
1 2 3 4 5 6 7
xcelium> run signed out(%d): -12 signed out(%b): 10100 unsigned out(%d): 20 unsigned out(%b): 10100 xmsim: *W,RNQUIE: Simulation is complete. xcelium> exit
vcs
1 2 3 4 5 6
Compiler version S-2021.09-SP2-1_Full64; Runtime version S-2021.09-SP2-1_Full64; May 7 17:24 2022 signed out(%d): -12 signed out(%b): 10100 unsigned out(%d): 20 unsigned out(%b): 10100 V C S S i m u l a t i o n R e p o r t
observation
When signed and unsigned is mixed,
the result is by default unsigned.
Prepend to operands with 0s instead of extending
sign, even though the operands is signed
LHS DONT affect how the simulator operate on the
operands but what the results represent, signed or unsigned
Therefore, although outSumUs is declared as signed, its
result is unsigned
subtraction example
In logic arithmetic, addition and subtraction are commonly used for
digital design. Subtraction is similar to addition except that the
subtracted number is 2's complement. By using 2's complement for the
subtracted number, both addition and subtraction can be unified to using
addition only.
$display("unsigned out(%%d): %0d", outSubUs); $display("unsigned out(%%b): %b", outSubUs); end endmodule
1 2 3 4 5 6
Compiler version S-2021.09-SP2-1_Full64; Runtime version S-2021.09-SP2-1_Full64; May 7 17:46 2022 signed out(%d): -3 signed out(%b): 11101 unsigned out(%d): 29 unsigned out(%b): 11101 V C S S i m u l a t i o n R e p o r t
1 2 3 4 5 6
xcelium> run signed out(%d): -3 signed out(%b): 11101 unsigned out(%d): 29 unsigned out(%b): 11101 xmsim: *W,RNQUIE: Simulation is complete.
$display("unsigned out(%%d): %0d", outSubUs); $display("unsigned out(%%b): %b", outSubUs); end endmodule
1 2 3 4 5 6
Compiler version S-2021.09-SP2-1_Full64; Runtime version S-2021.09-SP2-1_Full64; May 7 17:50 2022 signed out(%d): 13 signed out(%b): 01101 unsigned out(%d): 13 unsigned out(%b): 01101 V C S S i m u l a t i o n R e p o r t
1 2 3 4 5 6 7
xcelium> run signed out(%d): 13 signed out(%b): 01101 unsigned out(%d): 13 unsigned out(%b): 01101 xmsim: *W,RNQUIE: Simulation is complete. xcelium> exit
Verilog has a nasty habit of treating everything as unsigned unless
all variables in an expression are signed. To add insult to injury, most
tools won’t warn you if signed values are being ignored.
If you take one thing away from this post:
Never mix signed and unsigned variables in one
expression!
Chronologic VCS simulator copyright 1991-2021 Contains Synopsys proprietary information. Compiler version S-2021.09-SP2-2_Full64; Runtime version S-2021.09-SP2-2_Full64; Nov 19 11:02 2022 Coordinates (7,7): x : 00000111 7 y : 00000111 7 Move +4: x1: 00001011 11 *LOOKS OK* y1: 00001011 11 Move -4: x1: 00010011 19 *SURPRISE* y1: 00000011 3 V C S S i m u l a t i o n R e p o r t Time: 60 CPU Time: 0.260 seconds; Data structure size: 0.0Mb
reference
Lee WF. Learning from VLSI Design Experience [electronic Resource] /
by Weng Fook Lee. 1st ed. 2019. Springer International Publishing; 2019.
doi:10.1007/978-3-030-03238-8
With implict sign extension, the implementation of
signed arithmetic is DIFFERENT from
that of unsigned. Otherwise, their implementations are
same.
The implementations manifest the RTL's behaviour correctly
add without implicit sign
extension
unsigned
rtl
1 2 3 4 5 6 7
module TOP ( inputwire [2:0] data0 ,inputwire [2:0] data1 ,outputwire [2:0] result ); assign result = data0 + data1; endmodule
synthesized netlist
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
///////////////////////////////////////////////////////////// // Created by: Synopsys DC Ultra(TM) in wire load mode // Version : S-2021.06-SP5 // Date : Sat May 7 11:43:27 2022 /////////////////////////////////////////////////////////////
module TOP ( data0, data1, result ); input [2:0] data0; input [2:0] data1; output [2:0] result; wire n4, n5, n6;
module TOP ( inputwiresigned [2:0] data0 ,inputwiresigned [2:0] data1 ,outputwiresigned [2:0] result ); assign result = data0 + data1; endmodule
synthesized netlist
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
///////////////////////////////////////////////////////////// // Created by: Synopsys DC Ultra(TM) in wire load mode // Version : S-2021.06-SP5 // Date : Sat May 7 11:48:54 2022 /////////////////////////////////////////////////////////////
module TOP ( data0, data1, result ); input [2:0] data0; input [2:0] data1; output [2:0] result; wire n4, n5, n6;
module TOP ( inputwire [2:0] data0 // 3 bit unsigned ,inputwire [1:0] data1 // 2 bit unsigned ,outputwire [2:0] result // 3 bit unsigned ); assign result = data0 + data1; endmodule
synthesized netlist
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
///////////////////////////////////////////////////////////// // Created by: Synopsys DC Ultra(TM) in wire load mode // Version : S-2021.06-SP5 // Date : Sat May 7 12:15:58 2022 /////////////////////////////////////////////////////////////
module TOP ( data0, data1, result ); input [2:0] data0; input [1:0] data1; output [2:0] result; wire n4, n5, n6;
///////////////////////////////////////////////////////////// // Created by: Synopsys DC Ultra(TM) in wire load mode // Version : S-2021.06-SP5 // Date : Sat May 7 12:21:51 2022 /////////////////////////////////////////////////////////////
Linear model of the CDR is used in a frequency lock
condition and is approaching to achieve phase
lock
Using this model, the power spectral density (PSD) of jitter in the
recovered clock \(S_{out}(f)\) is \[
S_{out}(f)=|H_T(f)|^2S_{in}(f)+|H_G(f)|^2S_{VCO}(f)
\] Here, we assume \(\varphi_{in}\) and \(\varphi_{VCO}\) are uncorrelated as they
come from independent sources.
Using below notation \[\begin{align}
\omega_n^2=\frac{K_{PD}K_{VCO}}{C} \\
\xi=\frac{K_{PD}K_{VCO}}{2\omega_n^2}
\end{align}\]
We can rewrite transfer function as follows \[
H_T(s)=\frac{2\xi\omega_n s+\omega_n^2}{s^2+2\xi \omega_n s+\omega_n^2}
\]
The jitter transfer represents a low-pass filter
whose magnitude is around 1 (0 dB) for low jitter frequencies and drops
at 20 dB/decade for frequencies above \(\omega_n\)
the recovered clock track the low-frequency
jitter of the input data
the recovered clock DONT track the
high-frequency jitter of the input data
The recovered clock does not suffer from high-frequency jitter even
though the input signal may contain high-frequency jitter, which will
limit the CDR tolerance to high-frequency jitter.
Jitter Peaking in
Jitter Transfer Function
The peak, slightly larger than 1 (0dB) implies that jitter will be
amplified at some frequencies in the CDR, producing a
jitter amplitude in the recovered clock, and thus also in the recovered
data, that is slightly larger than the jitter amplitude
in the input data.
This is certainly undesirable, especially in applications such as
repeaters.
Jitter Generation
If the input data to the CDR is clean with no jitter, i.e., \(\varphi_{in}=0\), the jitter of the
recovered clock comes directly from the VCO jitter. The transfer
function that relates the VCO jitter to the recovered clock jitter is
known as jitter generation. \[
H_G(s)=\frac{\varphi_{out}}{\varphi_{VCO}}|_{\varphi_{in}=0}=\frac{s^2}{s^2+2\xi
\omega_n s+\omega_n^2}
\] Jitter generation is high-pass filter with
two zeros, at zero frequency, and two poles identical to those of the
jitter transfer function
Jitter Tolerance
To quantify jitter tolerance, we often apply a sinusoidal jitter of a
fixed frequency to the CDR input data and observe the BER of the CDR
The jitter tolerance curve DONT capture a CDR's true
tolerance to random jitter. Because we are applying
"sinusoidal" jitter, which is deterministic signal.
We can deal only with the jitter's amplitude and frequency instead of
the PSD of the jitter thanks to deterministic sinusoidal jitter signal.
\[
JTOL(f) = \left | \varphi_{in}(f) \right |_{\text{pp-max}} \quad
\text{for a fixed BER}
\] Where the subscript \(\text{pp-max}\) indicates the maximum
peak-to-peak amplitude. We can further expand this equation as follows
\[
JTOL(f)=\left| \frac{\varphi_{in}(f)}{\varphi_{e}(f)} \right| \cdot
|\varphi_e(f)|_{pp-max}
\]
Relative jitter, \(\varphi_e\) must
be less than 1UIpp for error-free operation
In an ideal CDR, the maximum peak-to-peak amplitude
of \(|\varphi_e(f)|\) is
1UI, i.e.,\(|\varphi_e(f)|_{pp-max}=1UI\)
Accordingly, jitter tolerance can be expressed in terms of the number
of UIs as \[
JTOL(f)=\left| \frac{\varphi_{in}(f)}{\varphi_{e}(f)} \right|\quad
\text{[UI]}
\] Given the linear CDR model, we can write \[
JTOL(f)=\left| 1+\frac{K_{PD}K_{VCO}H_{LF}(f)}{j2\pi f} \right|\quad
\text{[UI]}
\] Expand \(H_{LF}(f)\) for the
CDR, we can write \[
JTOL(f)=\left| 1-2\xi j \left(\frac{f_n}{f}\right) -
\left(\frac{f_n}{f}\right)^2 \right|\quad \text{[UI]}
\]
At frequencies far below and above the natural frequency, the jitter
tolerance can be approximated by the following \[
JTOL(f) = \left\{ \begin{array}{cl}
\left(\frac{f_n}{f}\right)^2 & : \ f\ll f_n \\
1 & : \ f\gg f_n
\end{array} \right.
\]
the jitter tolerance at very high jitter
frequencies is limited to 1UIpp
This is consistent with that the recovered clock does not track the
high-frequency jitter, limiting the maximum peak-to-peak deviation of
the data edge from its nominal position to 1UI
The circumstance, (b) jittery data with ideal clock
the jitter tolerance is increased at 40dB/decade for jitter
frequencies below \(f_c\)
This is consistent with our obervation earlier that the recovered
clock better tracks data jitter at lower jitter frequencies
Equivalently, the data edge and the clock edge move together in the
same direction. As a result, the relative jitter
between the data and the clock remains small, i.e., below 1UI
peak-to-peak
The circumstance, (c) jittery data and jittery clock
OJTF
Concepts of JTF and OJTF
Simplified Block Diagram of a Clock-Recovery PLL
Jitter Transfer Function (JTF)
Input Signal Versus Recovered Clock
JTF, by jitter frequency, compares how much input signal jitter is
transferred to the output of a clock-recovery's PLL (recovered
clock)
Input signal jitter that is within the clock recovery PLL's loop
bandwidth results in jitter that is faithfully transferred (closed-loop
gain) to the clock recovery PLL's output signal. JTF in this situation
is approximately 1.
Input signal jitter that is outside the clock recovery PLL's loop
bandwidth results in decreasing jitter (open-loop gain) on the clock
recovery PLL's output, because the jitter is filtered out and no longer
reaches the PLL's VCO
Observed Jitter Transfer Function
Input Signal Versus Sampled Signal
OJTF compares how much input signal jitter is transferred to the
output of a receiver's decision making circuit as
effected by a clock recovery's PLL. As the recovered clock is the
reference for detecting the input signal
Input signal jitter that is within the clock
recovery PLL's loop bandwidth results in jitter on the recovered clock
which reduces the amount of jitter that can be detected. The input
signal and clock signal are closer in phase
Input signal jitter that is outside the clock
recovery PLL's loop bandwidth results in reduced jitter on the
recovered clock which increases the amount of jitter that can
be detected. The input signal and clock signal are more out of phase.
Jitter that is on both the input and clock signals can not detected or
is reduced
JTF and OJTF for 1st Order PLLs
The observed jitter is a complement to the PLL jitter transfer
response OJTF=1-JTF (Phase matters!)
OTJF gives the amount of jitter which is tracked and therefore not
observed at the output of the CDR as a function of the jitter rate
applied to the input.
Jitter Measurement
\[
J_{\text{measured}} = JTF_{\text{DUT}} \cdot OJTF_{\text{instrument}}
\] The combination of the OJTF of a jitter measurement device and
the JTF of the clock generator under test gives the measured jitter as a
function of frequency.
For example, a clock generator with a type 1, 1st order PLL measured
with a jitter measurement device employing a golden PLL is \[
J_{\text{measured}} = \frac{\omega_1}{s+\omega_1}\frac{s}{s+\omega_2}
\]
Accurate measurement of the clock JTF requires that the OJTF cutoff
of the jitter measurement be significantly below that of the clock JTF
and that the measurement is compensated for the instrument's OJTF.
The overall response is a band pass filter because the clock JTF is
low pass and the jitter measurement device OJTF is high pass.
The compensation for the instrument OJTF is performed by measuring
the jitter of the reference clock at each jitter rate being tested and
comparing the reference jitter with the jitter
measured at the output of the DUT.
The lower the cutoff frequency of the jitter measurement device the
better the accuracy of the measurement will be.
The cutoff frequency is limited by several factors including the
phase noise of the DUT and measurement time.
Digital Sampling
Oscilloscope
How to analyze jitter:
TIE (Time Interval Error) track
histogram
FFT
TIE track provides a direct view of how the phase of
the clock evolves over time.
histogram provides valuable information about the
long term variations in the timing.
FFT allows jitter at specific rates to be measured
down to the femto-second range.
Maintaining the record length at a minimum of \(1/10\) of the inverse of the PLL loop
bandwidth minimizes the response error
reference
Dalt, Nicola Da and Ali Sheikholeslami. “Understanding Jitter and
Phase Noise: A Circuits and Systems Perspective.” (2018).
A power spectrum is equal to the square of the absolute value of
DFT.
The sum of all power spectral lines in a power spectrum is equal to
the power of the input signal.
The integral of a PSD is equal to the power of the input
signal.
power spectrum has units of \(V^2\)
and power spectral density has units of \(V^2/Hz\)
Parseval's theorem is a property of the Discrete
Fourier Transform (DFT) that states: \[
\sum_{n=0}^{N-1}|x(n)|^2 = \frac{1}{N}\sum_{k=0}^{N-1}|X(k)|^2
\] Multiply both sides of the above by \(1/N\): \[
\frac{1}{N}\sum_{n=0}^{N-1}|x(n)|^2 =
\frac{1}{N^2}\sum_{k=0}^{N-1}|X(k)|^2
\]\(|x(n)|^2\) is instantaneous
power of a sample of the time signal. So the left side of the equation
is just the average power of the signal over the N
samples. \[
P_{\text{av}} = \frac{1}{N^2}\sum_{k=0}^{N-1}|X(k)|^2\text{, }V^2
\] For the each DFT bin, we can say: \[
P_{\text{bin}}(k) = \frac{1}{N^2}|X(k)|^2\text{,
k=0:N-1, }V^2/\text{bin}
\] This is the power spectrum of the signal.
Note that \(X(k)\) is the
two-sided spectrum. If \(x(n)\) is real, then \(X(k)\) is symmetric about \(fs/2\), with each side containing half of
the power. In that case, we can choose to keep just the
one-sided spectrum, and multiply Pbin by 2
(except DC & Nyquist):
rng default Fs = 1000; t = 0:1/Fs:1-1/Fs; x = cos(2*pi*100*t) + randn(size(t)); N = length(x); xdft = fft(x); xsq_sum_avg = sum(x.^2)/N; specsq_sum_avg = sum(abs(xdft).^2)/N^2;
where xsq_sum_avg is same with
specsq_sum_avg
For a discrete-time sequence x(n), the DFT is defined as: \[
X(k) = \sum_{n=0}^{N-1}x(n)e^{-j2\pi kn/N}
\] By it definition, the DFT does NOT apply to
infinite duration signals.
Different scaling is needed to apply for amplitude spectrum, power
spectrum and power spectrum density, which shown as below
\(f_s\) in Eq.(13) is sample
rate rather than frequency resolution.
And Eq.(13) can be expressed as \[
\text{PSD}(k) =\frac{1}{f_{\text{res}}\cdot
N\sum_{n}w^2(n)}\left|X_{\omega}(k)\right|^2
\] where \(f_{\text{res}}\) is
frequency resolution
We define the following two sums for normalization purposes:
where Normalized Equivalent Noise BandWidth is
defined as \[
\text{NENBW} =\frac{N S_2}{S_1^2}
\] and Effective Noise BandWidth is \[
\text{ENBW} =f_{\text{res}} \cdot \frac{N S_2}{S_1^2}
\]
For Rectangular window, \(\text{ENBW}
=f_{\text{res}}\)
This equivalent noise bandwidth is required when the
resulting spectrum is to be expressed as spectral density (such as
for noise measurements).
plot(Fx1,10*log10(Pxx1),Fx2,10*log10(Pxx2),'r--'); legend('PSD via Eq.(13)','PSD via pwelch')
window effects
It is possible to correct both the amplitude and energy content of
the windowed signal to equal the original signal. However, both
corrections cannot be applied simultaneously
power spectral density (PSD)\[
\text{PSD} =\frac{\left|X_{\omega}(k)\right|^2}{f_s\cdot S_2}
\]
We have \(\text{PSD} =
\frac{\text{PS}}{\text{ENBW}}\), where \(\text{ENBW}=\frac{N \cdot
S_2}{S_1^2}f_{\text{res}}\)
linear power spectrum\[
\text{PS}_L=\frac{|X_{\omega}(k)|^2}{N\cdot S_2}
\]
usage: RMS value, total power \[
\text{PS}_L(k)=\text{PSD(k)} \cdot f_{\text{res}}
\]
Window Correction Factors
While a window helps reduce leakage (The window reduces the jumps at
the ends of the repeated signal), the window itself distorts the data in
two different ways:
Amplitude – The amplitude of the signal
is reduced
This is due to the fact that the window removes information in the
signal
Energy – The area under the curve, or
energy of the signal, is reduced
Window correction factors are used to try and
compensate for the effects of applying a window to data. There are both
amplitude and energy correction factors.
Window Type
Amplitude Correction (\(K_a\))
Energy Correction (\(K_e\))
Rectangluar
1.0
1.0
hann
1.9922
1.6298
blackman
2.3903
1.8155
kaiser
1.0206
1.0204
Only the Uniform window (rectangular window), which is equivalent to
no window, has the same amplitude and energy correction factors.
In literature, Coherent power gain is defined show
below, which is close related to \(K_a\)\[
\text{Coherent power gain (dB)} = 20 \; log_{10} \left( \frac{\sum_n
w[n]}{N} \right)
\]
With amplitude correction, by multiplying by two, the peak
value of both the original and corrected spectrum match. However
the energy content is not the same.
The amplitude corrected signal (red) appears to have more energy, or
area under the curve, than the original signal (blue).
Multiplying the values in the spectrum by 1.63, rather than 2, makes
the area under the curve the same for both the original signal
(blue) and energy corrected signal (red)
hanning's correction factors:
1 2 3 4
N = 256; w = hanning(N); Ka = N/sum(w) Ke = sqrt(N/sum(w.^2))
%% plot psd of two methods plot(Fx1,10*log10(Pxx1),Fx2,10*log10(Pxx2),'r--'); legend('PSD via Eq.(13)','PSD via pwelch') grid on; xlabel('Freq (Hz)'); ylabel('dB; V^2/Hz')
We may also want to know for example the RMS value of the signal, in
order to know how much power the signal generates. This can be done
using Parseval’s theorem.
For a periodic signal, which has a discrete
spectrum, we obtain its total RMS value by summing the included signals
using \[
x_{\text{rms}}=\sqrt{\sum R_{xk}^2}
\] Where \(R_{xk}\) is the RMS
value of each sinusoid for \(k=1,2,3,...\) The RMS value of a signal
consisting of a number of sinusoids is consequently equal to the
square root of the sum of the RMS values.
This result could also be explained by noting that sinusoids of
different frequencies are orthogonal, and can therefore
be summed like vectors (using Pythagoras’ theorem)
For a random signal we cannot interpret the spectrum in the same way.
As we have stated earlier, the PSD of a random signal contains all
frequencies in a particular frequency band, which makes it
impossible to add the frequencies up. Instead, as the PSD is a
density function, the correct interpretation is to sum the area under
the PSD in a specific frequency range, which then is the square of the
RMS, i.e., the mean-square value of the signal \[
x_{\text{rms}}=\sqrt{\int G_{xx}(f)df}=\sqrt{\text{area under the
curve}}
\] The linear spectrum, or RMS
spectrum, defined by \[\begin{align}
X_L(k) &= \sqrt{\text{PSD(k)} \cdot f_{\text{res}}}\\
&=\sqrt{\frac{\left|X_{\omega}(k)\right|^2}{f_{\text{res}}\cdot
N\sum_{n}\omega^2(n)} \cdot f_{\text{res}}} \\
&= \sqrt{\frac{\left|X_{\omega}(k)\right|^2}{N\sum_{n}\omega^2(n)}}
\\
&= \sqrt{\frac{|X_{\omega}(k)|^2}{N\cdot S_2}}
\end{align}\]
The corresponding linear power spectrum or
RMS power spectrum can be defined by \[\begin{align}
\text{PS}_L(k)&=X_L(k)^2=\frac{|X_{\omega}(k)|^2}{S_1^2}\frac{S_1^2}{N\cdot
S_2} \\
&=\text{PS}(k) \cdot \frac{S_1^2}{N\cdot S_2}
\end{align}\]
So, RMS can be calculated as below \[\begin{align}
P_{\text{tot}} &= \sum \text{PS}_L(k) \\
\text{RMS} &= \sqrt{P_{\text{tot}}}
\end{align}\]
DFT averaging
we use \(N= 8*\text{nfft}\) time
samples of \(x\) and set the number of
overlapping samples to \(\text{nfft}/2 =
512\). pwelch takes the DFT of \(\text{Navg} = 15\) overlapping segments of
\(x\), each of length \(\text{nfft}\), then averages the \(|X(k)|^2\) of the DFT’s.
In general, if there are an integer number of segments that cover all
samples of N, we have \[
N = (N_{\text{avg}}-1)*D + \text{nfft}
\] where \(D=\text{nfft}-\text{noverlap}\). For our
case, with \(D = \text{nfft}/2\) and
\(N/\text{nfft} = 8\), we have \[
N_{\text{avg}}=2*N/\text{nfft}-1=15
\] For a given number of time samples N, using overlapping
segments lets us increase \(N_{avg}\)
compared with no overlapping. In this case, overlapping of 50% increases
\(N_{avg}\) from 8 to 15. Here is the
Matlab code to compute the spectrum:
1 2 3 4 5 6 7 8
nfft= 1024; N= nfft*8; % number of samples in signal n= 0:N-1; x= A*sin(2*pi*f0*n*Ts) + .1*randn(1,N); % 1 W sinewave + noise noverlap= nfft/2; % number of overlapping time samples window= hanning(nfft); [pxx,f]= pwelch(x,window,noverlap,nfft,fs); % W/Hz PSD PdB_bin= 10*log10(pxx*fs/nfft); % dBW/bin
DFT averaging reduces the variance \(\sigma^2\) of the noise spectrum by a
factor of \(N_{avg}\), as long as
noverlap is not greater than nfft/2
fftshift
The result of fft and its index is shown as below
After fftshift
1 2 3 4 5
>> fftshift([123456])
ans =
456123
dft and
psd function in virtuoso
dft always return
To compensate windowing effect, \(W(n)\), the dft output should
be multiplied by \(K_a\), e.g. 1.9922
for hanning window.
psd function has taken into account \(K_e\), postprocessing is
not needed
Rapuano, Sergio, and Harris, Fred J., An Introduction to FFT and Time
Domain Windows, IEEE Instrumentation and Measurement Magazine, December,
2007. https://ieeexplore.ieee.org/document/4428580
Heinzel, Gerhard, A. O. Rüdiger and Roland Schilling. "Spectrum and
spectral density estimation by the Discrete Fourier transform (DFT),
including a comprehensive list of window functions and some new at-top
windows." (2002). URL: https://holometer.fnal.gov/GH_FFT.pdf
Jens Ahrens, Carl Andersson, Patrik Höstmad, Wolfgang Kropp,
“Tutorial on Scaling of the Discrete Fourier Transform and the Implied
Physical Units of the Spectra of Time-Discrete Signals” in 148th
Convention of the AES, e-Brief 56, May 2020 [ pdf,
web
].
Manolakis, D., & Ingle, V. (2011). Applied Digital Signal
Processing: Theory and Practice. Cambridge: Cambridge University
Press. doi:10.1017/CBO9780511835261
<divider> represents the hierarchical pathname
divider. The default hierarchical character is forward slash
(/).
*|DELIMITER <delimiter>
<delimiter> represents the delimiter character
used to concatenate an instance name and pin name to form an instance
pin name.
It is also represents the delimiter character used to concatenate a
net name and subnode number to form a subnode name. The default
character is colon (:)
*|BUSBIT <left_busbit_char><right_busbit_char>
<left_busbit_char> and
<right_busbit_char> are used at the end of an
identifier of an array to select a single object of the array.
Objects which may be indexed include nets, primary pins, and
instance pins
*|NET <netName> <netCap>
<netName> represents the name of a net. It can be
a user-provided net name, the name of the driving pin, or the name of
the driving instance pin.
<netCap> represents the total
capacitance value in farads associated with the net. This may be
comprised of capacitances to ground and capacitances to nearby
wires.
*|P <pinName> <pinType> <pinCap> {<coord>}
<pinName> represents the name of the pin.
<pinType> represents the type of the pin. It can
be any of the following: I (Input), O (Output), B (Bidirectional), X
(don’t care), S (Switch), and J (Jumper).
<pinCap> represents the capacitance value
associated with the pin.
<coord> is optional. It represents the location
of the pin. Multiple pin locations are allowed.
*|S <subNodeName> {<coord>}
subnodes in the net
<subNodeName> represents the name of the subnode.
A subnode name is obtained by concatenating the net name and a subnode
number using the delimiter specified in the DELIMITER statement. The
default delimiter is colon (:).
<instPinName> represents the name of the instance
pin. An instance pin name is obtained by concatenating the
<instName> and the <pinName> with
a delimiting character which is specified by the DELIMITER
statement
<instName> represents the name of the
instance
*|DeviceFingerDelim "@"
MOS finger delimiter
For example, M8's finger is 4, then split into 4 Devices
in DSPF
MM8, MM8@2, MM8@3,
MM8@4
its drain terminal will be
MM8:d, MM8@2:d, MM8@3:d,
MM8@4:d
DSPF Syntax
DSPF has two sections:
a net section
The net section consists of a series of net description blocks. Each
net description block corresponds to a net in the physical design. A net
description block begins with a net statement followed by pins, instance
pins, subnodes, and parasitic resistor/capacitor
(R/C) components that characterize the
electrical behavior of the net.
an instance section
The instance section consists of a series of SPICE instance
statements. SPICE instance statements begin with an
X.
Each file consists of hierarchical cells and interconnects only.
The DSPF format is as generic and as much like SPICE as possible.
While native SPICE statements describe the R/C sections, some non-native
SPICE statements complete the net descriptions. These non-native SPICE
statements start with the notation "*|" to differentiate them from
native SPICE statements. For native SPICE statements, a continuation
line begins with the conventional "+" sign in the first column.
The native SPICE statements used by the DSPF format are listed
below:
.SUBCKT represents a subcircuit statement.
.ENDS represents the end of a subcircuit
statement.
R represents a resistor element.
C represents a capacitor element.
E represents a voltage-controlled voltage sources
element.
X represents an instance of a cell;
* represents a comment line unless it is
*| or *+.
.END is an optional statement that represents the end
of a simulation session
spectre netlist
hier_delimiter="."
Used to set hierarchical delimiter. Length of
hier_delimiter should not be longer than 1, except the
leader escape character
This option maps the bus delimiter between schematic netlist and
parasitic file (i.e. DSPF, SPEF, or DPF). The option defines the bus
delimiter in the schematic netlist, and optionally the bus delimiter in
the parasitic file. By default, the bus delimiter of the parasitic file
is taken from the parasitic file header (i.e. |BUSBIT [],
|BUS_BIT [], or *|BUS_DELIMITER []). If the bus delimiter is not
defined in the parasitic file header, you need to specify it by using
the spfbusdelim option in schematic netlist.
Exampel
spfbusdelim=<> - A<1> in the schematic netlist is mapped
to A_1 in the DSPF file, if the bus delimiter header in the DSPF file is
"_".
spfbusdelim=@ [] - A@1 in the schematic netlist is mapped to to A[1]
in the DSPF file (the bus delimiter in DSPF header will be
ignored).
How to Save Net voltage in
DSPF
!!! follow the name of net section in DSPF - prepend to top-level
devices in the schematic with X
Assume node n1...n4 are named as below in DSPF file (prefix
X)
n1
XXosc/zip:1
n2
XXosc/zip:2
n3
XXosc/zip:3
n4
XXosc/zip:4
To save these nodes, you can add follow code in Definition
Files
saveopt.scs
1 2 3 4
save Xwrapper.Xvco.XXosc\/zip\:1 save Xwrapper.Xvco.XXosc\/zip\:2 save Xwrapper.Xvco.XXosc\/zip\:3 save Xwrapper.Xvco.XXosc\/zip\:4
Escape character \ is used for hierarchical pathname
divider / and subnode :
By the way, . is hierarchical delimiter of
Spectre
Calibre always prepend one X to instance name of
schematic in generated DSPF file
The DSPF design is flatten, the DIVIDER character
indicate the hierarchy
1
save Xwrapper.Xvco.XXosc\/zip
The above save voltage, however I'm NOT sure which node it save.
To avoid this unsure problem, the MOS terminal may be better choice
to save.
But keep in mind
OD resistance is lumped in the FEOL model
M0OD and above layer resistances are extracted by RC tool
How to Save Current in DSPF
!!! follow the name of instance section of DSPF - prepend to
top-level devices in the schematic with XX
MOS in schematic: Xsupply.M4
MOS related information in DSPF (prefix XX in instance
section):
1 2 3 4 5 6 7 8 9
... // net section *|I XXsupply/MM4:d XXsupply/MM4 d B 0.0
<instName> in
*|I <instPinName> <instName> <pinName> <pinType><pinCap> {<coord>?}
which has prefix X corresponding to schematic is
NOT the instance name in DSPF. The instance name is in
instance section and has prefix XX
!!! Only work for MOS terminal current. Fail to apply to block
pin
Thinking about voltage
and current save
MOS device always prepend with M
To save net voltage, take account of the prefix
X of top-level device
To save MOS terminal, take account of the prefix
XX of top-level device
Post-layout netlists are created by layout extraction tools - Mentor
Calibre
Differences
Between DSPF and Schematic Names
MOS Terminal Mismatch ( ‘s’ vs ‘1’)
Schematic: number '1' ,'2', '3','4'
DSPF: 'd', 'g', 's','b'
.simrc file
If DSPF files show such differences, you can set options in the
.simrc file to update the save statement in the
netlist so that the device names match with those in the DSPF
file
Additionally, dspf_include reads all the DSPF lines
starting with * (|NET, |I, *|P,*|S), while
include considers all related lines as comments.
Only verified to DSPF output of Mentor Calibre
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
; ensure that the netlist is recreated each time nlReNetlistAll=t
The net name is x1/x1:DRN. During the simulation, the following
warning is reported:
Warning from spectre during initial setup.
1 2
WARNING (SPECTRE-8282): `xpi1.x1/x1' is not a device or subcircuit instance name. WARNING (SPECTRE-8287): Ignoring invalid item `xpi1.x1/x1:DRN' in save statement.
How can I save this net for plotting and measurements?
Solution
The colon (:) in the save statement specifies terminal
current. So, the save statement used above is for terminal
current and, hence, the warning messages are reported.
1
save xpi1.x1\/x1:DRN
You need to modify the save statement as below:
1
save xpi1.x1\/x1\:DRN
Now, run the simulation and the issue will be resolved.
In T* DRC deck, it is based on the voltage recognition CAD layer and
net connection to calculate the voltage difference between two
neighboring nets by the following formula:
\[
\Delta V = \max(V_H(\text{net1})-V_L(\text{net2}),
V_H(\text{net2})-V_L(\text{net1}))
\]
where \[
V_H(\text{netx}) = \max(V(\text{netx}))
\] and \[
V_L(\text{netx}) = \min(V(\text{netx}))
\]
The \(\Delta V\) will be
0 if two nets are connected as same potential
If \(V_L \gt V_H\)on a
net, DRC will report warning on this net
Voltage recognition CAD
Layer
Two method
voltage text layer
You place specific voltage text on specific drawing layer
voltage marker layer
Each voltage marker layer represent different voltage for specific
drawing layer
voltage text layer has higher priority than voltage
marker layer and is recommended
voltage text layer
For example M3
Process Layer
CAD Layer#
Voltage High
Voltage High Top (highest priority)
Voltage Low
Voltage Low Top (highest priority)
M3
63
110
112
111
113
where 63 is layer number,
110 ~ 113 is datatype
voltage marker layer
Different data type represent different voltage, like
class uvm_reg_map extends uvm_object; // Function: add_submap // // Add an address map // // Add the specified address map instance to this address map. // The address map is located at the specified base address. // The number of consecutive physical addresses occupied by the submap // depends on the number of bytes in the physical interface // that corresponds to the submap, // the number of addresses used in the submap and // the number of bytes in the // physical interface corresponding to this address map. // // An address map may be added to multiple address maps // if it is accessible from multiple physical interfaces. // An address map may only be added to an address map // in the grand-parent block of the address submap. // externvirtualfunctionvoid add_submap (uvm_reg_map child_map, uvm_reg_addr_t offset);
// Function: add_mem // // Add a memory // // Add the specified memory instance to this address map. // The memory is located at the specified base address and has the // specified access rights ("RW", "RO" or "WO"). // The number of consecutive physical addresses occupied by the memory // depends on the width and size of the memory and the number of bytes in the // physical interface corresponding to this address map. // // If ~unmapped~ is TRUE, the memory does not occupy any // physical addresses and the base address is ignored. // Unmapped memories require a user-defined ~frontdoor~ to be specified. // // A memory may be added to multiple address maps // if it is accessible from multiple physical interfaces. // A memory may only be added to an address map whose parent block // is the same as the memory's parent block. // externvirtualfunctionvoid add_mem (uvm_mem mem, uvm_reg_addr_t offset, string rights = "RW", bit unmapped=0, uvm_reg_frontdoor frontdoor=null); endclass: uvm_reg_map