同様に、入力が 1 の場合、シーケンス検出器は最初の 1 を待っているのか、それとも 10 を受信して 101 の確認を控えているのか。過去の情報を保持し、将来の判断に関連する情報を保存する必要があります。これが状態です。タイミング論理の核心は状態の保持にあり、クロックは状態変化を同期設計で整理する方法であり、すべてのタイミング回路にクロックが必要というわけではありません。
理解すべき問題 本稿の入り口 重要な違い
データはいつ記憶素子を通過できるか ラッチとフリップフロップ トランスペアレントウィンドウとサンプリングエッジ
なぜ遅くしてもエラーが発生しうるか セットアップ、ホールド、スキュー 最長パスと最短パス
入力の履歴をどう記憶するか レジスタ、カウンター、FSM 状態の意味と更新条件
非同期入力はどのように接続するか メタステーブルと CDC レベルの信頼性とメッセージの完全性
電源投入時にどのように確定状態に入るか リセットと起動 リセットの有効化とリリースタイミング
フィードバック記憶から D フリップフロップへ
クロス結合されたゲート回路は、2つの安定状態を形成できます。アクティブハイの NOR 型 SR ラッチを例に挙げると、方程式は Q=¬(R+Q̄)、Q̄=¬(S+Q) です。S=1 になると、まず Q̄=0 が強制され、フィードバックにより Q=1 になります。S が 0 に戻っても、フィードバックによってこの状態が維持されます。
S R NOR 型 SR ラッチの動作
0 0 元の状態を保持
1 0 セット、Q=1
0 1 リセット、Q=0
1 1 両方の出力が 0 になり、補完関係が失われる;同時に解除されると結果は不確定
NAND 型は通常、アクティブロー入力を採用しており、禁止組み合わせは上記の表と逆になり、2つの入力極性を混用することはできません。電源投入時にも、フィードバックラッチがどちらの状態になるかは自然に決まりません。システムで初期値を確定させる必要がある場合は、明示的な初期化またはリセットメカニズムを採用すべきです。
D ラッチは、データ D とイネーブル E を使用して、通常の動作における SR の禁止組み合わせを回避します。アクティブハイイネーブルの場合、E=1 の間、伝搬遅延後に Q が D に追従し、E=0 になると最後にラッチされた値を保持します。この「トランスペアレント(透明)」な性質は機能であり、故障ではありません。しかし、接続方法によってデータが同じトランスペアレントウィンドウ内で多段を通過できる場合、スルー(貫通)とラッチのタイミングを分析する必要があり、エッジトリガパイプラインルールをそのまま適用することはできません。
ポジエッジ D フリップフロップは、クロックの立ち上がりエッジでサンプリングし、その後 tCQ の遅延を経て Q が更新されます。それ以外の時間、非同期セット/リセットなどの制御が無効な間は状態を保持します。デバイスにはネガティブエッジモデルもあります。データシート内のクロック記号、反転泡、および機能表によって具体的な動作が決定されます。TI:SN74HC74 ポジエッジ D フリップフロップ
−tsetup +thold CLK D Q tCQ 図示のサンプリング値は 1 サンプリングは瞬間的な魔法ではない:D はサンプリングウィンドウをカバーする 必要があり、その後 Q が更新される ウィンドウは正のセットアップ/ホールド時間の模式図であり、パラメータは対応するデバイス、電源電圧、温度を参照す ること。図中の幅は比例を表すものではない。
セットアップ時間は、D がサンプリングエッジの前に安定していることを要求し、ホールド時間はエッジの後に引き続き安定していることを要求します。これらの要件に違反すると、結果は通常のタイミング保証が得られなくなります。古い値や新しい値をキャプチャする可能性があり、メタステーブル状態に陥る可能性もあります。違反のたびに必ずメタステーブルが発生するとは限らず、メタステーブルを必然的な振動として定義することもできません。出力が利用可能な論理レベルに達するまで遅延したり、後続の異なる受信ユニットが異なる判断を下したりすることがあります。
JK フリップフロップは、有効エッジに基づいて J/K によって保持、セット、リセット、またはトグルを実行します。J=K=1 の場合、トグルします。T フリップフロップの更新式は Q_next=Q⊕T であり、D フリップフロップに XOR 論理を追加することで実現できます。ここで言う「1回トグルする」ことは、具体的なトリガ構造とタイミングに依存しており、エッジトリガの結論を任意のトランスペアレントフィードバック回路に直接適用することはできません。
レジスタとカウンター:各サイクルで古い状態を使用する
n 個のフリップフロップがクロックを共有することで、n ビットレジスタを構成します。イネーブル付きレジスタは、en=1 のときに新しいデータを読み込み、それ以外は保持します。データセレクタを使用して保持を実現するのが一般的であり、en をクロックと AND 演算するよりも制約が正しく設定しやすいです。本物のクロックゲート制御には、グリッチフリーゲート構造またはデバイス専用リソースが必要です。
同期バイナリカウンターは、en ? Q+1 : Q と記述でき、ビット幅がモジュラス数を決定します。同期とは、すべてのビットが同じクロックでサンプリングされることを意味しますが、すべての Q の物理的な変化が絶対的に同時であることを意味するわけではありません。リップルカウンターは、前の段の出力で次の段のクロックを駆動するため、段ごとの遅延があり、デコード時に中間コードをより目に見えて確認できます。
BCD(Binary-Coded Decimal)の1桁の10進数は、4ビットの符号 0000~1001 を使用します。3ビットのバイナリ増分シーケンスは BCD ではありません。モジュロ 10 カウンターでは、不正な状態 1010~1111 の動作を規定する必要があります。例えば、次のサイクルで 0000 に戻すなどです。Gray コードでは、隣接する有効なカウントは1ビットのみ変化しますが、それでも正しいレジスタ化、同期、および配線制約が必要であり、「1ビットのみ変化する」という事実だけで、ドメイン間が絶対的に安全であると結論付けることはできません。
シフトレジスタは、古い隣接ビットを同時にサンプリングします。4ビットレジスタの右端にシリアル bit が入力される例では、Q_next=((Q<<1)|bit)&0xF となります。1、0、1、1 を順に入力すると、状態は 0001、0010、0101、1011 となります。パラレル出力は、各サイクルで全体が更新されるものであり、ソフトウェアのループでビットごとに更新される連鎖結果ではありません。
// 同期アクティブハイリセット;reset と en はどちらも clk クロックドメインに属する。
always_ff @(posedge clk) begin
if (reset)
q <= '0;
else if (en)
q <= {q[2:0], serial_in};
end
非ブロッキング代入は、エッジにおいて古い値に基づいて計算し、レジスタを更新することを記述します。ここで言う serial_in も、このクロックドメインのサンプリング要件を満たす必要があります。always_ff を使用しただけでは、非同期入力が自動的に同期されるわけではありません。
セットアップとホールド:上限を制限するものと下限を制限するもの
送信クロックエッジが 0 で到達し、受信クロックの対応するエッジが s 遅れて到達すると仮定します。s>0 は、受信クロックが遅れていることを示します。単一サイクル、ポジエッジからポジエッジへのパスにおいて、別途列挙されているジッタや不確実性を無視すると:
チェック 簡略化された制約 物理的な意味
セットアップ tCQ,max+tcomb,max+tsetup ≤ T+s 前のサイクルで送信されたデータが、次の受信エッジに間に合う必要がある
ホールド tCQ,min+tcomb,min ≥ s+thold 新しいデータが、今回のサンプリング値を早期に消去してはならない
受信クロックが遅れると、セットアップチェックにはより多くの時間が与えられますが、ホールドの満たしにくさが増します。実際のツールでは、異なるエッジ、クロックパス、プロセスコーナーを区別し、対応する不確実性を計上します。典型値の遅延で最悪条件の分析を代替することはできません。MIT:タイミング論理と制約
教学例として、T=10 ns、s=0.5 ns、tCQ,max=1 ns、tcomb,max=7 ns、tsetup=1 ns を取ると、セットアップマージンは 10+0.5−1−7−1=1.5 ns です。最速パスが tCQ,min=0.2 ns、tcomb,min=0.1 ns、thold=0.2 ns の場合、ホールドマージンは 0.2+0.1−0.5−0.2=−0.4 ns となり、依然として失敗します。
周期を 10 ns から 20 ns に増やすと、セットアップは改善されますが、この同エッジのホールド制約は変化しません。ホールドの修正通常、最短パス遅延、クロックスキュー、および配置配置に関与します。すべてのデータパス遅延を盲目的に増やすと、セットアップを壊す可能性があります。パイプライン化は、各セグメントの最長組合せパスを短縮できますが、処理遅延のサイクル数が増加するため、各セグメントのホールドと制御の整列を再確認する必要があります。
低速化してもホールドが直らない理由は?
既定はsetup+1.5 ns、hold−0.4 ns。周期を20 nsにしてもhold境界は動かない。データ遅延を加えると最早・最遅の両方が遅れるため、両条件を再確認する。
図を準備しています 再読み込み
低速化してもホールドが直らない理由は? セットアップは次の受信エッジ、ホールドは現在のエッジを見る。周期増加は次のエッジだけを遅らせ、正のスキューはsetupを改善するがholdを悪化させる。
{"id":"setup-hold-independent","title":"低速化してもホールドが直らない理由は?","summary":"セットアップは次の受信エッジ、ホールドは現在のエッジを見る。周期増加は次のエッジだけを遅らせ、正のスキューはsetupを改善するがholdを悪化させる。","height":1000,"html":"<h2 data-i18n=\"heading\"></h2><p class=\"intro\" data-i18n=\"intro\"></p><div class=\"control\"><label for=\"period\" data-i18n=\"period\"></label><output for=\"period\" id=\"period-value\"></output><input id=\"period\" type=\"range\" min=\"5\" max=\"20\" value=\"10\" step=\"0.5\"></div><div class=\"control\"><label for=\"skew\" data-i18n=\"skew\"></label><output for=\"skew\" id=\"skew-value\"></output><input id=\"skew\" type=\"range\" min=\"-1\" max=\"2\" value=\"0.5\" step=\"0.1\"></div><div class=\"control\"><label for=\"delay\" data-i18n=\"delay\"></label><output for=\"delay\" id=\"delay-value\"></output><input id=\"delay\" type=\"range\" min=\"0\" max=\"4\" value=\"0\" step=\"0.1\"></div><div class=\"chart-wrap\"><div class=\"chart-label\" data-i18n=\"timeline\"></div><svg id=\"timeline\" class=\"curve\" viewBox=\"0 0 360 210\" role=\"img\" data-i18n-label=\"timeline\"></svg></div><div class=\"metrics\"><div><span data-i18n=\"setup\"></span><strong id=\"setup\"></strong></div><div><span data-i18n=\"hold\"></span><strong id=\"hold\"></strong></div></div><p id=\"eq\" class=\"formula\"></p><details class=\"scope\"><summary data-i18n=\"scopeLabel\"></summary><p data-i18n=\"scope\"></p></details>","css":".intro{margin:8px 0 18px;color:var(--muted);font-size:14px}.caption,.hint{font-size:12px;color:var(--muted);margin-top:12px}.control{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px 12px;align-items:center;margin:14px 0;font-size:13px}.control label{font-size:13px}.control output{color:var(--accent);min-width:5em;text-align:right;font-variant-numeric:tabular-nums}.control input{grid-column:1/-1;width:100%;margin:0}.presets{display:flex;gap:4px;align-items:stretch}.presets button{flex:1 1 0;min-width:0;overflow-wrap:anywhere;font-size:13px}.actions{display:flex;gap:8px;flex-wrap:wrap;margin:14px 0}.actions button{flex:1;min-width:0;font-size:13px;min-height:42px}.copy{display:grid;font-size:14px;margin:16px 0}.copy>*{grid-area:1/1;margin:0}.reserve{visibility:hidden}.scope{margin-top:14px;color:var(--muted);font-size:12px}.scope summary{padding:8px 0;cursor:pointer}.scope p{margin-top:10px}.two{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin:16px 0}.card{border:1px solid var(--rule);border-radius:9px;padding:14px;min-width:0}.card header{font-size:14px;font-weight:600;margin-bottom:10px}.card button{font-size:12px;width:100%;min-width:0}.card small{display:block;font-size:12px;color:var(--muted)}.card code{font-size:12px;overflow-wrap:anywhere}.metrics{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin:16px 0}.metrics>div{border-left:2px solid var(--accent);padding-left:10px;min-width:0}.metrics span{display:block;min-height:3.2em;color:var(--muted);font-size:12px}.metrics strong{font-size:23px;display:block;font-weight:550;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}.formula{border-top:1px solid var(--rule);padding-top:12px;margin-top:14px;font-size:13px;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}.value{font:550 20px ui-monospace,monospace}.legend{display:flex;flex-wrap:wrap;gap:6px 14px;font-size:12px;color:var(--muted);margin:12px 0}.legend span:before{content:'';display:inline-block;width:8px;height:8px;border-radius:2px;background:var(--accent);margin-right:6px}.legend .second:before{background:var(--second)}.check{display:flex;align-items:center;gap:8px;font-size:13px;margin:12px 0}.check input{width:16px;height:16px;flex-shrink:0;accent-color:var(--accent)}select,input[type=text],input[type=number]{background:var(--paper);color:var(--ink);font:inherit;font-size:13px;padding:10px;border:1px solid var(--rule);border-radius:7px;max-width:100%;min-width:0}select{width:100%;min-height:42px}.band{height:20px;display:flex;background:var(--surface);border-radius:4px;overflow:hidden}.band i{height:100%;display:block;background:var(--accent);transition:width .25s}.band i.second{background:var(--second)}button:disabled{cursor:default}.status{font-size:13px;min-height:4.8em}.mono{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums}.muted{color:var(--muted)}\n@media(max-width:480px){.two{gap:8px}.card{padding:12px 9px}.actions button,.presets button{font-size:12px}.metrics strong{font-size:20px}.metrics{gap:8px}}\n@media(prefers-reduced-motion:reduce){*,*::before,*::after{transition:none!important;animation:none!important}}\n.track-row{margin:16px 0}.track-row>span{display:block;font-size:12px;color:var(--muted);margin-bottom:7px}.track{display:flex;gap:5px;min-width:0}.cell{flex:1;min-width:0;min-height:48px;border:1px solid var(--rule);border-radius:5px;background:var(--surface);display:flex;align-items:center;justify-content:center;text-align:center;padding:5px 3px;font-size:12px;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}.cell.on{background:var(--accent-soft);border-color:var(--accent)}.cell.gold{background:var(--second-soft);border-color:var(--second)}.cell.empty{border-style:dashed;color:var(--muted)}.cell.error{border-color:var(--second);text-decoration:line-through}.choices{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px;margin:14px 0}.choices button{min-width:0;padding:10px 4px;font-size:12px;overflow-wrap:anywhere}.choices button[aria-current=true]{border-color:var(--accent);background:var(--accent-soft)}.relation{display:grid;grid-template-columns:minmax(0,1fr) 28px minmax(0,1fr);align-items:center;gap:6px;margin:12px 0}.relation .cell{min-height:72px}.relation>i{text-align:center;font-style:normal;color:var(--accent)}.readout{font-size:13px;white-space:pre-line;min-height:6.4em;overflow-wrap:anywhere}.plot{position:relative;border-left:1px solid var(--rule);border-bottom:1px solid var(--rule);padding:8px 0;margin:18px 0}.plot-row{height:28px;position:relative;margin:4px 0;background:var(--surface)}.plot-row i{position:absolute;inset-block:5px;background:var(--accent);min-width:2px;transition:width .2s,left .2s}.plot-row b{position:relative;padding:4px 6px;font:11px/28px ui-monospace,monospace;background:var(--paper);border-radius:3px}.axis{display:flex;justify-content:space-between;font-size:11px;color:var(--muted)}\n\n/* Action labels must remain readable across locales and narrow embeds. */\n.actions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}\n.actions button{overflow-wrap:anywhere;white-space:normal;min-height:58px;padding:8px}\nbutton{overflow-wrap:anywhere}\n@media(min-width:640px){.actions{grid-template-columns:repeat(3,minmax(0,1fr))}}\n\n.metrics span{overflow-wrap:anywhere}\n.panel{border:1px solid var(--rule);border-radius:9px;padding:12px;margin:14px 0;min-width:0}.panel h3{font-size:13px;margin:0 0 10px;color:var(--muted)}.source{font:13px/1.8 ui-monospace,monospace;white-space:pre-wrap;overflow-wrap:anywhere;margin:12px 0}.source mark{background:var(--accent-soft);color:var(--ink);border-bottom:2px solid var(--accent)}.source .fault{background:var(--second-soft);border-color:var(--second)}.diagram{display:block;width:100%;height:auto;max-height:320px;margin:14px 0;overflow:visible}.diagram text{fill:var(--ink);font:12px ui-monospace,monospace}.diagram .edge{stroke:var(--muted);stroke-width:1.5;fill:none}.diagram .edge.on{stroke:var(--accent);stroke-width:3}.diagram .node{fill:var(--surface);stroke:var(--rule);stroke-width:1.5}.diagram .node.on{fill:var(--accent-soft);stroke:var(--accent)}.diagram .node.gold{fill:var(--second-soft);stroke:var(--second)}.log{font:12px/1.8 ui-monospace,monospace;white-space:pre-line;overflow-wrap:anywhere;min-height:7.2em}.table{display:grid;gap:5px;margin:14px 0}.table .tr{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:5px}.table .tr>*{padding:8px 5px;background:var(--surface);border-radius:4px;min-width:0;overflow-wrap:anywhere;font-size:12px}.table .tr .on{background:var(--accent-soft)}.table .tr .gold{background:var(--second-soft)}.choices button{min-height:44px}.metrics strong{min-height:1.6em}.code-line{display:block}.code-line.on{background:var(--accent-soft);border-left:2px solid var(--accent);padding-left:6px}.status-badge{font-size:12px;color:var(--accent)}.tile-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px}.tile-grid .cell{min-height:40px}.actions button{min-height:48px}.form-field{display:grid;gap:8px;margin:14px 0;font-size:13px}.form-field input{width:100%;font-family:ui-monospace,monospace}.metrics.three{grid-template-columns:repeat(3,minmax(0,1fr))}.formula{min-height:3.2em}.presets{flex-wrap:wrap}.presets button{flex-basis:25%;min-height:44px}\n\n.budget{display:flex;height:28px;margin:16px 0;background:var(--surface);border-radius:5px;overflow:hidden}.budget i{display:block;background:var(--accent);transition:width .2s}.budget i.gold{background:var(--second)}.intervals{margin:16px 0}.interval{position:relative;height:36px;background:var(--surface);margin:6px 0;border-radius:4px;overflow:hidden}.interval i{position:absolute;height:100%;background:var(--accent-soft);border-left:2px solid var(--accent)}.interval i.gold{background:var(--second-soft);border-color:var(--second)}.interval span{position:relative;z-index:1;font:12px/36px ui-monospace,monospace;padding-left:7px}.table .tr>*{min-height:4.8em}.formula{white-space:pre-line;min-height:7.2em}.actions:has(>button:only-child){grid-template-columns:1fr}.metrics strong{min-height:3.2em}.rangegrid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:3px;margin:14px 0}.rangegrid .cell{min-height:30px;padding:3px 1px;font-size:10px}.message{min-height:7.2em;white-space:pre-line;font:13px/1.8 ui-monospace,monospace;overflow-wrap:anywhere}\n/* Allow CJK hanging punctuation without overflowing a metric's border box. */\n.metrics>div{padding-right:4px}.metrics span{line-break:anywhere}\n\n.chart-wrap{margin:18px 0}.chart-label{font-size:12px;color:var(--muted);min-height:3.2em}.curve{display:block;width:100%;height:auto;max-height:320px;overflow:visible}.curve text{font:11px ui-monospace,monospace;fill:var(--muted)}.gridline{stroke:var(--rule);stroke-width:1}.metrics strong{font-size:20px;min-height:3.2em}.formula{font:12px/1.8 ui-monospace,monospace;min-height:9em}.readout{min-height:8em}.presets button{flex-basis:30%}.scope p{overflow-wrap:anywhere} .unit-note{font-size:12px;color:var(--muted);margin:10px 0}\n\n.metrics span{word-break:break-all;line-break:strict}.metrics>div{padding-right:6px}\n\n","js":"const $=s=>document.querySelector(s);const set=(id,v)=>$('#'+id).textContent=v;const t=k=>viz.t(k);function cells(id,values){$('#'+id).replaceChildren(...values.map(v=>{const e=document.createElement('div');e.className='cell '+(v.cls||'');e.textContent=v.text;e.title=v.title||v.text;return e;}));}function pressed(mode){document.querySelectorAll('[data-mode]').forEach(e=>e.setAttribute('aria-pressed',String(e.dataset.mode===mode)));}const esc=s=>String(s).replace(/[&<>\"']/g,c=>({'&':'&','<':'<','>':'>','\"':'"',\"'\":'''}[c]));const fmt=s=>'{'+[...s].sort().join(', ')+'}';function graph(id,nodes,edges){const el=$('#'+id);el.setAttribute('viewBox','0 0 360 200');el.innerHTML='<defs><marker id=\"arrow-'+id+'\" viewBox=\"0 0 10 10\" refX=\"8\" refY=\"5\" markerWidth=\"5\" markerHeight=\"5\" orient=\"auto-start-reverse\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"var(--muted)\"/></marker></defs>'+edges.map(e=>{const a=nodes[e[0]],b=nodes[e[1]],dx=b.x-a.x,dy=b.y-a.y,d=Math.hypot(dx,dy)||1;if(edges.some(r=>r[0]===e[1]&&r[1]===e[0])){const nx=-dy/d,ny=dx/d;return '<path class=\"edge '+(e[2]?'on':'')+'\" d=\"M '+(a.x+dx/d*22+nx*12)+' '+(a.y+dy/d*22+ny*12)+' Q '+((a.x+b.x)/2+nx*38)+' '+((a.y+b.y)/2+ny*38)+' '+(b.x-dx/d*25+nx*12)+' '+(b.y-dy/d*25+ny*12)+'\" marker-end=\"url(#arrow-'+id+')\"/>';}return '<line class=\"edge '+(e[2]?'on':'')+'\" x1=\"'+(a.x+dx/d*25)+'\" y1=\"'+(a.y+dy/d*25)+'\" x2=\"'+(b.x-dx/d*28)+'\" y2=\"'+(b.y-dy/d*28)+'\" marker-end=\"url(#arrow-'+id+')\"/>';}).join('')+nodes.map(n=>'<g><circle class=\"node '+(n.cls||'')+'\" cx=\"'+n.x+'\" cy=\"'+n.y+'\" r=\"25\"/><text x=\"'+n.x+'\" y=\"'+(n.y+4)+'\" text-anchor=\"middle\">'+esc(n.name)+'</text>'+(n.sub?'<text x=\"'+n.x+'\" y=\"'+(n.y+43)+'\" text-anchor=\"middle\">'+esc(n.sub)+'</text>':'')+'</g>').join('');}function table(id,rows){$('#'+id).classList.add('table');$('#'+id).replaceChildren(...rows.map(r=>{const row=document.createElement('div');row.className='tr';row.style.gridTemplateColumns='repeat('+r.length+',minmax(0,1fr))';r.forEach(x=>{const c=document.createElement('div');if(typeof x==='object'){c.textContent=x.text;c.className=x.cls||'';}else c.textContent=x;row.append(c)});return row;}));}function band(id,parts,total){$('#'+id).replaceChildren(...parts.map((p,i)=>{const e=document.createElement('i');e.style.width=(100*p.value/total)+'%';e.className=i%2?'gold':'on';e.title=p.name+': '+p.value;return e}));}function intervals(id,items,total){$('#'+id).replaceChildren(...items.map(p=>{const row=document.createElement('div');row.className='interval';const bar=document.createElement('i');bar.style.left=(100*p.start/total)+'%';bar.style.width=(100*(p.end-p.start)/total)+'%';bar.className=p.cls||'';const label=document.createElement('span');label.textContent=p.label;row.append(bar,label);return row;}));}function plot(id,series,xr,yr,opts={}){const e=$('#'+id),X=x=>42+(x-xr[0])/(xr[1]-xr[0])*298,Y=y=>175-(y-yr[0])/(yr[1]-yr[0])*148;let out='<defs><clipPath id=\"clip-'+id+'\"><rect x=\"42\" y=\"27\" width=\"298\" height=\"148\"/></clipPath></defs>';for(let i=0;i<3;i++){let x=xr[0]+i*(xr[1]-xr[0])/2,y=yr[0]+i*(yr[1]-yr[0])/2;out+='<path class=\"gridline\" d=\"M '+X(x)+' 27V175M42 '+Y(y)+'H340\"/><text x=\"'+X(x)+'\" y=\"194\" text-anchor=\"middle\">'+esc(opts.xfmt?opts.xfmt(x):Number(x.toFixed(2)))+'</text><text x=\"36\" y=\"'+(Y(y)+4)+'\" text-anchor=\"end\">'+esc(opts.yfmt?opts.yfmt(y):Number(y.toFixed(2)))+'</text>';}out+='<g clip-path=\"url(#clip-'+id+')\">';for(const s of series){out+='<path fill=\"none\" stroke=\"'+(s.color||'var(--accent)')+'\" stroke-width=\"2.5\" '+(s.dash?'stroke-dasharray=\"5 4\"':'')+' d=\"'+s.pts.map((p,i)=>(i?'L':'M')+X(p[0]).toFixed(2)+','+Y(p[1]).toFixed(2)).join(' ')+'\"/>';}for(const p of opts.points||[])out+='<circle cx=\"'+X(p[0])+'\" cy=\"'+Y(p[1])+'\" r=\"4\" fill=\"var(--second)\" stroke=\"var(--paper)\" stroke-width=\"1.5\"/>';if(opts.cursor!==undefined)out+='<path d=\"M'+X(opts.cursor)+' 27V175\" stroke=\"var(--muted)\" stroke-dasharray=\"3 3\"/>';e.innerHTML=out+'</g>';e.dataset.curves=JSON.stringify(series.map(s=>s.pts));}const curve=(fn,lo,hi,n=120)=>Array.from({length:n+1},(_,i)=>{const x=lo+(hi-lo)*i/n;return[x,fn(x)]});function inputs(draw){document.querySelectorAll('input,select').forEach(e=>{e.addEventListener('input',draw);e.addEventListener('change',draw)});draw()}const n=id=>+$('#'+id).value;const show=(id,v,d=3)=>set(id,Number(v.toFixed(d)));function draw(){let T=n('period'),s=n('skew'),d=n('delay'),earliest=.3+d,latest=8+d,hs=s+.2,ss=T+s-1;['period','skew','delay'].forEach(k=>show(k+'-value',n(k)));plot('timeline',[{pts:[[earliest,.5],[latest,.5]]},{pts:[[hs,0],[hs,1]],color:'var(--second)'},{pts:[[ss,0],[ss,1]],color:'var(--second)'}],[-1,22],[0,1],{points:[[earliest,.5],[latest,.5]]});show('setup',ss-latest);show('hold',earliest-hs);set('eq','Setup = T + s − (8 + d) − 1 = '+(ss-latest).toFixed(2)+' ns\\nHold = 0.3 + d − s − 0.2 = '+(earliest-hs).toFixed(2)+' ns');$('#hold').dataset.pass=earliest>=hs;}inputs(draw);","audio":false,"strings":{"delay":"追加データ遅延(ns)","heading":"低速化してもホールドが直らない理由は?","hold":"ホールド余裕(ns)","intro":"周期、受信クロックスキュー、追加データ遅延を個別に変更。","period":"クロック周期(ns)","reset":"リセット","scope":"最早到着0.3 ns、最遅8 ns、setup=1 ns、hold=0.2 ns。追加遅延は両方へ加算。ジッターや複数コーナーなし。","scopeLabel":"モデルの範囲と前提","setup":"セットアップ余裕(ns)","skew":"受信スキュー s(ns)","timeline":"横軸 ns、青:データ到着範囲、金:hold終点とsetup期限"}}
FSM:シーケンス 101 で、なぜ状態がこのように設計されているかを説明する
同期 FSM は state_next=F(state,input) と記述されます。Moore 出力は G(state)、Mealy 出力は G(state,input) です。両者の違いは出力の依存関係にあり、「片方は常にグリッチがなく、もう片方は必ず高速である」という意味ではありません。Moore で複数ビットの状態組み合わせをデコードする場合、状態ビットの伝搬遅延が異なるため、グリッチが発生する可能性があります。出力をレジスタ化すると、このタイミング境界を変更できます。
重複を許可する 101 検出器を考えます。S0 は現在有用な接尾辞がないことを表し、S1 は 1 にマッチしたことを表し、S2 は 10 にマッチしたことを表します。S2 で 1 を受信すると、ヒットを報告して S1 に遷移します。なぜなら、直前に受信した 1 が次の 101 の先頭になる可能性があるからです。
S0 未マッチ S1 末尾が 1 S2 末尾が 10 1 / 0 0 / 0 1 / 1:ヒット 0 / 0 0 / 0 1 / 0 重複シーケンス 101 の検出:状態は「現在どこまでマッチしたか」を保存する 矢印は「入力 / Mealy 出力」を示す;入力はまずこのクロックドメインに同期され、状態は有効なクロックエッジで更新さ れる。
現在状態 入力 0:次状態 / 出力 入力 1:次状態 / 出力
S0 S0 / 0 S1 / 0
S1 S2 / 0 S1 / 0
S2 S0 / 0 S1 / 1
入力が 10101 の場合、3番目と5番目のビットでヒットする必要があります。ヒット後に直接 S0 に戻ると、重複する2回目のマッチを見逃してしまいます。これは「状態がどのような情報を保存するか」が機能に直接影響を与える例です。Mealy 出力は、現在の状態が S2 のままで入力が 1 に安定している間に、組合せ遅延を経てハイになります。外部インターフェースで1サイクル安定したパルスを要求する場合、明確なサンプリング境界でこの結果をレジスタ化し、対応する遅延を記録する必要があります。
状態エンコーディングはバイナリまたは one-hot のいずれかです。one-hot はより多くのフリップフロップを使用しますが、一部のデコードが単純になる可能性があります。ただし、消費電力、速度、および面積は対象デバイスに応じて判断する必要があります。組合せの次状態ブロックでは、すべての分岐をカバーする必要があります。不正な状態の回復方法を明確にし、回復戦略が正しい CDC や電源完全性を代替することはできません。
メタステーブルとシンクロナイザ:回復時間を増やすもので、確定遅延を保証するものではない
非同期入力は、ターゲットクロックに対してサンプリングウィンドウに落ちる可能性があり、通常の同期タイミング制約では解消できません。シンクロナイザは、まず第1段で受信し、回復時間を確保してから、ターゲットクロックの第2段でサンプリングします。ビジネスロジックは最終段の出力のみを使用します。段間に組合せ論理を挿入したり、ビジネス受信側に分岐させたりしてはいけません。配置配置や専用シンクロナイザ属性も、利用可能な回復時間に影響を与えます。
非同期レベル 十分に長く保持 第1段 DFF 準安定の可能性 第2段 DFF 受信側回路へ sync_out 同じターゲットクロック 段間に組合せ論理を挿入しない 短距離配線で回復に時間を確保 2段シンクロナイザ:第1段により多くの回復時間を提供し、ビジネスロジックは最 終段のみを使用する 失敗確率を低減するが、ゼロリスクを保証するものではない。短パルスがキャプチャされることを直接保証するものでは なく、複数ビットデータが自動的に整合するものでもない。
2段が一般的な出発点ですが、実際に必要な段数は、デバイス特性、ターゲットクロック、入力遷移周波数、および信頼性要件に応じて計算する必要があります。典型的なモデルは MTBF∝exp(Tresolve/τ)/(fclk·fdata) の傾向を示しますが、定数と τ はデバイス特性から取得する必要があります。任意の τ を使用して信頼寿命を計算することはできません。複数のドメイン間リンクの故障率は累積されるため、単一リンクの MTBF がシステム全体の保証になるわけではありません。Intel:メタステーブルとシンクロナイザの分析
同期結果は、非同期変化に対して異なる数のサイクル遅れる可能性があります。シンクロナイザはメタステーブルの伝播確率を低減しますが、すべての短パルスがサンプリングされることを保証するものではありません。例えば、ターゲットクロックが 20 ns ごとにサンプリングする場合、2回のサンプリングの間に完全に位置する 5 ns のパルスは消失します。これは受信フリップフロップがメタステーブルになっていない場合でも同様です。
メタステーブルなしでもイベントは消える
既定の5–10 nsパルスはエッジ間にあり四回とも0。20 nsを覆うよう移動するとHighを捉える。ここではメタステーブルを扱わず、理想サンプルでも短パルスを失い、段数追加では復元できないことを示す。
図を準備しています 再読み込み
メタステーブルなしでもイベントは消える 同期器は第1段が一度も捉えないパルスを復元できない。イベント保持には適切な符号化やハンドシェイクが必要。
{"id":"cdc-short-pulse-sampling","title":"メタステーブルなしでもイベントは消える","summary":"同期器は第1段が一度も捉えないパルスを復元できない。イベント保持には適切な符号化やハンドシェイクが必要。","height":1000,"html":"<h2 data-i18n=\"heading\"></h2><p class=\"intro\" data-i18n=\"intro\"></p><div class=\"control\"><label for=\"start\" data-i18n=\"start\"></label><output for=\"start\" id=\"start-value\"></output><input id=\"start\" type=\"range\" min=\"1\" max=\"39\" value=\"5\" step=\"0.5\"></div><div class=\"control\"><label for=\"width\" data-i18n=\"width\"></label><output for=\"width\" id=\"width-value\"></output><input id=\"width\" type=\"range\" min=\"1\" max=\"25\" value=\"5\" step=\"0.5\"></div><div class=\"chart-wrap\"><div class=\"chart-label\" data-i18n=\"plot\"></div><svg id=\"plot\" class=\"curve\" viewBox=\"0 0 360 210\" role=\"img\" data-i18n-label=\"plot\"></svg></div><div class=\"track-row\"><span data-i18n=\"samples\"></span><div id=\"samples\" class=\"track\"></div></div><div class=\"metrics\"><div><span data-i18n=\"count\"></span><strong id=\"count\"></strong></div></div><p id=\"eq\" class=\"formula\"></p><details class=\"scope\"><summary data-i18n=\"scopeLabel\"></summary><p data-i18n=\"scope\"></p></details>","css":".intro{margin:8px 0 18px;color:var(--muted);font-size:14px}.caption,.hint{font-size:12px;color:var(--muted);margin-top:12px}.control{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px 12px;align-items:center;margin:14px 0;font-size:13px}.control label{font-size:13px}.control output{color:var(--accent);min-width:5em;text-align:right;font-variant-numeric:tabular-nums}.control input{grid-column:1/-1;width:100%;margin:0}.presets{display:flex;gap:4px;align-items:stretch}.presets button{flex:1 1 0;min-width:0;overflow-wrap:anywhere;font-size:13px}.actions{display:flex;gap:8px;flex-wrap:wrap;margin:14px 0}.actions button{flex:1;min-width:0;font-size:13px;min-height:42px}.copy{display:grid;font-size:14px;margin:16px 0}.copy>*{grid-area:1/1;margin:0}.reserve{visibility:hidden}.scope{margin-top:14px;color:var(--muted);font-size:12px}.scope summary{padding:8px 0;cursor:pointer}.scope p{margin-top:10px}.two{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin:16px 0}.card{border:1px solid var(--rule);border-radius:9px;padding:14px;min-width:0}.card header{font-size:14px;font-weight:600;margin-bottom:10px}.card button{font-size:12px;width:100%;min-width:0}.card small{display:block;font-size:12px;color:var(--muted)}.card code{font-size:12px;overflow-wrap:anywhere}.metrics{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin:16px 0}.metrics>div{border-left:2px solid var(--accent);padding-left:10px;min-width:0}.metrics span{display:block;min-height:3.2em;color:var(--muted);font-size:12px}.metrics strong{font-size:23px;display:block;font-weight:550;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}.formula{border-top:1px solid var(--rule);padding-top:12px;margin-top:14px;font-size:13px;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}.value{font:550 20px ui-monospace,monospace}.legend{display:flex;flex-wrap:wrap;gap:6px 14px;font-size:12px;color:var(--muted);margin:12px 0}.legend span:before{content:'';display:inline-block;width:8px;height:8px;border-radius:2px;background:var(--accent);margin-right:6px}.legend .second:before{background:var(--second)}.check{display:flex;align-items:center;gap:8px;font-size:13px;margin:12px 0}.check input{width:16px;height:16px;flex-shrink:0;accent-color:var(--accent)}select,input[type=text],input[type=number]{background:var(--paper);color:var(--ink);font:inherit;font-size:13px;padding:10px;border:1px solid var(--rule);border-radius:7px;max-width:100%;min-width:0}select{width:100%;min-height:42px}.band{height:20px;display:flex;background:var(--surface);border-radius:4px;overflow:hidden}.band i{height:100%;display:block;background:var(--accent);transition:width .25s}.band i.second{background:var(--second)}button:disabled{cursor:default}.status{font-size:13px;min-height:4.8em}.mono{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums}.muted{color:var(--muted)}\n@media(max-width:480px){.two{gap:8px}.card{padding:12px 9px}.actions button,.presets button{font-size:12px}.metrics strong{font-size:20px}.metrics{gap:8px}}\n@media(prefers-reduced-motion:reduce){*,*::before,*::after{transition:none!important;animation:none!important}}\n.track-row{margin:16px 0}.track-row>span{display:block;font-size:12px;color:var(--muted);margin-bottom:7px}.track{display:flex;gap:5px;min-width:0}.cell{flex:1;min-width:0;min-height:48px;border:1px solid var(--rule);border-radius:5px;background:var(--surface);display:flex;align-items:center;justify-content:center;text-align:center;padding:5px 3px;font-size:12px;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}.cell.on{background:var(--accent-soft);border-color:var(--accent)}.cell.gold{background:var(--second-soft);border-color:var(--second)}.cell.empty{border-style:dashed;color:var(--muted)}.cell.error{border-color:var(--second);text-decoration:line-through}.choices{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px;margin:14px 0}.choices button{min-width:0;padding:10px 4px;font-size:12px;overflow-wrap:anywhere}.choices button[aria-current=true]{border-color:var(--accent);background:var(--accent-soft)}.relation{display:grid;grid-template-columns:minmax(0,1fr) 28px minmax(0,1fr);align-items:center;gap:6px;margin:12px 0}.relation .cell{min-height:72px}.relation>i{text-align:center;font-style:normal;color:var(--accent)}.readout{font-size:13px;white-space:pre-line;min-height:6.4em;overflow-wrap:anywhere}.plot{position:relative;border-left:1px solid var(--rule);border-bottom:1px solid var(--rule);padding:8px 0;margin:18px 0}.plot-row{height:28px;position:relative;margin:4px 0;background:var(--surface)}.plot-row i{position:absolute;inset-block:5px;background:var(--accent);min-width:2px;transition:width .2s,left .2s}.plot-row b{position:relative;padding:4px 6px;font:11px/28px ui-monospace,monospace;background:var(--paper);border-radius:3px}.axis{display:flex;justify-content:space-between;font-size:11px;color:var(--muted)}\n\n/* Action labels must remain readable across locales and narrow embeds. */\n.actions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}\n.actions button{overflow-wrap:anywhere;white-space:normal;min-height:58px;padding:8px}\nbutton{overflow-wrap:anywhere}\n@media(min-width:640px){.actions{grid-template-columns:repeat(3,minmax(0,1fr))}}\n\n.metrics span{overflow-wrap:anywhere}\n.panel{border:1px solid var(--rule);border-radius:9px;padding:12px;margin:14px 0;min-width:0}.panel h3{font-size:13px;margin:0 0 10px;color:var(--muted)}.source{font:13px/1.8 ui-monospace,monospace;white-space:pre-wrap;overflow-wrap:anywhere;margin:12px 0}.source mark{background:var(--accent-soft);color:var(--ink);border-bottom:2px solid var(--accent)}.source .fault{background:var(--second-soft);border-color:var(--second)}.diagram{display:block;width:100%;height:auto;max-height:320px;margin:14px 0;overflow:visible}.diagram text{fill:var(--ink);font:12px ui-monospace,monospace}.diagram .edge{stroke:var(--muted);stroke-width:1.5;fill:none}.diagram .edge.on{stroke:var(--accent);stroke-width:3}.diagram .node{fill:var(--surface);stroke:var(--rule);stroke-width:1.5}.diagram .node.on{fill:var(--accent-soft);stroke:var(--accent)}.diagram .node.gold{fill:var(--second-soft);stroke:var(--second)}.log{font:12px/1.8 ui-monospace,monospace;white-space:pre-line;overflow-wrap:anywhere;min-height:7.2em}.table{display:grid;gap:5px;margin:14px 0}.table .tr{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:5px}.table .tr>*{padding:8px 5px;background:var(--surface);border-radius:4px;min-width:0;overflow-wrap:anywhere;font-size:12px}.table .tr .on{background:var(--accent-soft)}.table .tr .gold{background:var(--second-soft)}.choices button{min-height:44px}.metrics strong{min-height:1.6em}.code-line{display:block}.code-line.on{background:var(--accent-soft);border-left:2px solid var(--accent);padding-left:6px}.status-badge{font-size:12px;color:var(--accent)}.tile-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px}.tile-grid .cell{min-height:40px}.actions button{min-height:48px}.form-field{display:grid;gap:8px;margin:14px 0;font-size:13px}.form-field input{width:100%;font-family:ui-monospace,monospace}.metrics.three{grid-template-columns:repeat(3,minmax(0,1fr))}.formula{min-height:3.2em}.presets{flex-wrap:wrap}.presets button{flex-basis:25%;min-height:44px}\n\n.budget{display:flex;height:28px;margin:16px 0;background:var(--surface);border-radius:5px;overflow:hidden}.budget i{display:block;background:var(--accent);transition:width .2s}.budget i.gold{background:var(--second)}.intervals{margin:16px 0}.interval{position:relative;height:36px;background:var(--surface);margin:6px 0;border-radius:4px;overflow:hidden}.interval i{position:absolute;height:100%;background:var(--accent-soft);border-left:2px solid var(--accent)}.interval i.gold{background:var(--second-soft);border-color:var(--second)}.interval span{position:relative;z-index:1;font:12px/36px ui-monospace,monospace;padding-left:7px}.table .tr>*{min-height:4.8em}.formula{white-space:pre-line;min-height:7.2em}.actions:has(>button:only-child){grid-template-columns:1fr}.metrics strong{min-height:3.2em}.rangegrid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:3px;margin:14px 0}.rangegrid .cell{min-height:30px;padding:3px 1px;font-size:10px}.message{min-height:7.2em;white-space:pre-line;font:13px/1.8 ui-monospace,monospace;overflow-wrap:anywhere}\n/* Allow CJK hanging punctuation without overflowing a metric's border box. */\n.metrics>div{padding-right:4px}.metrics span{line-break:anywhere}\n\n.chart-wrap{margin:18px 0}.chart-label{font-size:12px;color:var(--muted);min-height:3.2em}.curve{display:block;width:100%;height:auto;max-height:320px;overflow:visible}.curve text{font:11px ui-monospace,monospace;fill:var(--muted)}.gridline{stroke:var(--rule);stroke-width:1}.metrics strong{font-size:20px;min-height:3.2em}.formula{font:12px/1.8 ui-monospace,monospace;min-height:9em}.readout{min-height:8em}.presets button{flex-basis:30%}.scope p{overflow-wrap:anywhere} .unit-note{font-size:12px;color:var(--muted);margin:10px 0}\n\n.metrics span{word-break:break-all;line-break:strict}.metrics>div{padding-right:6px}\n\n","js":"const $=s=>document.querySelector(s);const set=(id,v)=>$('#'+id).textContent=v;const t=k=>viz.t(k);function cells(id,values){$('#'+id).replaceChildren(...values.map(v=>{const e=document.createElement('div');e.className='cell '+(v.cls||'');e.textContent=v.text;e.title=v.title||v.text;return e;}));}function pressed(mode){document.querySelectorAll('[data-mode]').forEach(e=>e.setAttribute('aria-pressed',String(e.dataset.mode===mode)));}const esc=s=>String(s).replace(/[&<>\"']/g,c=>({'&':'&','<':'<','>':'>','\"':'"',\"'\":'''}[c]));const fmt=s=>'{'+[...s].sort().join(', ')+'}';function graph(id,nodes,edges){const el=$('#'+id);el.setAttribute('viewBox','0 0 360 200');el.innerHTML='<defs><marker id=\"arrow-'+id+'\" viewBox=\"0 0 10 10\" refX=\"8\" refY=\"5\" markerWidth=\"5\" markerHeight=\"5\" orient=\"auto-start-reverse\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"var(--muted)\"/></marker></defs>'+edges.map(e=>{const a=nodes[e[0]],b=nodes[e[1]],dx=b.x-a.x,dy=b.y-a.y,d=Math.hypot(dx,dy)||1;if(edges.some(r=>r[0]===e[1]&&r[1]===e[0])){const nx=-dy/d,ny=dx/d;return '<path class=\"edge '+(e[2]?'on':'')+'\" d=\"M '+(a.x+dx/d*22+nx*12)+' '+(a.y+dy/d*22+ny*12)+' Q '+((a.x+b.x)/2+nx*38)+' '+((a.y+b.y)/2+ny*38)+' '+(b.x-dx/d*25+nx*12)+' '+(b.y-dy/d*25+ny*12)+'\" marker-end=\"url(#arrow-'+id+')\"/>';}return '<line class=\"edge '+(e[2]?'on':'')+'\" x1=\"'+(a.x+dx/d*25)+'\" y1=\"'+(a.y+dy/d*25)+'\" x2=\"'+(b.x-dx/d*28)+'\" y2=\"'+(b.y-dy/d*28)+'\" marker-end=\"url(#arrow-'+id+')\"/>';}).join('')+nodes.map(n=>'<g><circle class=\"node '+(n.cls||'')+'\" cx=\"'+n.x+'\" cy=\"'+n.y+'\" r=\"25\"/><text x=\"'+n.x+'\" y=\"'+(n.y+4)+'\" text-anchor=\"middle\">'+esc(n.name)+'</text>'+(n.sub?'<text x=\"'+n.x+'\" y=\"'+(n.y+43)+'\" text-anchor=\"middle\">'+esc(n.sub)+'</text>':'')+'</g>').join('');}function table(id,rows){$('#'+id).classList.add('table');$('#'+id).replaceChildren(...rows.map(r=>{const row=document.createElement('div');row.className='tr';row.style.gridTemplateColumns='repeat('+r.length+',minmax(0,1fr))';r.forEach(x=>{const c=document.createElement('div');if(typeof x==='object'){c.textContent=x.text;c.className=x.cls||'';}else c.textContent=x;row.append(c)});return row;}));}function band(id,parts,total){$('#'+id).replaceChildren(...parts.map((p,i)=>{const e=document.createElement('i');e.style.width=(100*p.value/total)+'%';e.className=i%2?'gold':'on';e.title=p.name+': '+p.value;return e}));}function intervals(id,items,total){$('#'+id).replaceChildren(...items.map(p=>{const row=document.createElement('div');row.className='interval';const bar=document.createElement('i');bar.style.left=(100*p.start/total)+'%';bar.style.width=(100*(p.end-p.start)/total)+'%';bar.className=p.cls||'';const label=document.createElement('span');label.textContent=p.label;row.append(bar,label);return row;}));}function plot(id,series,xr,yr,opts={}){const e=$('#'+id),X=x=>42+(x-xr[0])/(xr[1]-xr[0])*298,Y=y=>175-(y-yr[0])/(yr[1]-yr[0])*148;let out='<defs><clipPath id=\"clip-'+id+'\"><rect x=\"42\" y=\"27\" width=\"298\" height=\"148\"/></clipPath></defs>';for(let i=0;i<3;i++){let x=xr[0]+i*(xr[1]-xr[0])/2,y=yr[0]+i*(yr[1]-yr[0])/2;out+='<path class=\"gridline\" d=\"M '+X(x)+' 27V175M42 '+Y(y)+'H340\"/><text x=\"'+X(x)+'\" y=\"194\" text-anchor=\"middle\">'+esc(opts.xfmt?opts.xfmt(x):Number(x.toFixed(2)))+'</text><text x=\"36\" y=\"'+(Y(y)+4)+'\" text-anchor=\"end\">'+esc(opts.yfmt?opts.yfmt(y):Number(y.toFixed(2)))+'</text>';}out+='<g clip-path=\"url(#clip-'+id+')\">';for(const s of series){out+='<path fill=\"none\" stroke=\"'+(s.color||'var(--accent)')+'\" stroke-width=\"2.5\" '+(s.dash?'stroke-dasharray=\"5 4\"':'')+' d=\"'+s.pts.map((p,i)=>(i?'L':'M')+X(p[0]).toFixed(2)+','+Y(p[1]).toFixed(2)).join(' ')+'\"/>';}for(const p of opts.points||[])out+='<circle cx=\"'+X(p[0])+'\" cy=\"'+Y(p[1])+'\" r=\"4\" fill=\"var(--second)\" stroke=\"var(--paper)\" stroke-width=\"1.5\"/>';if(opts.cursor!==undefined)out+='<path d=\"M'+X(opts.cursor)+' 27V175\" stroke=\"var(--muted)\" stroke-dasharray=\"3 3\"/>';e.innerHTML=out+'</g>';e.dataset.curves=JSON.stringify(series.map(s=>s.pts));}const curve=(fn,lo,hi,n=120)=>Array.from({length:n+1},(_,i)=>{const x=lo+(hi-lo)*i/n;return[x,fn(x)]});function inputs(draw){document.querySelectorAll('input,select').forEach(e=>{e.addEventListener('input',draw);e.addEventListener('change',draw)});draw()}const n=id=>+$('#'+id).value;const show=(id,v,d=3)=>set(id,Number(v.toFixed(d)));function draw(){let s=n('start'),w=n('width'),edges=[0,20,40,60],bits=edges.map(t=>+(t>=s&&t<s+w));show('start-value',s);show('width-value',w);plot('plot',[{pts:[[0,0],[s,0],[s,1],[s+w,1],[s+w,0],[65,0]]}],[0,65],[-.1,1.1],{points:edges.map((t,i)=>[t,bits[i]])});cells('samples',bits.map(x=>({text:String(x),cls:x?'on':''})));show('count',bits.reduce((a,b)=>a+b));set('eq','input = 1 for ['+s+', '+(s+w)+') ns\\nsample[k] = input(20k ns)\\n'+bits.join(' → '));}inputs(draw);","audio":false,"strings":{"count":"Highのサンプル数","heading":"メタステーブルなしでもイベントは消える","intro":"非同期パルスの位置と幅を変え、サンプルエッジが捉えるか確認。","plot":"横軸 ns、青:入力、金点:第1段サンプル","reset":"リセット","samples":"0 / 20 / 40 / 60 ns のサンプル","scope":"受信エッジ0,20,40,60 ns。High区間は左閉右開。理想点サンプルのみで実setup/hold窓付近は保証しない。","scopeLabel":"モデルの範囲と前提","start":"パルス開始(ns)","width":"パルス幅(ns)"}}
CDC では、伝送されるのがレベル、イベント、データかをまず確定させる
伝送対象 一般的な手法 依然として保証すべき条件
長時間保持される単一ビットの状態 ターゲットドメイン同期チェーン レベルに十分な可視時間があり、サンプリング遅延を許容する
毎回保持する必要があるイベント リクエスト/アキュー、またはレート制約付きのトグル 前のイベントが観察される前に上書きできない;リセット状態が一致している
整合性が必須のデータセット ハンドシェイク固定データ、または非同期 FIFO データが受信完了まで保持される、スループットとバックプレッシャーが明確
単調に隣接変化を行うポインタ Gray ポインタをレジスタ化してドメイン間伝送 ビット間スキュー/最大遅延制約、同期チェーン、正しい満空判定
複数ビットデータの場合、各ビットを2回サンプリングしても、旧ワードでも新ワードでもない混合値が得られる可能性があります。例えば、バイナリ 0111→1000 の場合、4ビットすべてが変化するため、受信側は任意の組み合わせを見る可能性があります。ハンドシェイク方式では、送信側がまずデータを安定させ、次に受信側を通知します。通知がドメイン間を跨いだ後、受信側がサンプリングし、確認が戻る前に送信側はデータを保持し、制御とデータの相対的な到達時間を制約します。非同期 FIFO は、データストレージと読み書きドメインのポインタ管理を分離し、継続的なフローに適しています。
Gray コードも汎用の複数ビット同期手法ではありません。任意の2つの Gray 符号の間でも、複数ビットが異なる可能性があります。ソース側で隣接カウントに従って進み、出力がレジスタ化され、ドメイン間パスの制約が正しい場合にのみ、1ビットのみ変化する性質を利用できます。受信側は中間カウントをスキップする可能性があるため、各サイクルで隣接値のみを見るとは限りません。
リセットリリースにもタイミングが必要
同期リセットは有効なクロックエッジで有効になり、クロックが動作しており、パルスがサンプリングをカバーする必要があります。非同期リセットはクロックを待たずに即座に有効になりますが、有効解除が有効エッジに近い場合、リカバリ/リムーバル要件に関与します。一般的な戦略は、各クロックドメインで非同期にリセットをセットし、同期してリリースし、クロックが安定するのを待つことです。具体的なデバイスでは、リセットパルス幅、電源投入時の初期化、および専用リソースを考慮する必要があります。AMD:同期リセットと非同期リセット
異なるドメインは、異なるタイミングでリセットから離脱する可能性があります。ドメイン間のハンドシェイクと FIFO では、この時点でどの信号が有効かを定義し、デフォルトのビット変化を新しいイベントとして扱わないようにする必要があります。ボタンのシンクロナイザは、デバウンスと同義ではありません。シンクロナイザはサンプリングタイミングを処理し、デバウンスは機械接点の繰り返し変化を処理します。通常、安定時間のカウントや他のフィルタリング戦略も必要です。
状態軌跡を用いた動作の照合
以下は、重複シーケンス検出、BCD 不正状態の回復、Gray 隣接性、およびセットアップ/ホールド計算例をチェックするものです。これは離散モデルチェックであり、アナログメタステーブルをシミュレートするものではなく、HDL シミュレーション、合成レポート、静的タイミング解析、および CDC 分析を代替するものではありません。
from fractions import Fraction as F
state , hits = 0 , [ ]
for pos , bit in enumerate ( map ( int , ' 10101' ) , 1 ) :
hit = state == 2 and bit == 1
if hit :
hits . append ( pos )
state = ( ( 0 , 1 ) , ( 2 , 1 ) , ( 0 , 1 ) ) [ state ] [ bit ]
assert hits == [ 3 , 5 ]
for q in range ( 16 ) :
nxt = q + 1 if q < 9 else 0
assert 0 <= nxt <= 9
assert nxt == ( ( q + 1 ) % 10 if q <= 9 else 0 )
gray = lambda n : n ^ ( n > > 1 )
for n in range ( 16 ) :
assert ( gray ( n ) ^ gray ( ( n + 1 ) % 16 ) ) . bit_count ( ) == 1
setup_slack = F ( 10 ) + F ( ' 0.5' ) - 1 - 7 - 1
hold_slack = F ( ' 0.2' ) + F ( ' 0.1' ) - F ( ' 0.5' ) - F ( ' 0.2' )
assert setup_slack == F ( ' 1.5' ) and hold_slack == F ( ' -0.4' )
assert F ( 20 ) + F ( ' 0.5' ) - 1 - 7 - 1 > setup_slack
print ( ' 重複検出、BCD 回復、Gray 隣接性及びセットアップ/ホールド予算チェック通過' )
引き続き参照