インテルのみ表示可能 — GUID: olu1504069671746
Ixiasoft
2.4.2.1. 高速クロック・ドメイン
2.4.2.2. ループの再構築
2.4.2.3. コントロール信号のバックプレッシャー
2.4.2.4. FIFOステータス信号によるフロー・コントロール
2.4.2.5. スキッドバッファーを使用したフロー制御
2.4.2.6. リードモディファイライトメモリー
2.4.2.7. カウンターとアキュムレーター
2.4.2.8. ステートマシン
2.4.2.9. メモリー
2.4.2.10. DSPブロック
2.4.2.11. 一般ロジック
2.4.2.12. モジュラスと除算
2.4.2.13. リセット
2.4.2.14. ハードウェアの再利用
2.4.2.15. アルゴリズム要件
2.4.2.16. FIFO
2.4.2.17. 三進加算器
インテルのみ表示可能 — GUID: olu1504069671746
Ixiasoft
2.4.1.4.2. ループ・パイプラインにおデモ
以下は、サンプルデザインでアキュムレーターを最適化するための適切なループ・パイプライン処理を示しています。元の実装では、入力されるアキュムレーター・データはxで乗算され、前の値outに加算され、yで乗算されます。このデモでは、次の手法を使用してパフォーマンスを改善します。
- フォワードロジックの分離を実装する
- ループレジスターのリタイミング
- カスケードロジックでフィードバックループの等価性を作成する
図 53. 元のループ構造
元のループ構造の例Verilog HDLコード
module orig_loop_strct (rstn, clk, in, x, y, out);
input clk, rstn, in, x, y;
output out;
reg out;
reg in_reg;
always @ ( posedge clk )
if ( !rstn ) begin
in_reg <= 1'b0;
end else begin
in_reg <= in;
end
always @ ( posedge clk )
if ( !rstn ) begin
out <= 1'b0;
end else begin
out <= y*out + x*in_reg;
end
endmodule //orig_loop_strct
最適化の最初の段階は、ロジックを書き直してループからできるだけ多くのロジックを削除し、フォワードロジックブロックを作成することです。書き換えの目標は、フィードバックループから可能な限り多くの作業を削除することです。Compilerは、フィードバックループ内のロジックを自動的に最適化することはできません。ループからロジックを削除する際には、次の推奨事項を考慮してください。
- ループの値に直接依存しない、ループの前にできるだけ多くの決定を評価し、できるだけ多くの計算を実行します。
- ループに渡す前に、レジスターステージにロジックを渡す可能性があります。
ロジックを書き換えた後、Compilerは、フォワードパスに移動したロジックのタイミングを自由に変更できるようになりました。
図 54. フォワードロジックとループの分離
次の最適化段階で、ループレジスターのタイミングを変更して、デザインが元のループ回路と同じように機能することを確認します。
図 55. リタイム・ループ・レジスター
最後に、強調表示された境界内のロジックを使用して最初の最適化手順を繰り返すことにより、ループをさらに最適化します。
図 56. Cascade Loop Logic、Hyper-Retimer、およびSynthesis Optimizations(4レベルの最適化)
4レベル最適化の例Verilog HDLコード
module cll_hypr_rtm_synopt ( rstn, clk, x, y, in, out);
input rstn, clk, x, y, in;
output out;
reg out;
reg in_reg;
wire out_add1;
wire out_add2;
wire out_add3;
wire out_add4;
reg out_add1_reg1;
reg out_add1_reg2;
reg out_add1_reg3;
reg out_add1_reg4;
always @ ( posedge clk )
if ( !rstn ) begin
in_reg <= 0;
end else begin
in_reg <= in;
end
always @ ( posedge clk )
if ( !rstn ) begin
out_add1_reg1 <= 0;
out_add1_reg2 <= 0;
out_add1_reg3 <= 0;
out_add1_reg4 <= 0;
end else begin
out_add1_reg1 <= out_add1;
out_add1_reg2 <= out_add1_reg1;
out_add1_reg3 <= out_add1_reg2;
out_add1_reg4 <= out_add1_reg3;
end
assign out_add1 = x*in_reg + ((((y*out_add1_reg4)*y)*y)*y);
assign out_add2 = out_add1 + (y*out_add1_reg1);
assign out_add3 = out_add2 + ((y*out_add1_reg2)*y);
assign out_add4 = out_add3 + (((y*out_add1_reg3)*y)*y);
always @ ( posedge clk ) begin
if ( !rstn )
out <= 0;
else
out <= out_add4;
end
endmodule //cll_hypr_rtm_synopt