11
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FPGAの入出力タイミング制約を可視化するシミュレータを作った

11
Last updated at Posted at 2026-04-05

FPGA タイミング制約シミュレータを作った — 波形・スラック・XDC をリアルタイム可視化

タイトルを更新しました 4/5

はじめに

FPGA設計で set_input_delay / set_output_delay を書くとき、「この値どこから来てるんだっけ?」と毎回なります。

データシートから Tco を拾って、ボード遅延を足して、セットアップ/ホールドのマージンを計算して……。
頭の中だけで追うのは辛いので、パラメータを動かしながらリアルタイムに波形・スラック・XDC制約を確認できるツールを作りました。

Live Demo: https://MameMame777.github.io/fpga-timing-simulator/
GitHub: https://github.com/MameMame777/fpga-timing-simulator

FPGA Timing Constraint Simulator

できること

機能 説明
タイミング解析 Setup/Hold スラックをリアルタイム計算。パラメータ変更で即座に Pass/Fail 判定
波形アニメーション Launch Edge → データ伝搬 → Capture Edge の一連の流れを Canvas で可視化
タイミングダイアグラム クロックエッジ、データウィンドウ、スラックを SVG で静的表示
XDC 制約生成 create_clockset_input_delayset_output_delay をコピー可能な形で出力
System / Source Sync 共通クロック方式とフォワードクロック方式の両方に対応
SDR / DDR R→R, R→F, F→R, F→F の全エッジコンボに対応
Independent Capture Clock Capture側クロックを Launch側と独立に設定可能(period/duty/port)
Routing min/max FPGA内部ルーティング遅延を min/max で入力し、解析式とXDCへ反映
ジッタ / 不確実性 set_input_jitter, set_system_jitter, set_clock_uncertainty をモデリング

なぜ作ったか

 タイミング制約ってわかりにくい!

  • Input/Output Path の制約を書く際、どの値がどの XDC コマンドに対応するのかが分かりにくい
  • Source Synchronous でフォワードクロックを使う場合の delay 計算が system sync と異なる
  • DDR や falling edge キャプチャの -clock_fall フラグの付け忘れに気づきにくい
  • Launch/Capture クロックを分離したときのエッジ関係(特に F→R / R→F)を直感的に把握しづらい

このツールでは各パラメータをスライダーで動かすと、波形・スラック値・XDC テキストが即座に連動して更新されるので、制約の意味を体感的に理解できます。

技術スタック

React 19 + TypeScript 5.9 (strict) + Vite 8
テスト: Vitest (36ケース)
デプロイ: GitHub Pages (GitHub Actions 自動デプロイ)
ランタイム依存: React / React-DOM のみ

アーキテクチャ

src/
├── types/timing.ts           ← ドメイン型定義 (純粋 interface)
├── engine/timing-analyzer.ts ← 計算ロジック (純粋関数, UI非依存)
├── utils/xdc-generator.ts    ← XDC制約テキスト生成 (純粋関数)
├── components/               ← React UIコンポーネント
├── canvas/WaveformRenderer.ts← Canvas 2D アニメーション
└── svg/                      ← SVG 可視化コンポーネント

ポイントは計算ロジック (engine) を純粋関数として UI から完全に分離していること。これにより:

  • analyzeInputPath() / analyzeOutputPath() を Vitest で直接テスト可能
  • 将来 CLI ツールや別の UI フレームワークへの移植が容易

Setup / Hold スラック計算の詳細

タイミング解析の核心部分を解説します。

System Synchronous (共通クロック)

image.png

// データ到着時間
dataArrivalMax = tcoSourceMax + boardDelayMax + routingDelayMax
dataArrivalMin = tcoSourceMin + boardDelayMin + routingDelayMin

// Required time (制約側)
setupRequired = effectiveWindow + skew  tsu  totalUncertainty
holdRequired  = skew + th + totalUncertainty

// スラック (正=OK, 負=Violation)
setupSlack = setupRequired  dataArrivalMax
holdSlack  = dataArrivalMin  holdRequired

effectiveWindow はエッジコンボで変わります:

Launch → Capture effectiveWindow
R→R T (= period)
R→F T × duty
F→R T × (1 − duty)
F→F T

Source Synchronous (フォワードクロック)

image.png

Source sync ではクロックがデータと一緒に伝搬するため、Required time の計算式が変わります。
なお データ到着時間 (dataArrival) は System Sync と同一です — Source sync で相殺されるのは XDC の set_input_delay 式上の board delay であり、解析エンジン内部ではデータ経路全体(tco + boardDelay + routingDelay)を追跡しています。

// データ到着時間(System Sync と同一)
dataArrivalMax = tcoSourceMax + boardDelayMax + routingDelayMax
dataArrivalMin = tcoSourceMin + boardDelayMin + routingDelayMin

// Required time: フォワードクロックの到着時間が加わる
setupRequired = effectiveWindow + clockArrivalMin + skew  tsu  totalUncertainty
holdRequired  = clockArrivalMax + skew + th + totalUncertainty

ポイント: Setup には clockArrivalMin(クロック早着 = マージン減)、Hold には clockArrivalMax(クロック遅着 = 制約厳しい)を使います。

Independent Capture Clock(Captureクロック分離)

Captureクロックを独立させると、computeEdgeTimes は以下のルールで有効キャプチャエッジを決めます。

// launchTime より後に来る、指定極性の最初の capture edge を採用
captureTime = firstCaptureEdgeAfter(launchTime)
effectiveWindow = captureTime - launchTime

同じ period/duty を設定しても、独立Captureモードでは「captureクロックとして別扱い」で描画・解析します。

XDC 制約生成

パラメータを入力すると、そのまま Vivado に貼れる XDC を自動生成します:

# Clock definition
create_clock -period 10.000 -name sys_clk [get_ports sys_clk]
set_input_jitter [get_clocks -of_objects [get_ports sys_clk]] 0.100
set_system_jitter 0.050
set_clock_uncertainty 0.100 [get_clocks sys_clk]

# Input delay constraints (System Synchronous)
# input_delay_max = tco_max(2.0) + board_delay_max(1.0) + routing_delay_max(0.5) = 3.500
set_input_delay -max 3.500 -clock sys_clk [get_ports data_in]
# input_delay_min = tco_min(1.0) + board_delay_min(0.3) + routing_delay_min(0.2) = 1.500
set_input_delay -min 1.500 -clock sys_clk [get_ports data_in]

# Output delay constraints
# output_delay_max = board_delay_max(1.0) + routing_delay_max(0.5) + tsu_dest(2.0) = 3.500
set_output_delay -max 3.500 -clock sys_clk [get_ports data_out]
# output_delay_min = board_delay_min(0.3) + routing_delay_min(0.2) - th_dest(0.3) = 0.200
set_output_delay -min 0.200 -clock sys_clk [get_ports data_out]

System Sync vs Source Sync の出力の違い

System Sync Source Sync
input_delay の基準クロック システムクロック フォワードクロック
input_delay_max の式 tco_max + board_delay_max + routing_delay_max + skew tco_max + routing_delay_max + skew
-clock 引数 sys_clk fwd_clk

Source sync では XDC の set_input_delay 式において データとフォワードクロックが同じボード上を伝搬するため board delay が相殺されます(forwarded clock 基準で記述するため)。一方で、FPGA内部ルーティング遅延は相殺されないため routing_delay は両モードで寄与します。

-clock_fall フラグの落とし穴

Capture edge が falling の場合、-clock_fall を付けないと Vivado は rising edge 基準で解析します。結果として本来 fail のパスが通ってしまう偽陽性が発生しうるので注意してください。

# Falling edge capture の場合
set_input_delay -max 3.500 -clock_fall -clock sys_clk [get_ports data_in]

可視化の技術的な工夫

Canvas vs SVG の使い分け

技術 用途 理由
Canvas 2D 波形アニメーション requestAnimationFrame で 60fps 描画。ピクセル単位の制御が必要
SVG (React) タイミング図・パスブロック図 宣言的レンダリング。DevTools で DOM として検査可能

GUIからパラメータを変更できます。リアルタイムにタイミングチャートに反映されます。
image.png

タイミングダイアグラム

image.png

SVG で描画した静的タイミング図。クロックの立ち上がり/立ち下がりエッジ、データ到着ウィンドウ、Setup/Hold スラックを1枚に集約しています。

Output Path の解析

Output Path では FPGA 内部の tco(Clock-to-Output)が起点となります:

// データ到着時間
dataArrivalMax = fpga.tcoMax + boardDelayMax + routingDelayMax
dataArrivalMin = fpga.tcoMin + boardDelayMin + routingDelayMin

// Required time(相手デバイスの tsu/th 基準)
setupRequired = effectiveWindow + skew  tsuDest  totalUncertainty
holdRequired  = skew + thDest + totalUncertainty

Input Path と構造は同じですが、起点が外部デバイスの tco ではなく FPGA の tco に、制約のタイミング要件が FPGA の tsu/th ではなく相手デバイスの tsu/th になる点が異なります。

テスト設計

タイミング計算のようなドメインロジックは、手計算した期待値をコメントに残すのが重要です:

it('basic R→R: positive setup slack', () => {
  const r = analyzeInputPath(baseClock, baseInput, baseFPGA, 'system_sync', RR);
  // setupRequired = window(10) + skew(0) - tsu(1.2) - uncertainty(0) = 8.8
  // dataArrivalMax = tcoMax(2) + boardMax(1.5) = 3.5
  // setupSlack = 8.8 - 3.5 = 5.3
  expect(r.setupSlack).toBeCloseTo(5.3);
});

テストケース 36件の内訳:

describe グループ 件数 内容
computeEdgeTimes 6 4エッジコンボ + 非対称 duty (30%) + 極小 period (1ns)
analyzeInputPath — system sync 10 setup/hold 正常・violation・スキュー・ジッタ・routing 寄与 等
analyzeInputPath — source sync 4 fwd clock 到着・clockSkew 平均・非対称遅延・ユーザskew 累積
analyzeOutputPath — system sync 5 基本 R→R / hold / uncertainty / F→R / routing 寄与
analyzeOutputPath — source sync 1 source sync output path
エッジケース 4 ゼロジッタ・R→R=F→F 対称性・R→F+F→R 総和・全数値 finite
independent capture clock 6 高速/低速 capture period・edge 探索・window 反映
合計 36

GitHub Pages へのデプロイ

Vite の base パス設定

// vite.config.ts
export default defineConfig({
  plugins: [react()],
  base: '/fpga-timing-simulator/',
})

GitHub Pages は https://<user>.github.io/<repo>/ のサブパスから配信されるため、base を設定しないとアセットの読み込みが壊れて白画面になります。

GitHub Actions ワークフロー

# main push 時に自動デプロイ
jobs:
  build:
    steps:
      - npm ci → npm test → npm run build
      - actions/upload-pages-artifact (dist/)
  deploy:
    needs: build
    uses: actions/deploy-pages@v4

Settings → Pages → SourceGitHub Actions を選択するのを忘れずに。

まとめ

  • FPGA I/O タイミング制約の計算過程をインタラクティブに可視化するツールを作りました
  • パラメータを動かすと波形・スラック・XDC がリアルタイムに連動して更新されます
  • System Sync / Source Sync / DDR / independent capture clock / routing min-max / ジッタ・不確実性まで対応
  • 計算ロジックを純粋関数として分離し、36件のユニットテストで品質を担保

FPGA のタイミング制約を学習する際や、実際の設計でパラメータの影響を素早く確認したい場面で活用していただければ幸いです。

Live Demo: https://MameMame777.github.io/fpga-timing-simulator/
GitHub: https://github.com/MameMame777/fpga-timing-simulator


フィードバックや改善提案は GitHub Issues でお待ちしています。

11
7
2

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
11
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?