インテル® Hyperflex™ アーキテクチャー高性能デザイン・ハンドブック

ID 683353
日付 10/04/2021
Public
ドキュメント目次

2.4.1.1.1. Shannonの分解例

サンプル回路は、 internal_total値の入力値をターゲット値との関係に基づいて加算または減算します。回路のコアは、次の例に示すtarget_loopモジュールです。

Shannonの分解前のソースコード

module target_loop (clk, sclr, data, target, running_total);
parameter WIDTH = 32;

input clk;
input sclr;
input [WIDTH-1:0] data; 
input [WIDTH-1:0] target; 
output [WIDTH-1:0] running_total; 

reg [WIDTH-1:0] internal_total; 

always @(posedge clk) begin
		if (sclr)
		begin
 			internal_total <= 0;
		end
		else begin
  		internal_total <= internal_total + ((( internal_total > target) ? -data:data)* (target/4));
		end
end
assign running_total = internal_total;
end module 

このモジュールでは、Hyper-Retimingをイネーブルにするための推奨事項に基づいて、同期クリアを使用します。

図 45は、レジスター・リングでインスタンス化されたtarget_loopモジュールのFast Forward Compileレポートを示しています。

図 45. Shannonの分解前のFast Forward Compileのレポート

Hyper-Retimingは、Fast Forward Compileでパイプライン・ステージを追加することで約248 MHzをレポートします。Limiting Reasonカラムは、クリティカル・チェーンがループであることを示します。クリティカル・チェーン・レポートを調べると、チェーンセグメントに繰り返した構造があることがわかります。Optimizing Loopsのセクションに、繰り返した構造を例として示します。

次の図は、前のサンプルコードで式を実装する構造を示しています。機能ブロックは、比較演算、加算演算、および乗算演算に対応します。各算術ブロックの名前のゼロは、ネットリストの合成名の一部です。ゼロは、ブロックが合成によって作成された演算子の最初のゼロ・インデックス付きインスタンスであるためです。

図 46. クリティカル・チェーンのサブループの要素

この式はShannonの分解の候補です。データの正または負の値で1回の加算だけを実行する代わりに、次の2つの計算を同時に実行できます。

  • internal_total - (data * target / 4)
  • internal_total +(data * target / 4)

次に、比較internal_total> targetの結果を使用して、使用する計算結果を選択することができます。次の例では、Shannonの分解を使用してinternal_total計算を実装するコードの修正版を示します。

Shannonの分解後のソースコード

module target_loop_shannon (clk, sclr, data, target, running_total);
  parameter WIDTH = 32;

input clk;
input sclr;
input [WIDTH-1:0] data;
input [WIDTH-1:0] target;
output [WIDTH-1:0] running_total;

reg [WIDTH-1:0] internal_total;
wire [WIDTH-1:0] total_minus;
wire [WIDTH-1:0] total_plus;

assign total_minus = internal_total - (data * (target / 4));
assign total_plus = internal_total + (data * (target / 4));

always @(posedge clk) begin
  if (sclr)
  begin 
     internal_total <= 0;
  end
  else begin
     internal_total <= (internal_total > target) ? total_minus:total_plus);
  end
end

assign running_total = internal_total;
endmodule

次の図に示すように、コードを変更してデザインをリコンパイルすると、パフォーマンスはほぼ倍増します。

図 47. Shannonの分解後のFast Forward Summaryのレポート