Lecture 7: Circuit Design & Integration
Part II: Devices & Circuits - SCE Futures
Learning Objectives¶
By the end of this session, you will be able to:
- Compose RSFQ/AQFP gates into functional circuit blocks
- Analyze timing constraints and clock distribution in SCE circuits
- Apply pipeline balancing techniques for SFQ pulse propagation
- Use standard cell libraries for SCE design
- Understand interconnect challenges (inductance matching, PTLs)
- Survey available CAD tools for SCE circuit design
# Setup
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.patches import FancyArrowPatch, FancyBboxPatch, Circle
import numpy as np
COLORS = {
'primary': '#2196F3',
'secondary': '#FF9800',
'success': '#4CAF50',
'danger': '#f44336',
'dark': '#1a1a2e',
'light': '#f5f5f5',
'purple': '#9C27B0',
'cyan': '#00BCD4',
'clock': '#E91E63',
'data': '#4CAF50',
'jtl': '#FF9800',
}
plt.rcParams['figure.facecolor'] = 'white'
plt.rcParams['axes.facecolor'] = 'white'
plt.rcParams['font.size'] = 11
print("Setup complete.")
Setup complete.
1. From Gates to Functional Blocks¶
In the previous lectures, we learned about individual SCE logic gates (RSFQ, AQFP). Now we must compose them into functional blocks - adders, multipliers, register files, and eventually complete processing units.
Design Hierarchy¶
Level 0: Devices JJs, inductors, resistors
↓
Level 1: Cells AND, OR, DFF, JTL
↓
Level 2: Blocks Adder, Multiplier, Register
↓
Level 3: Subsystems ALU, MAC unit, Memory controller
↓
Level 4: System Complete processor/accelerator
Key Differences from CMOS¶
| Aspect | CMOS | SCE (RSFQ/AQFP) |
|---|---|---|
| Signal representation | Voltage levels | SFQ pulses / flux states |
| Logic style | Combinational + sequential | All sequential (pipelined) |
| Fan-out | Easy (voltage buffers) | Limited (pulse splitting) |
| Timing | Clock edges | Pulse arrival times |
| Interconnect | RC-dominated | L-dominated (inductance) |
The Pipelining Imperative¶
In RSFQ logic, every gate is a pipeline stage. An SFQ pulse entering a gate produces an output pulse one clock cycle later.
This means:
- All paths through a circuit must have matched delay
- Extra delay stages (DFFs) must be inserted to balance paths
- Feedback loops require careful timing analysis
# Visualize: CMOS vs RSFQ circuit structure
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# CMOS combinational logic
ax = axes[0]
ax.set_xlim(0, 10)
ax.set_ylim(0, 8)
ax.set_aspect('equal')
ax.axis('off')
ax.set_title('CMOS: Combinational + Sequential', fontsize=12, fontweight='bold')
# Input registers
for i in range(2):
rect = FancyBboxPatch((0.5, 2 + i*2.5), 1.2, 1, boxstyle="round,pad=0.05",
facecolor=COLORS['primary'], edgecolor='black', linewidth=2)
ax.add_patch(rect)
ax.text(1.1, 2.5 + i*2.5, 'DFF', ha='center', va='center', fontsize=9, color='white', fontweight='bold')
# Combinational cloud
from matplotlib.patches import Ellipse
ellipse = Ellipse((4.5, 4), 3, 4, facecolor=COLORS['light'], edgecolor='black', linewidth=2)
ax.add_patch(ellipse)
ax.text(4.5, 4, 'Combinational\nLogic\n(multi-level)', ha='center', va='center', fontsize=10)
# Output register
rect = FancyBboxPatch((7.5, 3.5), 1.2, 1, boxstyle="round,pad=0.05",
facecolor=COLORS['primary'], edgecolor='black', linewidth=2)
ax.add_patch(rect)
ax.text(8.1, 4, 'DFF', ha='center', va='center', fontsize=9, color='white', fontweight='bold')
# Arrows
ax.annotate('', xy=(3, 4.5), xytext=(1.7, 4.5), arrowprops=dict(arrowstyle='->', color='black', lw=1.5))
ax.annotate('', xy=(3, 2.5), xytext=(1.7, 2.5), arrowprops=dict(arrowstyle='->', color='black', lw=1.5))
ax.annotate('', xy=(7.5, 4), xytext=(6, 4), arrowprops=dict(arrowstyle='->', color='black', lw=1.5))
ax.text(5, 0.5, 'Timing: setup/hold at register boundaries\nLogic levels: unlimited (within cycle)',
ha='center', fontsize=9)
# RSFQ pipelined logic
ax = axes[1]
ax.set_xlim(0, 10)
ax.set_ylim(0, 8)
ax.set_aspect('equal')
ax.axis('off')
ax.set_title('RSFQ: Fully Pipelined', fontsize=12, fontweight='bold')
# Pipeline stages
stage_colors = [COLORS['success'], COLORS['secondary'], COLORS['purple'], COLORS['cyan']]
stage_labels = ['AND', 'OR', 'XOR', 'DFF']
for i, (color, label) in enumerate(zip(stage_colors, stage_labels)):
rect = FancyBboxPatch((0.5 + i*2.3, 3), 1.8, 2, boxstyle="round,pad=0.05",
facecolor=color, edgecolor='black', linewidth=2)
ax.add_patch(rect)
ax.text(1.4 + i*2.3, 4, label, ha='center', va='center', fontsize=10, color='white', fontweight='bold')
ax.text(1.4 + i*2.3, 3.3, f'Stage {i}', ha='center', va='center', fontsize=8, color='white')
if i < 3:
ax.annotate('', xy=(2.5 + i*2.3, 4), xytext=(2.3 + i*2.3, 4),
arrowprops=dict(arrowstyle='->', color='black', lw=1.5))
# Clock line
ax.plot([0.5, 9.5], [2, 2], color=COLORS['clock'], linewidth=2, linestyle='--')
ax.text(5, 1.7, 'Global Clock', ha='center', fontsize=9, color=COLORS['clock'])
for i in range(4):
ax.annotate('', xy=(1.4 + i*2.3, 3), xytext=(1.4 + i*2.3, 2.2),
arrowprops=dict(arrowstyle='->', color=COLORS['clock'], lw=1.5))
ax.text(5, 0.5, 'Timing: every gate is a pipeline stage\nLogic levels: each adds 1 cycle latency',
ha='center', fontsize=9)
plt.tight_layout()
plt.show()
2. Timing & Clock Distribution¶
RSFQ Clocking¶
RSFQ circuits require a global clock distributed to every gate:
- Clock is itself an SFQ pulse train
- Generated by an on-chip oscillator or external source
- Distributed via clock trees (JTL networks)
Clock Tree Design¶
[CLK Source]
│
[Splitter]
/ \
[JTL] [JTL]
/ \
[Splitter] [Splitter]
/ \ / \
[Gate] [Gate] [Gate] [Gate]
Challenges:
- Skew: Different path lengths → different arrival times
- Jitter: Pulse timing variations
- Fan-out: Each split requires a splitter cell
AQFP Clocking¶
AQFP uses AC excitation rather than SFQ pulse clocks:
- Multi-phase AC current (typically 4-phase)
- Gates evaluate in sequence based on phase
- More tolerant to skew (adiabatic operation)
Phase 0 ──────┐ ┌──────
└────┘
Phase 1 ─────────┐ ┌───
└────┘
Phase 2 ────────────┐ ┌
└────┘
Phase 3 ───────────────┐
└──
# Visualize: Clock distribution and timing
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# RSFQ Clock Tree
ax = axes[0]
ax.set_xlim(0, 10)
ax.set_ylim(0, 10)
ax.set_aspect('equal')
ax.axis('off')
ax.set_title('RSFQ Clock Tree', fontsize=12, fontweight='bold')
# Clock source
circle = Circle((5, 9), 0.5, facecolor=COLORS['clock'], edgecolor='black', linewidth=2)
ax.add_patch(circle)
ax.text(5, 9, 'CLK', ha='center', va='center', fontsize=9, color='white', fontweight='bold')
# Level 1 splitter
rect = FancyBboxPatch((4.3, 7), 1.4, 0.8, boxstyle="round,pad=0.05",
facecolor=COLORS['jtl'], edgecolor='black', linewidth=2)
ax.add_patch(rect)
ax.text(5, 7.4, 'SPL', ha='center', va='center', fontsize=9, color='white', fontweight='bold')
# JTLs
for x in [3, 7]:
rect = FancyBboxPatch((x-0.5, 5.5), 1, 0.6, boxstyle="round,pad=0.05",
facecolor=COLORS['jtl'], edgecolor='black', linewidth=1.5)
ax.add_patch(rect)
ax.text(x, 5.8, 'JTL', ha='center', va='center', fontsize=8, color='white')
# Level 2 splitters
for x in [2, 4, 6, 8]:
rect = FancyBboxPatch((x-0.5, 4), 1, 0.6, boxstyle="round,pad=0.05",
facecolor=COLORS['jtl'], edgecolor='black', linewidth=1.5)
ax.add_patch(rect)
ax.text(x, 4.3, 'SPL', ha='center', va='center', fontsize=8, color='white')
# Logic gates (endpoints)
for x in [1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5]:
rect = FancyBboxPatch((x-0.4, 2), 0.8, 0.8, boxstyle="round,pad=0.05",
facecolor=COLORS['success'], edgecolor='black', linewidth=1.5)
ax.add_patch(rect)
# Draw connections
ax.plot([5, 5], [8.5, 7.8], 'k-', linewidth=1.5)
ax.plot([5, 3], [7, 6.1], 'k-', linewidth=1.5)
ax.plot([5, 7], [7, 6.1], 'k-', linewidth=1.5)
ax.plot([3, 2], [5.5, 4.6], 'k-', linewidth=1.5)
ax.plot([3, 4], [5.5, 4.6], 'k-', linewidth=1.5)
ax.plot([7, 6], [5.5, 4.6], 'k-', linewidth=1.5)
ax.plot([7, 8], [5.5, 4.6], 'k-', linewidth=1.5)
for i, x in enumerate([2, 4, 6, 8]):
ax.plot([x, x-0.5], [4, 2.8], 'k-', linewidth=1)
ax.plot([x, x+0.5], [4, 2.8], 'k-', linewidth=1)
ax.text(5, 0.5, 'Challenge: balance path lengths to minimize skew', ha='center', fontsize=9)
# AQFP 4-phase clocking
ax = axes[1]
ax.set_xlim(0, 10)
ax.set_ylim(0, 10)
ax.set_aspect('equal')
ax.axis('off')
ax.set_title('AQFP 4-Phase Excitation', fontsize=12, fontweight='bold')
# Time axis
t = np.linspace(0, 4*np.pi, 200)
phases = [0, np.pi/2, np.pi, 3*np.pi/2]
colors = [COLORS['primary'], COLORS['success'], COLORS['secondary'], COLORS['purple']]
for i, (phase, color) in enumerate(zip(phases, colors)):
y = 8 - i*1.8 + 0.6*np.sin(t + phase)
x_scaled = t / (4*np.pi) * 8 + 1
ax.plot(x_scaled, y, color=color, linewidth=2)
ax.text(0.5, 8 - i*1.8, f'φ{i}', ha='center', va='center', fontsize=10,
color=color, fontweight='bold')
# Gate chain showing phase progression
for i in range(4):
rect = FancyBboxPatch((1.5 + i*2, 0.5), 1.5, 1, boxstyle="round,pad=0.05",
facecolor=colors[i], edgecolor='black', linewidth=2)
ax.add_patch(rect)
ax.text(2.25 + i*2, 1, f'Gate\nφ{i}', ha='center', va='center', fontsize=9, color='white')
if i < 3:
ax.annotate('', xy=(3.2 + i*2, 1), xytext=(3 + i*2, 1),
arrowprops=dict(arrowstyle='->', color='black', lw=1.5))
plt.tight_layout()
plt.show()
3. Pipeline Balancing¶
In RSFQ/AQFP, all paths must be balanced - signals that need to arrive at a gate simultaneously must traverse the same number of pipeline stages.
The Problem¶
Consider a simple function: Y = (A AND B) OR C
A ──┬─[AND]──┬─[OR]── Y
B ──┘ │
C ───────────┘
Issue: The AND gate adds 1 cycle of latency. When C arrives at the OR gate, (A AND B) hasn't been computed yet!
The Solution: Delay Matching¶
Insert DFF (D flip-flop) stages to balance paths:
A ──┬─[AND]──┬─[OR]── Y
B ──┘ │
C ──[DFF]────┘
Now C is delayed by 1 cycle, matching the AND latency.
Path Balancing Algorithm¶
- Build the circuit graph: Nodes are gates, edges are connections
- Label each node: Assign pipeline stage number (depth from inputs)
- Find mismatches: For each gate, check if all inputs arrive at same stage
- Insert delays: Add DFFs to equalize arrival times
Timing Analysis Example¶
For Y = (A AND B) OR C at 20 GHz (50 ps clock):
| Signal | Path | Stages | Arrival Time |
|---|---|---|---|
| A, B | Input → AND → OR | 2 | 100 ps |
| C (unbalanced) | Input → OR | 1 | 50 ps |
| C (balanced) | Input → DFF → OR | 2 | 100 ps |
Without balancing: C arrives 50 ps early → race condition, wrong result.
With balancing: All signals arrive at cycle 2 → correct operation.
Cost of Balancing¶
Every DFF added:
- Area: ~400 μm² per DFF
- Energy: ~0.1-1 aJ per DFF per cycle
- Latency: Increases total pipeline depth
For complex circuits, balancing overhead can be 20-50% additional DFFs. This is a fundamental cost of fully-pipelined logic.
# Visualize: Pipeline balancing example
fig, axes = plt.subplots(2, 1, figsize=(12, 8))
# Unbalanced circuit
ax = axes[0]
ax.set_xlim(0, 12)
ax.set_ylim(0, 6)
ax.set_aspect('equal')
ax.axis('off')
ax.set_title('Unbalanced: Y = (A AND B) OR C', fontsize=12, fontweight='bold', color=COLORS['danger'])
# Inputs
for i, label in enumerate(['A', 'B', 'C']):
ax.text(0.5, 4.5 - i*1.5, label, ha='center', va='center', fontsize=12, fontweight='bold')
ax.plot([0.8, 1.5], [4.5 - i*1.5, 4.5 - i*1.5], 'k-', linewidth=2)
# AND gate
rect = FancyBboxPatch((2, 3.5), 1.5, 1.5, boxstyle="round,pad=0.05",
facecolor=COLORS['success'], edgecolor='black', linewidth=2)
ax.add_patch(rect)
ax.text(2.75, 4.25, 'AND', ha='center', va='center', fontsize=10, color='white', fontweight='bold')
# Connect A and B to AND
ax.plot([1.5, 2], [4.5, 4.5], 'k-', linewidth=2)
ax.plot([1.5, 2], [3, 3.8], 'k-', linewidth=2)
# OR gate
rect = FancyBboxPatch((5, 2.5), 1.5, 1.5, boxstyle="round,pad=0.05",
facecolor=COLORS['secondary'], edgecolor='black', linewidth=2)
ax.add_patch(rect)
ax.text(5.75, 3.25, 'OR', ha='center', va='center', fontsize=10, color='white', fontweight='bold')
# Connect AND to OR
ax.plot([3.5, 5], [4.25, 3.5], 'k-', linewidth=2)
# Connect C directly to OR (problem!)
ax.plot([1.5, 5], [1.5, 2.7], color=COLORS['danger'], linewidth=2, linestyle='--')
ax.text(3, 1.2, 'C arrives 1 cycle\ntoo early!', ha='center', fontsize=9, color=COLORS['danger'])
# Output
ax.plot([6.5, 7.5], [3.25, 3.25], 'k-', linewidth=2)
ax.text(8, 3.25, 'Y', ha='center', va='center', fontsize=12, fontweight='bold')
# Balanced circuit
ax = axes[1]
ax.set_xlim(0, 12)
ax.set_ylim(0, 6)
ax.set_aspect('equal')
ax.axis('off')
ax.set_title('Balanced: Added DFF delay on C path', fontsize=12, fontweight='bold', color=COLORS['success'])
# Inputs
for i, label in enumerate(['A', 'B', 'C']):
ax.text(0.5, 4.5 - i*1.5, label, ha='center', va='center', fontsize=12, fontweight='bold')
ax.plot([0.8, 1.5], [4.5 - i*1.5, 4.5 - i*1.5], 'k-', linewidth=2)
# AND gate
rect = FancyBboxPatch((2, 3.5), 1.5, 1.5, boxstyle="round,pad=0.05",
facecolor=COLORS['success'], edgecolor='black', linewidth=2)
ax.add_patch(rect)
ax.text(2.75, 4.25, 'AND', ha='center', va='center', fontsize=10, color='white', fontweight='bold')
# Connect A and B to AND
ax.plot([1.5, 2], [4.5, 4.5], 'k-', linewidth=2)
ax.plot([1.5, 2], [3, 3.8], 'k-', linewidth=2)
# DFF for C delay
rect = FancyBboxPatch((2, 1), 1.5, 1, boxstyle="round,pad=0.05",
facecolor=COLORS['primary'], edgecolor='black', linewidth=2)
ax.add_patch(rect)
ax.text(2.75, 1.5, 'DFF', ha='center', va='center', fontsize=10, color='white', fontweight='bold')
ax.plot([1.5, 2], [1.5, 1.5], 'k-', linewidth=2)
# OR gate
rect = FancyBboxPatch((5, 2.5), 1.5, 1.5, boxstyle="round,pad=0.05",
facecolor=COLORS['secondary'], edgecolor='black', linewidth=2)
ax.add_patch(rect)
ax.text(5.75, 3.25, 'OR', ha='center', va='center', fontsize=10, color='white', fontweight='bold')
# Connect AND to OR
ax.plot([3.5, 5], [4.25, 3.5], 'k-', linewidth=2)
# Connect DFF to OR (now balanced)
ax.plot([3.5, 5], [1.5, 2.7], color=COLORS['success'], linewidth=2)
ax.text(4.5, 1.2, '- Paths balanced', ha='center', fontsize=9, color=COLORS['success'])
# Output
ax.plot([6.5, 7.5], [3.25, 3.25], 'k-', linewidth=2)
ax.text(8, 3.25, 'Y', ha='center', va='center', fontsize=12, fontweight='bold')
# Timing annotation
ax.text(10, 3, 'Latency: 2 cycles\n(AND + OR)', ha='center', fontsize=10,
bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5))
plt.tight_layout()
plt.show()
4. Standard Cell Methodology¶
Like CMOS, SCE designs use standard cell libraries - pre-designed and characterized cells that can be instantiated and connected.
Typical RSFQ Cell Library (MIT-LL SFQ5ee Process)¶
| Cell | Function | JJ Count | Latency | Area (μm²) |
|---|---|---|---|---|
| JTL | Signal transmission | 2 | ~5 ps | 100 |
| SPL | Signal splitting | 3 | ~5 ps | 150 |
| DFF | D flip-flop | 5-6 | 1 cycle | 400 |
| AND | Logical AND | 7-8 | 1 cycle | 600 |
| OR | Logical OR | 6-7 | 1 cycle | 550 |
| XOR | Exclusive OR | 9-10 | 1 cycle | 750 |
| NOT | Inverter | 3-4 | 1 cycle | 300 |
Timing Parameters¶
At 20 GHz clock (50 ps period):
| Parameter | Typical Value | Notes |
|---|---|---|
| Clock period | 50 ps | At 20 GHz |
| Setup time | ~10 ps | Data before clock |
| Hold time | ~5 ps | Data after clock |
| Clock-to-Q | ~15 ps | Output delay |
| JTL delay | ~5 ps/stage | Signal propagation |
Timing margin: With 50 ps period and ~30 ps for setup + clock-to-Q, you have ~20 ps margin for interconnect and skew.
AQFP Cell Library (Typical 4-Phase)¶
| Cell | Function | JJ Count | Latency | Notes |
|---|---|---|---|---|
| Buffer | Regeneration | 2 | 1 phase | Basic element |
| MAJ | Majority gate | 4 | 1 phase | Core logic |
| NOT | Inverter | 2 | 0 | Constant input |
| AND | A AND B | 4 | 1 phase | MAJ(A, B, 0) |
| OR | A OR B | 4 | 1 phase | MAJ(A, B, 1) |
| Branch | Fan-out (1→2) | 4 | 1 phase | Requires splitter |
Majority Logic¶
AQFP uses majority logic, where the fundamental operation is:
$$\text{MAJ}(A, B, C) = AB + BC + AC$$
Any Boolean function can be expressed using majority gates and inverters. This is more efficient than AND/OR for many functions.
# Visualize: Standard cell examples
fig, axes = plt.subplots(2, 4, figsize=(14, 6))
cells = [
('JTL', 'Transmission', 2, COLORS['jtl']),
('SPL', 'Splitter', 3, COLORS['secondary']),
('DFF', 'Storage', 5, COLORS['primary']),
('AND', 'Logic', 7, COLORS['success']),
('OR', 'Logic', 7, COLORS['success']),
('XOR', 'Logic', 9, COLORS['success']),
('MAJ', 'AQFP Core', 4, COLORS['purple']),
('NDRO', 'Memory', 10, COLORS['cyan']),
]
for idx, (name, func, jj_count, color) in enumerate(cells):
ax = axes[idx // 4, idx % 4]
ax.set_xlim(0, 10)
ax.set_ylim(0, 10)
ax.set_aspect('equal')
ax.axis('off')
# Cell body
rect = FancyBboxPatch((1, 2), 8, 6, boxstyle="round,pad=0.1",
facecolor=color, edgecolor='black', linewidth=2)
ax.add_patch(rect)
# Cell name
ax.text(5, 6, name, ha='center', va='center', fontsize=16,
color='white', fontweight='bold')
# Function
ax.text(5, 4.2, func, ha='center', va='center', fontsize=10, color='white')
# JJ count
ax.text(5, 2.8, f'{jj_count} JJs', ha='center', va='center', fontsize=9, color='white')
# I/O ports
ax.plot([0, 1], [5, 5], 'k-', linewidth=2)
ax.plot([9, 10], [5, 5], 'k-', linewidth=2)
plt.tight_layout()
plt.show()
print("Standard cells are the building blocks for all SCE digital designs.")
print("Libraries are process-specific (MIT-LL, SeeQC, etc.)")
Standard cells are the building blocks for all SCE digital designs. Libraries are process-specific (MIT-LL, SeeQC, etc.)
5. Interconnect & Signal Integrity¶
Superconducting Interconnect¶
Unlike CMOS (RC-limited), SCE interconnect is inductance-dominated:
- Superconducting wires have zero DC resistance
- But they have significant kinetic inductance
- Signal propagation is governed by L/C (not RC)
Josephson Transmission Line (JTL)¶
For long-distance signal transmission, JTLs actively regenerate SFQ pulses:
Input ──[JJ]──L──[JJ]──L──[JJ]──L──[JJ]── Output
│ │ │ │
Bias Bias Bias Bias
Each JJ restores the pulse amplitude, preventing attenuation.
Passive Transmission Line (PTL)¶
For shorter distances, PTLs are simpler:
- Matched impedance (~1-5 Ω typical)
- Lower latency than JTL
- No active elements (no bias needed)
- Limited distance before attenuation
Impedance Matching¶
Critical for signal integrity:
$$Z_0 = \sqrt{\frac{L}{C}}$$
Where:
- L = inductance per unit length
- C = capacitance per unit length
Mismatched impedance causes reflections that corrupt SFQ pulses.
Layout Considerations¶
| Factor | Guideline |
|---|---|
| Wire width | Determines inductance (narrower = higher L) |
| Spacing | Cross-talk and magnetic coupling |
| Layer stack | Ground plane proximity affects Z₀ |
| Corners | Mitered corners reduce reflections |
| Via inductance | Minimize layer transitions |
# Visualize: JTL vs PTL interconnect
fig, axes = plt.subplots(2, 1, figsize=(12, 6))
# JTL
ax = axes[0]
ax.set_xlim(0, 12)
ax.set_ylim(0, 4)
ax.set_aspect('equal')
ax.axis('off')
ax.set_title('Josephson Transmission Line (JTL) - Active', fontsize=12, fontweight='bold')
# Draw JTL stages
for i in range(5):
x = 1 + i * 2.2
# JJ symbol (X)
ax.plot([x, x+0.3], [2, 2.3], 'k-', linewidth=2)
ax.plot([x, x+0.3], [2.3, 2], 'k-', linewidth=2)
# Inductor (coil)
for j in range(3):
circle = Circle((x + 0.6 + j*0.25, 2.15), 0.12, fill=False, color='black', linewidth=1.5)
ax.add_patch(circle)
# Bias arrow
ax.annotate('', xy=(x+0.15, 1.5), xytext=(x+0.15, 1.8),
arrowprops=dict(arrowstyle='->', color=COLORS['danger'], lw=1.5))
# Connection
if i < 4:
ax.plot([x+1.3, x+2.2], [2.15, 2.15], 'k-', linewidth=1.5)
ax.text(0.3, 2.15, 'In', ha='center', va='center', fontsize=10, fontweight='bold')
ax.text(11.7, 2.15, 'Out', ha='center', va='center', fontsize=10, fontweight='bold')
ax.text(6, 0.5, 'Active regeneration at each stage | Unlimited distance | Higher latency',
ha='center', fontsize=9)
# PTL
ax = axes[1]
ax.set_xlim(0, 12)
ax.set_ylim(0, 4)
ax.set_aspect('equal')
ax.axis('off')
ax.set_title('Passive Transmission Line (PTL) - Passive', fontsize=12, fontweight='bold')
# Signal line
ax.fill([1, 11, 11, 1], [2.3, 2.3, 2, 2], color=COLORS['jtl'], alpha=0.7)
ax.plot([1, 11], [2.3, 2.3], color=COLORS['jtl'], linewidth=2)
ax.plot([1, 11], [2, 2], color=COLORS['jtl'], linewidth=2)
# Ground planes
ax.fill([0.5, 11.5, 11.5, 0.5], [3.2, 3.2, 2.8, 2.8], color='gray', alpha=0.5)
ax.fill([0.5, 11.5, 11.5, 0.5], [1.5, 1.5, 1.1, 1.1], color='gray', alpha=0.5)
ax.text(6, 3, 'Ground plane', ha='center', va='center', fontsize=9, color='gray')
ax.text(6, 1.3, 'Ground plane', ha='center', va='center', fontsize=9, color='gray')
# Impedance annotation
ax.text(6, 2.15, f'Z₀ = √(L/C) ≈ 1-5 Ω', ha='center', va='center', fontsize=10,
fontweight='bold', color='white')
ax.text(0.3, 2.15, 'In', ha='center', va='center', fontsize=10, fontweight='bold')
ax.text(11.7, 2.15, 'Out', ha='center', va='center', fontsize=10, fontweight='bold')
ax.text(6, 0.5, 'No active elements | Lower latency | Distance limited by attenuation',
ha='center', fontsize=9)
plt.tight_layout()
plt.show()
6. CAD Tools for SCE¶
SCE circuit design uses specialized CAD tools, different from standard CMOS EDA.
Circuit Simulation¶
WRSPICE¶
- SPICE variant with Josephson junction models
- Time-domain simulation of SFQ circuits
- Industry standard for SCE simulation
JSIM¶
- Optimized JJ simulator
- Faster than WRSPICE for large circuits
- Developed at UC Berkeley
PSCAN2¶
- Margin analysis tool
- Finds operating ranges for bias currents
- Critical for yield optimization
Inductance Extraction¶
InductEx¶
- 3D inductance extraction for SCE layouts
- Accounts for kinetic inductance
- Essential for accurate timing
FastHenry¶
- General-purpose inductance solver
- Can be adapted for SCE
Layout & Verification¶
LASI¶
- Layout editor for SCE
- Free, widely used in academia
KLayout¶
- Modern layout editor
- Python scripting for DRC/LVS
Commercial Tools¶
- Cadence/Synopsys can be adapted
- Require custom PDKs and rule decks
Design Flow¶
Specification
↓
RTL / High-level design
↓
Logic synthesis (majority logic for AQFP)
↓
Path balancing (insert DFFs)
↓
Place & Route
↓
Inductance extraction (InductEx)
↓
Circuit simulation (WRSPICE)
↓
Margin analysis (PSCAN2)
↓
Tape-out
# Visualize: SCE Design Flow
fig, ax = plt.subplots(figsize=(10, 10))
ax.set_xlim(0, 10)
ax.set_ylim(0, 12)
ax.set_aspect('equal')
ax.axis('off')
ax.set_title('SCE Design Flow', fontsize=14, fontweight='bold')
stages = [
('Specification', COLORS['dark'], 'Requirements, architecture'),
('RTL Design', COLORS['primary'], 'Verilog/VHDL, high-level'),
('Logic Synthesis', COLORS['success'], 'Majority logic (AQFP)'),
('Path Balancing', COLORS['secondary'], 'Insert delay stages'),
('Place & Route', COLORS['purple'], 'Physical layout'),
('Extraction', COLORS['cyan'], 'InductEx, parasitic L'),
('Simulation', COLORS['primary'], 'WRSPICE, timing'),
('Margin Analysis', COLORS['danger'], 'PSCAN2, yield'),
('Tape-out', COLORS['success'], 'GDS-II to foundry'),
]
for i, (name, color, desc) in enumerate(stages):
y = 11 - i * 1.2
rect = FancyBboxPatch((2, y - 0.4), 6, 0.8, boxstyle="round,pad=0.05",
facecolor=color, edgecolor='black', linewidth=2)
ax.add_patch(rect)
ax.text(5, y, name, ha='center', va='center', fontsize=11,
color='white', fontweight='bold')
ax.text(8.5, y, desc, ha='left', va='center', fontsize=9)
if i < len(stages) - 1:
ax.annotate('', xy=(5, y - 0.6), xytext=(5, y - 0.4),
arrowprops=dict(arrowstyle='->', color='black', lw=2))
# Iteration arrow
ax.annotate('', xy=(1.5, 5.5), xytext=(1.5, 2.5),
arrowprops=dict(arrowstyle='->', color=COLORS['danger'], lw=2,
connectionstyle='arc3,rad=0.3'))
ax.text(0.8, 4, 'Iterate\nif margins\nfail', ha='center', fontsize=9, color=COLORS['danger'])
plt.tight_layout()
plt.show()
Summary¶
Key Takeaways¶
Gates to blocks: SCE design uses hierarchical composition, but every gate is a pipeline stage
Timing is critical:
- RSFQ: 50 ps clock period at 20 GHz, ~20 ps margin for routing
- AQFP: 4-phase AC excitation, data advances one phase per gate
- All paths must be balanced
Pipeline balancing:
- Insert DFFs on shorter paths to align signal arrival
- Overhead: 20-50% additional DFFs for complex circuits
- Each DFF: ~400 μm², ~0.1-1 aJ/cycle
Standard cells:
- RSFQ: JTL, DFF, AND, OR (5-10 JJs each)
- AQFP: Buffer, MAJ gate (2-4 JJs each)
- Libraries are process-specific (MIT-LL, SeeQC, etc.)
Interconnect:
- JTL: Active regeneration, unlimited distance
- PTL: Passive, lower latency, ~1-5 Ω impedance
- Matching critical to avoid reflections
CAD tools: WRSPICE (simulation), InductEx (extraction), PSCAN2 (margins)