0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

1.5ビットパイプラインADCのステージ動作とVout₂の一般式導出

Posted at

はじめに

本記事では、1.5ビット構成のパイプラインADCの動作を段階的に解析し、特に第2ステージの残差電圧 $V_{\mathrm{out2}}$ の導出を、補助キャパシタ $C_2$ を一般化した形で行います。Pythonコードと数式を併用して、理解しやすく記述します。


1. システムパラメータの定義

以下に主要パラメータを定義します:

記号 内容 単位 備考
$V_{\mathrm{DD}}$ 電源電圧 [V]
$V_0$ 比較基準電圧 [V] $V_0 = \frac{V_{\mathrm{DD}}}{2}$
$C_1$ 主キャパシタ [F]
$C_2$ 補助キャパシタ [F] ※ 一般化。元構成では $C_2 = \frac{C_1}{4}$
$V_1$ スイッチ注入用補助電圧 [V] 通常は $V_1 = \frac{V_{\mathrm{DD}}}{2}$
$D_1, D_2$ ビット判定出力 0 or 1

2. ステージ1:MSB(D₁)の生成

電荷保存則に基づく残差出力

最初の段階では、サンプリングした電荷と保持時の電荷を等価とし、

$$
C_1\left(V_{\mathrm{in}} - \frac{V_{\mathrm{DD}}}{2}\right) = C_1(V_0 - V_{\mathrm{out1}})
$$

と書けるため、整理して:

$$
V_{\mathrm{out1}} = V_{\mathrm{DD}} - V_{\mathrm{in}}
$$

MSBビット $D_1$ の判定則

$$
D_1 =
\begin{cases}
1 & (V_{\mathrm{in}} \geq V_0) \
0 & (V_{\mathrm{in}} < V_0)
\end{cases}
$$


3. ステージ2:LSB(D₂)の生成とVout₂の一般化

補助項の定義

スイッチ構成により挿入される電圧は:

$$
\mathrm{aux_term} = D_1 \cdot V_1 + (1 - D_1) \cdot (-V_1) = (2D_1 - 1)V_1
$$


残差電圧Vout₂の電荷保存式

充電と保持の電荷バランスより:

$$
C_1(V_{\mathrm{in}} - \frac{V_{\mathrm{DD}}}{2}) + C_2(-\frac{V_{\mathrm{DD}}}{2})
= C_1(V_0 - V_{\mathrm{out2}}) + C_2(\mathrm{aux_term} - V_{\mathrm{out2}})
$$

展開して:

$$
(C_1 + C_2) V_{\mathrm{out2}}
= C_1 V_0 - C_1(V_{\mathrm{in}} - \frac{V_{\mathrm{DD}}}{2})

  • C_2 \cdot \frac{V_{\mathrm{DD}}}{2}
  • C_2 \cdot \mathrm{aux_term}
    $$

整理されたVout₂の一般式

$$
V_{\mathrm{out2}} =
\frac{-C_1 V_{\mathrm{in}} + C_1 V_{\mathrm{DD}} + \tfrac{C_2 V_{\mathrm{DD}}}{2} - C_2 (2D_1 - 1) V_1}
{C_1 + C_2}
$$


4. 判定ビット D₂ の決定

$$
D_2 =
\begin{cases}
1 & (V_{\mathrm{out2}} < V_0) \
0 & (V_{\mathrm{out2}} \geq V_0)
\end{cases}
$$


# Program Name: pipeline_adc_1.5stage_ramp.py
# Creation Date: 20250821
# Overview: Simulate and visualize a 1.5-stage pipeline ADC operation using a ramp input waveform.
# Usage: Run the script to observe residue voltages and bit outputs (D1, D1_bar, D2, D2_bar), and detect threshold crossings.

import numpy as np
import matplotlib.pyplot as plt

# --- Parameter Definitions ---
VDD = 1.0
C1 = 1.0
C4 = 1.0
V0 = VDD / 2
V1 = 1.0
Vin = np.linspace(0, VDD, 100000)

# --- Stage 1 ---
D1_bar = (Vin < V0).astype(int)
D1 = 1 - D1_bar
Vout1 = V0 - (Vin - VDD / 2)

# --- Stage 2 ---
aux_term = D1 * V1 + D1_bar * (-V1)
numerator = C1 * (Vin - VDD / 2) + (C1 / 4) * (-VDD / 2) - (C4 / 4) * aux_term
denominator = C1 + (C4 / 4)
Vout2 = (C1 * V0 - numerator) / denominator
D2 = (Vout2 < V0).astype(int)
D2_bar = 1 - D2

# --- Print Formulas ---
print("D1_bar = 1 if Vin < V0 else 0")
print("D1 = 1 - D1_bar")
print("Vout1 = V0 - (Vin - VDD/2)")
print("aux_term = D1 * V1 + D1_bar * (-V1)")
print("Vout2 = (C1*V0 - [C1*(Vin - VDD/2) + (C1/4)*(-VDD/2) - (C4/4)*aux_term]) / (C1 + C4/4)")
print("D2 = 1 if Vout2 < V0 else 0")
print("D2_bar = 1 - D2")

# --- Plotting ---
plt.figure()
plt.plot(Vin, label='Vin (Input Ramp)')
plt.axhline(V0, color='red', linestyle='--', label='Threshold V0')
plt.xlabel('Sample Index')
plt.ylabel('Vin [V]')
plt.title('Input Ramp Waveform')
plt.legend()
plt.grid(True)

plt.figure()
plt.plot(Vin, Vout1, label='Vout1')
plt.axhline(V0, color='gray', linestyle='--', label='Threshold V0')
plt.xlabel('Vin [V]')
plt.ylabel('Vout1 [V]')
plt.title('Stage 1 Residue Vout1 vs Vin')
plt.legend()
plt.grid(True)

plt.figure()
plt.plot(Vin, Vout2, label='Vout2')
plt.axhline(V0, color='gray', linestyle='--', label='Threshold V0')
plt.xlabel('Vin [V]')
plt.ylabel('Vout2 [V]')
plt.title('Stage 2 Residue Vout2 vs Vin')
plt.legend()
plt.grid(True)

plt.figure()
plt.plot(Vin, D2, label='D2')
plt.xlabel('Vin [V]')
plt.ylabel('D2')
plt.title('D2 Output vs Vin')
plt.legend()
plt.grid(True)

# --- Find Vin where Vout2 ≈ VDD/2 ---
target_value = VDD / 2
tolerance = 1e-3
indices = np.where(np.isclose(Vout2, target_value, atol=tolerance))[0]
Vin_at_half_Vout2 = Vin[indices]

print(f"\nVout2 ≈ {VDD/2} となる Vin の値(許容誤差 {tolerance}):")
for v in Vin_at_half_Vout2:
    print(f"{v:.5f} V")

# --- Detect D2 transitions ---
d2_diff = np.diff(D2)
rising_edges = np.where(d2_diff == 1)[0] + 1
falling_edges = np.where(d2_diff == -1)[0] + 1

print("\n--- D2のクロック変化タイミング ---")
for idx in rising_edges:
    print(f"↑ Rising Edge at Vin = {Vin[idx]:.5f} V (index {idx})")
for idx in falling_edges:
    print(f"↓ Falling Edge at Vin = {Vin[idx]:.5f} V (index {idx})")

# --- Plot D2 transitions ---
plt.figure()
plt.plot(Vin, D2, label='D2')
plt.plot(Vin[rising_edges], D2[rising_edges], 'ro', label='Rising Edge')
plt.plot(Vin[falling_edges], D2[falling_edges], 'bo', label='Falling Edge')
plt.xlabel('Vin [V]')
plt.ylabel('D2')
plt.title('D2 Output with Edge Detection')
plt.legend()
plt.grid(True)

plt.show()
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?