インテル® Quartus® Primeプロ・エディションのユーザーガイド: デザイン上の推奨事項

ID 683082
日付 4/13/2020
Public

このドキュメントの新しいバージョンが利用できます。お客様は次のことを行ってください。 こちらをクリック 最新バージョンに移行する。

ドキュメント目次

1.6.2. クロック・マルチプレクサー

クロック・マルチプレクサーは、異なるクロックソースで同じロジック機能を動作させるために使用される場合があります。 このタイプのロジックは、機能的な問題を引き起こすグリッチを引き起こす可能性があります。組み合わせロジックに固有の遅延もタイミングの問題につながる可能性があります。クロック・マルチプレクサー ーは、広範なデザイン・ルール・チェックおよびタイミング解析ツールから警告をトリガーします。

マルチプレクサーのロジックを使用する代わりに、専用ハードウェアを使用して、使用可能な場合にクロック多重化を実行します。たとえば、特定のIntel FPGAデバイスで使用可能なクロックスイッチオーバー機能またはクロック制御ブロックを使用できます。これらの専用ハードウェア・ブロックは、グリッチを回避し、グローバルな低スキュー・ルーティング・ラインを使用することを保証し、クロックラインのロジック遅延によるデバイスのホールドタイムの問題を回避します。 Intel FPGAデバイスは、ダイナミックPLLリコンフィグレーションもサポートしています。これは、デバイスの動作中にクロックレートを変更する最も安全で堅牢な方法です。

デザインのクロックが多すぎてクロック制御ブロックを使用できない場合、またはダイナミック・リコンフィグレーションがデザインにとって複雑すぎる場合、ロジックセルにクロック・マルチプレクサーを実装できます。ただし、この実装を使用する場合、入力の同時切り替えを検討し、グリッチのない遷移を確保してください。

図 2. 6入力LUTのシンプル・クロック・マルチプレクサー

各デバイスのデータシートには、LUT機能に関係なく、入力信号の同時切り替え中にLUT出力がどのようにグリッチするかが記載されています。 4:1 MUX機能は同時データ入力の切り替え中に検出可能なグリッチを生成しませんが、多重化ロジックの一部のセル実装では重大なグリッチが発生するため、このクロック・マルチプレクサー構造は推奨されません。この実装の追加の問題は、 clk_select信号の変更中に出力が不規則に動作することです。この動作により、システムクロックによって供給されるすべてのレジスターでタイミング違反が発生し、メタスタビリティーが発生する可能性があります。

より洗練されたクロック選択構造により、トグルとスイッチングの同時問題を排除できます。

図 3. グリッチのないクロック・マルチプレクサー ー構造

この構造は、任意の数のクロックチャネルに一般化できます。このデザインにより、他のすべてが少なくとも数サイクル非アクティブになるまでクロックがアクティブにならず、クロックが低い間にアクティブになることが保証されます。デザインはCLK_OUT ORゲートの入力には、同時トグルがない保証され、右側にANDゲートにsynthesis_keepディレクティブを適用します。

注: クロックAからクロックBに切り替えるには、クロックAが少なくとも数サイクル動作し続ける必要があります。クロックAがすぐに停止すると、デザインは固まります。この例では、選択信号は「ワンホット」コントロールとして実装されていますが、必要に応じて他のエンコードを使用できます。入力側のロジックは非同期であり、重要ではありません。このデザインは、切り替えプロセス中の極端なグリッチに耐えることができます。

Verilog HDL Clock Multiplexing Design to Avoid Glitches

この例はVerilog-2001で機能します。

module clock_mux (clk,clk_select,clk_out);

	parameter num_clocks = 4;

	input [num_clocks-1:0] clk;
	input [num_clocks-1:0] clk_select; // one hot
	output clk_out;

	genvar i;

	reg [num_clocks-1:0] ena_r0;
	reg [num_clocks-1:0] ena_r1;
	reg [num_clocks-1:0] ena_r2;
	wire [num_clocks-1:0] qualified_sel;

	// A look-up-table (LUT) can glitch when multiple inputs 
	// change simultaneously. Use the keep attribute to
	// insert a hard logic cell buffer and prevent 
	// the unrelated clocks from appearing on the same LUT.

	wire [num_clocks-1:0] gated_clks /* synthesis keep */;

	initial begin
		ena_r0 = 0;
		ena_r1 = 0;
		ena_r2 = 0;
	end

	generate
		for (i=0; i<num_clocks; i=i+1) 
		begin : lp0
			wire [num_clocks-1:0] tmp_mask;
			assign tmp_mask = {num_clocks{1'b1}} ^ (1 << i);

			assign qualified_sel[i] = clk_select[i] & (~|(ena_r2 & tmp_mask));

			always @(posedge clk[i]) begin
				ena_r0[i] <= qualified_sel[i];    	
				ena_r1[i] <= ena_r0[i];    	
			end

			always @(negedge clk[i]) begin
				ena_r2[i] <= ena_r1[i];    	
			end

			assign gated_clks[i] = clk[i] & ena_r2[i];
		end
	endgenerate

	// These will not exhibit simultaneous toggle by construction
	assign clk_out = |gated_clks;

endmodule