序章
このページでは、 source-synchronous inputとのインターフェース方法として 01-signal sampling について説明します。この種のデータ ソースとインターフェイスするための他の戦略については、 source-synchronous inputs 全般に関するページで概説されています。このページでは source-synchronous input とは何かについても説明しています。
01-signal sampling の背後にある考え方は、外部 clock が data signalとして扱われるということです。 したがって、 clock は registerによってサンプリングされます。この register は、安定した外部 clockから独立した内部 clock を使用します。
data signals は追加の registersによってサンプリングされます。この目的には、同じ内部 clock が使用されます。この内部 clock は、 01-signal samplingを実装するすべての logic にも使用されます。
この logic は、外部 clockをサンプリングしている register 上の変更を検出します。この register が '0' から '1'に変わるということは、外部 clockに rising edge があったことを意味します。 logic は、他の registers の値を FIFOに書き込むことで、このイベントに応答します。これらの registers には、外部 clock の rising edge が発生したときに存在していた data signals の値が含まれています。
この logic は、 FIFOの clock が外部の clock であり、 FIFOの data inputs が data signalsに直接接続されている場合と同じ結果を実現します。違いは、 logicがどの clock を使用するかです。 外部 clock または内部 clock。 01-signal sampling の利点は、すべての logic が内部 clockのみに依存していることです。この clock は安定していて信頼性があります。外部の clock が誤動作しても、 logic は引き続き正常に動作します。
次の図は 01-signal samplingを示しています。
この画像では、 @stable_clk は FPGAの内部 clockです。 @data_clk と @data は、 FPGAに届く信号です。 @data_clk_samp と @data_samp は FPGAの中に registers が入っています。外部信号 @data_clk を @data_clk_sampで表す。 @dataに関して @data_samp についても同様です。
この図は、 @data_clk_sampに「0 1」パターンが出現すると、 @data_samp の値が FIFOに書き込まれることを示しています。これが、この方法が「01-signal sampling」と呼ばれる理由です。
ここでは、到着したデータをどう処理するかの例として FIFO を示します。内部 clock の周波数はデータ レートよりも大幅に高いため、これは多くの場合適切なソリューションです。したがって、多くの場合、より低い clock 周波数に基づいて logic でデータを処理し続けると便利です。 FIFO は、別の clock domainの logic にデータを引き渡すための便利な方法です。
それでも、 01-signal samplingに使用されたものと同じ内部 clock を使用して logic の残りの部分を実装することは可能です。 FIFO の使用は可能性の 1 つにすぎません。
Verilogでの例
この Verilog コードは、この考え方を示しています。外部 clock は @data_clkです。
module top (
input stable_clk,
input data_clk,
input [7:0] data
);
reg [7:0] data_guard, data_samp;
reg data_clk_guard, data_clk_samp, data_clk_samp_d;
wire fifo_wr_en;
always @(posedge stable_clk)
begin
data_guard <= data;
data_clk_guard <= data_clk;
data_samp <= data_guard;
data_clk_samp <= data_clk_guard;
data_clk_samp_d <= data_clk_samp;
end
assign fifo_wr_en = data_clk_samp && !data_clk_samp_d;
data_fifo fifo_i
(
.wr_clk(stable_clk),
.din(data_samp),
.wr_en(fifo_wr_en),
[ ... other ports connected here ... ]
);
endmodule
重要な部分はFIFOの wr_enです。 @fifo_wr_en。この signal は「data_clk_samp && !data_clk_samp_d」に相当します。したがって、この signal は、 @data_clk_sampで「0 1」パターンが検出された結果としてハイになります。これにより、 @data_samp の値が FIFOに書き込まれます。
@stable_clk のみが logicによって clock として使用されることに注意してください。 @data_clk は通常の I/O inputと同じように扱われます。
@data_guard および @data_clk_guard の timing 要件は保証されていません。 input ports は、 @stable_clkに対して非同期です。したがって、 @data_guard と @data_clk_guard は metastability guardsになります。 logic は、これら 2 つの registersの値に直接依存しません。一方、 @data_samp と @data_clk_samp は、 registers が metastability guardの 2 段目であるため、 logicによって直接使用されます。
しかし、これは本当に機能するのでしょうか?答えは timing analysisにあります。
Timing analysis
timing analysis と 01-signal sampling は通常の方法とは異なります。 通常、 clock edge と data signals がサンプリングされる瞬間には一定の時間差があります。これは、サンプリングに使用される clock が data signalsと同期しているためです。しかし、 01-signal samplingでは、 @data のサンプリングは @stable_clkで行われます。したがって、サンプリングの瞬間は、 data signals自体の timingとは何の関係もありません。代わりに、 logic は rising clock edgeに近い @data_clk_samp の値のみを選択します。
したがって、 data clockの rising edge の瞬間と実際のサンプリングが発生する瞬間の間にはランダムな時間差が生じます。この方法が信頼できるとどうして言えるでしょうか?
logic designにおける timing の基本については別のページがあります。そのページでは tsu と tholdの意味が説明されています。簡単に言うと、 flip-flopの input port は、 rising edge または clock の前後で安定している必要があります ( flip-flop が rising edgeでアクティブ化されていると仮定します)。 tsu は、 rising edgeの前に input port が安定する必要がある時間を定義します。 thold は、 rising edgeの後に input port が安定するまでの時間を定義します。これらの条件のいずれかに違反した場合、 rising edge に対する flip-flopの応答は予測できません。
これを別の方法で見ることもできます。 input port は、 rising edgeの前後の特定の期間にわたって安定している必要があります。この期間を Δt = tsu + tholdと呼びましょう。 Δt およびその他のパラメータに基づいて、信頼性の高い動作を保証する timing requirements を見つけます。
timing analysis 全体は、 @data_clk_guard が高く、 @data_clk_samp が低い状況に基づいています。この場合、 clock cycle の 1 つ後に「0 1」パターンが検出されます。つまり、次期 clock cycleでは @data_clk_samp_d は「0」、 @data_clk_samp は「1」となる。結果として @fifo_wr_en は High になるため、 @data_samp にはデータ ソースが意図した値が含まれている必要があります。
したがって、分析では次の質問に焦点を当てます。 @data_clk_guard がハイで @data_clk_samp がローの場合、情報が正しく届くことを保証する @data の要件は何ですか?
分析は 2 つの部分で行われます。 どちらの部分でも、 @data_clk_guard が高く、 @data_clk_samp が低いと仮定します。最初の部分では、次のような質問が行われます。 この前提を破ることなく、 @data_clk が低レベルから高レベルに変化できる最新の瞬間は何ですか?次に、 @data_samp に正しい値が含まれていることを確認する、 @data に関する timing requirement を見つけます。
分析の後半では、逆の質問をします。 @data_clk_guard および @data_clk_sampの前提を破ることなく、 @data_clk が低から高に変化する最も早い瞬間は何ですか?次に、 timing requirementsについても同様の分析を行っていきます。
まず、いくつかのシンボルを定義しましょう。
- tclk: @stable_clkの clock period 。
- tskew: @data_clk と @dataの portsの間の skew です。これは、信号のソースから FPGAの flip-flopsまでのすべての接続における signal delays 間の最大の違いです。
- tj: jitter の clock periodへの最大限の貢献。つまり、2 つの clock edges 間の時間差は常に tclk - tj と tclk + tjの間の値になります。より正確に言えば、 clock period がこれらの制限の外にある可能性は無視できます。
分析の最初の部分
この timing diagram は @stable_clkの2つの clock cycles を示しています。以下の説明では、 @data_clk_guard は、右側の rising edge 上の @data_clk から新しい値をコピーします。同様に、 @data_guard は、同じ clock edge上の @data から新しい値をコピーします。
同じ原理により、 @data_clk_samp と @data_samp は左側の @stable_clkの rising clock edge に関連付けられます。
このシナリオでは、 @data_clk は黄色の領域の終わりで正確に High に変化します。 flip-flopの timing requirements は侵害されているため、結果は予測できません。ただし、 @data_clk_guard が高くなり、 @data_clk_samp が低くなる可能性があります。
ただし、 @data_clk の値が少し後で変更されると、 flip-flopの動作は予測可能であるため、 @data_clk_guard は確実に低くなります。 このシナリオでは、 input port は黄色の期間全体にわたって低くなります。だからこそ次のように言えるのです。 @data_clk_guard がハイで @data_clk_samp がローの場合、 @data_clk は上記の timing diagram で示されているよりも早くローからハイに変化します。したがって、 timing diagram は、 @data_clk が可能な限り最も遅い時点で変更されたシナリオを示しています。
@data_guard に信頼できる値が含まれていることを確認するには、 @data がイエロー ゾーンの前で安定している必要があります。これにより、最初の timing requirementが得られます。 @data は、 @data_clkの rising edgeより前の Δt の期間安定している必要があります。
@data_clk が先にローからハイに変更された場合でも、この timing requirement は @data_guardの tsu 要件を引き続き保証することに注意してください。したがって、 flip-flopsの tsu は、 @data_clk_guard が高く、 @data_clk_samp が低いすべてのシナリオで保証されます。
上記の timing diagram には、 skewに関連するものは何も表示されません。 skew を考慮すると、 timing requirement は次のようになります。 @data は、 @data_clkの rising edgeより前の Δt + tskew の期間安定している必要があります。
clock edge は 1 台だけが議論に関与しているため、このシナリオでは jitter を考慮する必要はありません。
分析の第 2 部
これは、このシナリオの timing diagram です。
このシナリオでは、 @data_clk は、 @stable_clkの前の clock edgeの黄色の領域の開始時に正確に High に変化します。
この状況では @data_clk_guard が高くなるのは間違いありません。ただし、 timing は以前の clock cycleで違反されていたため、 @data_clk_samp の値は予測できません。先ほどと同様に、 @data_clk_samp が低くなる可能性があります。しかし、 @data_clk がこれより早く値を変更すると、 @data_clk_samp は間違いなく高くなります。
したがって、 @data_clk_guard がハイで @data_clk_samp がローの場合、 @data_clk は上記の timing diagram で示されているよりも遅くローからハイに変化します。したがって、 timing diagram は、 @data_clk が可能な限り早い時点で変更されたシナリオを示しています。
@data_guard に正しい値が含まれていることを確認するには、 @data が右側の黄色の領域の後に安定している必要があります。
上記の timing diagram によると、 @data_clkの rising edge と 2 番目の黄色の領域の終わりとの時間差は Δt + tclkです。ただし、 skew と jitter も考慮する必要があります。したがって、 @data は、 @data_clk以降 Δt + tclk + tskew + tj の期間安定している必要があります。
@data_clk が以前に低から高に変更された場合でも、この timing requirement は @data_guardの hold 要件を引き続きカバーすることに注意してください。したがって、 flip-flopsの thold は、 @data_clk_guard が高く、 @data_clk_samp が低いすべてのシナリオで保証されます。
timing requirements
上記の timing analysis の結論として、 01-signal samplingの信頼性の高い動作を保証する 2 つの timing requirements は次のとおりです。
- @data は、 @data_clkの rising edgeよりも少なくとも Δt + tskew の期間安定している必要があります。
- @data は、 @data_clkの rising edgeの後、少なくとも Δt + tclk + tskew + tj の期間安定している必要があります。
これらの要件は複雑に見えるかもしれませんが、多くの場合、それらの要件を確実に達成するのは簡単です。たとえば、 @data が @data_clkの falling edgeに合わせて変更される場合、通常、これらの要件を確保するのは簡単です。 @stable_clk が @data_clkの 3 倍の速度であれば、多くの場合、それで十分です。
ほとんどの場合、 Δt、 tskew 、または tjの正確な値を知る必要はありません。多くの場合、上記の 2 つの要件に基づいて、 Δt および Δt + tskew + tj の許容されるサイズを計算するだけで十分です。 @stable_clkの周波数が十分に高い場合、これら 2 つの式の値は、 FPGAで現実的に可能な値よりも大きくなることがよくあります。
IOB registersは、 FPGAと input ports (tskew) の間の timing の違いを最小限に抑えるために使用する必要があります。また、IOB registers が確実に使用されるように、 timing constraints はこれらの input ports と関連付けて記述する必要があります。
01-signal samplingの亜種
これまでの説明では、 data_clkの falling edgeに合わせて @data も変更されると想定してきました。 @data_clkの rising edgeとともに @data が変更される場合は、 @data_clk_guard がローで @data_clk_samp がハイのときに代わりに logic がアクティブになるように調整する必要があります。言い換えれば、 logic は「1 0」パターンを検索することで @data_clk の falling edge を検出する必要があります。
@dataの値をいつ取得するかについて、別の基準を選択することもできます。たとえば、 @fifo_wr_en を数 clock cycles遅らせる方がよい場合があります。場合によっては、 @fifo_wr_en を上記の提案よりも早くアクティブにした方がよい場合があります。これは、 @data_clk と @dataのタイミング関係に依存します。信号源のデータシートを参照し、上に示すように timing を分析します。
@data_clkの周波数が比較的高い場合は、 @data_clk と @dataをサンプリングするために DDR registers を使用することができます。このソリューションを実装する logic はもう少し複雑ですが、同じ原則が適用されます。
@data_guard は本当に metastability guardですか?
この質問に対する簡単な答えは「はい」です。 @data は @stable_clkと非同期であるため、 @data_guardの timing requirements は保証されません。
ただし、 @data_guardのコンテンツが実際に使用される clock cycles に議論を絞り込んでみましょう。 上記の 2 つの timing requirements により、 @data_guard を実装する flip-flops が確実に動作することが保証されることに注意してください。この flip-flops は tsu と thold の両方が保証されています。
したがって、 @data_guard は実際には metastability guardとして使用されません。この register の使い方では、 delay registerとしてのみ機能します。ただし、追加の register が、物理信号 (@data) が誤動作した場合に発生する可能性のある timing violations から保護することに問題はありません。これは、信号がコネクタを介して FPGA に接続されている場合に特に関係します。
実際の例
別ページに OV7670 camera sensor と接続した logic の例があります。この logic は、 01-signal samplingによってこのカメラ センサーからピクセル データを取得します。カメラセンサーからの inputs は次のとおりです。
input pclk_in;
input [7:0] D_in;
input hsync_in, vsync_in;
01-signal sampling を実行する logic は次のとおりです。
(* IOB = "TRUE" *) reg [7:0] D_guard;
(* IOB = "TRUE" *) reg pclk_guard, hsync_guard, vsync_guard;
reg [7:0] D;
reg pclk, hsync, vsync;
wire sample_valid;
reg previous_pclk;
always @(posedge stable_clk)
begin
// Metastability guards on asynchronous inputs
D_guard <= D_in;
pclk_guard <= pclk_in;
hsync_guard <= hsync_in;
vsync_guard <= vsync_in;
D <= D_guard;
pclk <= pclk_guard;
hsync <= hsync_guard;
vsync <= vsync_guard;
previous_pclk <= pclk;
end
assign sample_valid = pclk && !previous_pclk;
明確にするために、ここで示されている Verilog コードと、 OV7670に関するページの Verilog コードの間にはわずかな違いがあります。これらの違いは、 logic の動作には影響しません。
この Verilog コードを、このページの冒頭で示した Verilog コードと比較してみましょう。 signals の名前は異なりますが、同じ意味です。 @dataの代わりに、 @D_in、 @hsync_in 、および @vsync_inが登場しました。 @data_clkの代わりに、 @pclk_inが登場しました。そして、 @fifo_wr_enの代わりに、 @sample_validが登場しました。名前の変更が混乱を招く可能性がありますが、上記の Verilog コードからの変更はありません。
registersの宣言の前にある「(* IOB = "TRUE" *)」の部分に注意してください。 Vivadoを使用する場合、これは registers を IOBsに挿入するように要求する可能性のある方法です。
この例では、 FIFO は示されていません。これは、すべてのデータを FIFOに書き込みたくないためです。 @sample_valid が高い場合、 @D、 @hsync 、および @vsync にカメラ センサーからの正しい値が含まれていることを意味します。しかし、それは @D を FIFOに書き込むという意味ではありません。 @hsync と @vsyncに依存します。したがって、 OV7670 の例には、ピクセルのみが FIFOに書き込まれるようにする追加の logic があります。
しかし、興味深い部分に移りましょう。 timing の計算。
この例の @stable_clk の周波数は 100 MHzです。 @pclk_in の周波数は 25 MHzです。 OV7670のデータシートによると、信号 @D_in、 @hsync_in 、および @vsync_in は、 @pclk_in が High から Low (falling edge) に変化した後、 5 ns の間安定していることが保証されています。
@pclk_inの clock cycle は 40 nsです。したがって、 falling edge から rising edge までの距離は 20 nsになります。それでは timing requirementsと比較してみましょう。
最初の timing requirement では、 @D_in、 @hsync_in 、および @vsync_in は、 @pclk_inの rising edgeの前に Δt の期間安定している必要がありました。実際には、これらの信号は falling edgeの 5 ns 後から安定しています。したがって、これらの信号は、次の rising edgeまでの少なくとも 15 ns で安定しています。 Δt = tsu + tholdを思い出してください。つまり、 timing requirement は実際には tsu + thold が 15 nsより小さいということになります。これはすべての FPGAに当てはまります。
2 番目の要件は、これらの信号が @pclk_inの rising edgeから少なくとも Δt + tclk + tskew + tj の期間安定していることです。ただし、これらの信号は falling edgeの結果としてのみ変化します。したがって、 Δt + tclk + tskew + tj が 20 nsよりも小さいことが要件となります。 @stable_clkの周波数は 100 MHzであるため、 tclk は 10 ns と同等です。したがって、実際の要件は、 Δt + tskew + tj が 10 nsよりも小さいことです。繰り返しますが、これはすべての FPGAで明らかです。
この例では、 FPGAの正確な timing parametersに関する知識がなくても、 timing requirements を簡単に確認できる方法を示します。
結論
01-signal sampling は、 FPGA がサポートできる clock 周波数に比べて data rate が低い場合に優れたソリューションです。 data clock は安定している必要はありません。また、 data clock の正確な周波数を事前に知る必要もありません。 timing requirementsを2台確保できれば十分です。
この方法にはさらに次のような利点もあります。 この clock が短時間非アクティブになった場合、唯一の結果は、その特定の期間中に data が収集されなくなることです。この clock の誤動作による被害は、 data flowの破壊に限定されます。これは目に見えるシステムの誤動作につながりますが、この誤動作は clock の問題のように見えます ( FPGA がゴーストに取り憑かれているわけではありません)。
したがって、 data signals の sampling には固有のランダム性がありますが、 01-signal sampling は source synchronous inputの信頼性が高く堅牢なソリューションです。唯一の本当の欠点は、 data rateの制限です。