1. 図が示している「Time-Based ADC」の基本構造
図は Voltage → Time → Digital という 3 段階の変換フローを示しています。
Analog Voltage → Time Information → Digital Code
(Vin) (Δt, pulse) (bits)
この方式の ADC は、SAR や ΔΣ のように「電圧を直接量子化」するのではなく、
電圧を一度「時間」に変換し、その“時間”を TDC が量子化する
という構成になっています。
2. VTC(Voltage-to-Time Converter)とは
図の左側にある VTC は「電圧 → 時間」変換器です。
代表的な動作イメージ:
- Vin をコンパレータ/ランプ発生器/充電回路に与える
- Vin が大きいほど「閾値に達する時間」が短い/長い
- こうして入力電圧を パルス幅 または 遅延時間 に変換する
図中の「Time Domain(矩形波)」は、これを示したものです。
例:
- Vin が高い → パルス幅が長い
- Vin が低い → パルス幅が短い
あるいはその逆でも設計によって成立します。
VTC の出力は 幅が Vin に比例したパルス または 電圧依存の遅延時間 Δt になります。
3. TDC(Time-to-Digital Converter)とは
図の右側の TDC は「時間 → デジタル」変換器です。
VTC が生成した
- パルス幅(PW)
- 遅延時間(Δt)
- 位相差(phase difference)
などを、TDC が「何ステップ分か」に量子化し、ビット列として出力します。
出力例:
00101
11100
…
つまり図の「Digital Domain」を意味しています。
TDC の例:
- DLL 型 TDC(遅延セルの均一化)
- Vernier TDC(差分遅延で ps 精度)
- GRO TDC(リング発振器で時間→位相→サイクル数へ)
いずれも 時間そのものを LSB として量子化します。
4. なぜ Voltage → Time → Digital なのか(メリット)
Time-Based ADC 方式の意義:
① 先端 CMOS で有利
- 低電圧(0.5 V 以下)だと電圧としての精度が取りづらい
- しかし「遅延」や「発振周波数」はデジタルプロセスでむしろ高精度になる
→ FinFET/GAA 世代で有利
② アナログ回路をほぼ使わない
- OTA や大容量 CDAC が不要
- ロジック中心 → 面積が小さい、速度が出る
③ 非常に高速
- GHz クロック領域での TDC / VCO を活用できる
- RF 〜 高速通信に向く
5. 図のまとめ(1枚で表現すると)
図は次の内容を一目で示しています。
(電圧領域)
アナログ信号 Vin
↓
[VTC]
↓
(時間領域)
パルス幅・遅延・位相差 Δt
↓
[TDC]
↓
(デジタル領域)
000110101...
- Voltage Domain(連続値の電圧)
- Time Domain(電圧が時間情報に変換される)
- Digital Domain(時間がデジタルコードになる)
という3段階の変換メカニズムそのものです。
# ============================================================
# Program Name: time_based_adc_numeric_input.py
# Creation Date: 20251203
# Purpose: Numeric-input interactive demo of Voltage→Time→Digital conversion
# ============================================================
import numpy as np
import matplotlib.pyplot as plt
from numba import njit
from ipywidgets import interact, FloatText, Button, VBox, HBox
import datetime
# ============================================================
# PARAM_INIT:パラメータ一元管理
# ============================================================
PARAM_INIT = {
"fs": 200e6, # Sampling frequency [Hz]
"duration": 200e-9, # Duration [sec]
"vtc_gain": 3e-9, # VTC gain [sec/V]
"tdc_lsb": 20e-12, # TDC LSB [sec]
"freq": 10e6, # Input sine freq
"amp": 0.5 # Input amplitude
}
# ============================================================
# Voltage Model
# ============================================================
def generate_sine(freq, amp, fs, T):
t = np.arange(0, T, 1/fs)
v = amp * np.sin(2*np.pi*freq*t)
return t, v
# ============================================================
# VTC Model(Voltage → Time)
# ============================================================
@njit
def vtc_model(v, gain):
return gain * v
# ============================================================
# TDC Model(Time → Digital)
# ============================================================
@njit
def tdc_model(tvals, lsb):
return np.floor(tvals / lsb).astype(np.int32)
# ============================================================
# Plot Function
# ============================================================
def plot_all(freq, amp, gain, lsb):
fs = PARAM_INIT["fs"]
T = PARAM_INIT["duration"]
# Voltage Domain
t, vin = generate_sine(freq, amp, fs, T)
# Voltage → Time
t_vtc = vtc_model(vin, gain)
# Time → Digital
code = tdc_model(t_vtc, lsb)
# --------------------------
# Plot
# --------------------------
fig, ax = plt.subplots(3,1, figsize=(7,8))
fig.tight_layout(pad=3)
# Voltage Domain
ax[0].plot(t*1e9, vin)
ax[0].set_title("Voltage Domain (Vin) [V]")
ax[0].set_xlabel("Time [ns]")
ax[0].grid(True)
# Time Domain
ax[1].plot(t*1e9, t_vtc*1e12)
ax[1].set_title("Time Domain (VTC Output) [ps]")
ax[1].set_xlabel("Time [ns]")
ax[1].grid(True)
# Digital Domain
ax[2].step(t*1e9, code, where='post')
ax[2].set_title("Digital Domain (TDC Code)")
ax[2].set_xlabel("Time [ns]")
ax[2].grid(True)
plt.show()
# ============================================================
# Save Functions
# ============================================================
def save_png():
ts = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
plt.savefig(f"time_adc_{ts}.png", dpi=300)
def save_pdf():
ts = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
plt.savefig(f"time_adc_{ts}.pdf")
# ============================================================
# UI Widgets(数値入力方式)
# ============================================================
freq_box = FloatText(value=PARAM_INIT["freq"], description="Freq [Hz]")
amp_box = FloatText(value=PARAM_INIT["amp"], description="Amp [V]")
gain_box = FloatText(value=PARAM_INIT["vtc_gain"], description="VTC gain [s/V]")
lsb_box = FloatText(value=PARAM_INIT["tdc_lsb"], description="TDC LSB [s]")
btn_plot = Button(description="Plot")
btn_png = Button(description="Save PNG")
btn_pdf = Button(description="Save PDF")
btn_reset = Button(description="Reset")
# ボタンイベント
def on_plot_clicked(b):
plot_all(freq_box.value, amp_box.value, gain_box.value, lsb_box.value)
def on_png(b):
save_png()
def on_pdf(b):
save_pdf()
def on_reset(b):
freq_box.value = PARAM_INIT["freq"]
amp_box.value = PARAM_INIT["amp"]
gain_box.value = PARAM_INIT["vtc_gain"]
lsb_box.value = PARAM_INIT["tdc_lsb"]
btn_plot.on_click(on_plot_clicked)
btn_png.on_click(on_png)
btn_pdf.on_click(on_pdf)
btn_reset.on_click(on_reset)
# ============================================================
# UI レイアウト
# ============================================================
ui = VBox([
HBox([freq_box, amp_box]),
HBox([gain_box, lsb_box]),
HBox([btn_plot, btn_png, btn_pdf, btn_reset])
])
ui

