符号なし固定小数点数の平方根を計算するための 2 分法アルゴリズム
この例では、2 分法アルゴリズムを実装して固定小数点表記の数値の平方根を計算する MATLAB® 設計からの HDL コードの生成方法を示します。
共有およびストリーミングの最適化において、元々 HDL コードで n 個の乗算器 (語長が n の場合) を使用する同じ実装で、1 つの乗算器のみをもつ HDL コードを生成できます。これは MATLAB HDL Coder™ の最適化の能力を表しています。
平方根アルゴリズムの設計は、結果として得られる RTL 設計で高速クロック レートを実現するためのパイプラインの概念を示します。この設計は既に固定小数点であるため、固定小数点の変換を実行する必要はありません。
MATLAB 設計
% Design Sqrt design_name = 'mlhdlc_sqrt'; % Test Bench for Sqrt testbench_name = 'mlhdlc_sqrt_tb';
平方根の設計を見てみましょう。
dbtype(design_name)
1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 % MATLAB design: Pipelined Bisection Square root algorithm
3 %
4 % Introduction:
5 %
6 % Implement SQRT by the bisection algorithm in a pipeline, for unsigned fixed
7 % point numbers (also why you don't need to run fixed-point conversion for this design).
8 % The demo illustrates the usage of a pipelined implementation for numerical algorithms.
9 %
10 % Key Design pattern covered in this example:
11 % (1) State of the bisection algorithm is maintained with persistent variables
12 % (2) Stages of the bisection algorithm are implemented in a pipeline
13 % (3) Code is written in a parameterized fashion, i.e. word-length independent, to work for any size fi-type
14 %
15 % Ref. 1. R. W. Hamming, "Numerical Methods for Scientists and Engineers," 2nd, Ed, pp 67-69. ISBN-13: 978-0486652412.
16 % 2. Bisection method, http://en.wikipedia.org/wiki/Bisection_method, (accessed 02/18/13).
17 %
18
19 % Copyright 2013-2015 The MathWorks, Inc.
20
21 %#codegen
22 function [y,z] = mlhdlc_sqrt( x )
23 persistent sqrt_pipe
24 persistent in_pipe
25 if isempty(sqrt_pipe)
26 sqrt_pipe = fi(zeros(1,x.WordLength),numerictype(x));
27 in_pipe = fi(zeros(1,x.WordLength),numerictype(x));
28 end
29
30 % Extract the outputs from pipeline
31 y = sqrt_pipe(x.WordLength);
32 z = in_pipe(x.WordLength);
33
34 % for analysis purposes you can calculate the error between the fixed-point bisection routine and the floating point result.
35 %Q = [double(y).^2, double(z)];
36 %[Q, diff(Q)]
37
38 % work the pipeline
39 for itr = x.WordLength-1:-1:1
40 % move pipeline forward
41 in_pipe(itr+1) = in_pipe(itr);
42 % guess the bits of the square-root solution from MSB to the LSB of word length
43 sqrt_pipe(itr+1) = guess_and_update( sqrt_pipe(itr), in_pipe(itr+1), itr );
44 end
45
46 %% Prime the pipeline
47 % with new input and the guess
48 in_pipe(1) = x;
49 sqrt_pipe(1) = guess_and_update( fi(0,numerictype(x)), x, 1 );
50
51 %% optionally print state of the pipeline
52 %disp('************** State of Pipeline **********************')
53 %double([in_pipe; sqrt_pipe])
54
55 return
56 end
57
58 % Guess the bits of the square-root solution from MSB to the LSB in
59 % a binary search-fashion.
60 function update = guess_and_update( prev_guess, x, stage )
61 % Key step of the bisection algorithm is to set the bits
62 guess = bitset( prev_guess, x.WordLength - stage + 1);
63 % compare if the set bit is a candidate solution to retain or clear it
64 if ( guess*guess <= x )
65 update = guess;
66 else
67 update = prev_guess;
68 end
69 return
70 end
設計のシミュレーション
コードの生成前にテスト ベンチを使用して設計のシミュレーションを実行し、実行時エラーが発生しないことを常に確認することをお勧めします。
mlhdlc_sqrt_tb
Iter = 01| Input = 0.000| Output = 0000000000 (0.00) | actual = 0.000000 | abserror = 0.000000 Iter = 02| Input = 0.000| Output = 0000000000 (0.00) | actual = 0.000000 | abserror = 0.000000 Iter = 03| Input = 0.000| Output = 0000000000 (0.00) | actual = 0.000000 | abserror = 0.000000 Iter = 04| Input = 0.000| Output = 0000000000 (0.00) | actual = 0.000000 | abserror = 0.000000 Iter = 05| Input = 0.000| Output = 0000000000 (0.00) | actual = 0.000000 | abserror = 0.000000 Iter = 06| Input = 0.000| Output = 0000000000 (0.00) | actual = 0.000000 | abserror = 0.000000 Iter = 07| Input = 0.000| Output = 0000000000 (0.00) | actual = 0.000000 | abserror = 0.000000 Iter = 08| Input = 0.000| Output = 0000000000 (0.00) | actual = 0.000000 | abserror = 0.000000 Iter = 09| Input = 0.000| Output = 0000000000 (0.00) | actual = 0.000000 | abserror = 0.000000 Iter = 10| Input = 0.000| Output = 0000000000 (0.00) | actual = 0.000000 | abserror = 0.000000 Iter = 11| Input = 4.625| Output = 0000010000 (2.00) | actual = 2.150581 | abserror = 0.150581 Iter = 12| Input = 12.500| Output = 0000011100 (3.50) | actual = 3.535534 | abserror = 0.035534 Iter = 13| Input = 16.250| Output = 0000100000 (4.00) | actual = 4.031129 | abserror = 0.031129 Iter = 14| Input = 18.125| Output = 0000100010 (4.25) | actual = 4.257347 | abserror = 0.007347 Iter = 15| Input = 20.125| Output = 0000100010 (4.25) | actual = 4.486090 | abserror = 0.236090 Iter = 16| Input = 21.875| Output = 0000100100 (4.50) | actual = 4.677072 | abserror = 0.177072 Iter = 17| Input = 35.625| Output = 0000101110 (5.75) | actual = 5.968668 | abserror = 0.218668 Iter = 18| Input = 50.250| Output = 0000111000 (7.00) | actual = 7.088723 | abserror = 0.088723 Iter = 19| Input = 54.000| Output = 0000111010 (7.25) | actual = 7.348469 | abserror = 0.098469 Iter = 20| Input = 62.125| Output = 0000111110 (7.75) | actual = 7.881941 | abserror = 0.131941 Iter = 21| Input = 70.000| Output = 0001000010 (8.25) | actual = 8.366600 | abserror = 0.116600 Iter = 22| Input = 81.000| Output = 0001001000 (9.00) | actual = 9.000000 | abserror = 0.000000 Iter = 23| Input = 83.875| Output = 0001001000 (9.00) | actual = 9.158330 | abserror = 0.158330 Iter = 24| Input = 83.875| Output = 0001001000 (9.00) | actual = 9.158330 | abserror = 0.158330 Iter = 25| Input = 86.875| Output = 0001001010 (9.25) | actual = 9.320676 | abserror = 0.070676 Iter = 26| Input = 95.125| Output = 0001001110 (9.75) | actual = 9.753205 | abserror = 0.003205 Iter = 27| Input = 97.000| Output = 0001001110 (9.75) | actual = 9.848858 | abserror = 0.098858 Iter = 28| Input = 101.375| Output = 0001010000 (10.00) | actual = 10.068515 | abserror = 0.068515 Iter = 29| Input = 102.375| Output = 0001010000 (10.00) | actual = 10.118053 | abserror = 0.118053 Iter = 30| Input = 104.250| Output = 0001010000 (10.00) | actual = 10.210289 | abserror = 0.210289

HDL Coder プロジェクトの新規作成
coder -hdlcoder -new mlhdlc_sqrt_prj
次に、mlhdlc_sqrt.m ファイルを MATLAB 関数としてプロジェクトに追加し、mlhdlc_sqrt_tb.m を MATLAB テスト ベンチとして追加します。
MATLAB HDL Coder プロジェクトの作成と入力に関する詳細なチュートリアルについては、MATLAB から HDL へのワークフロー入門を参照してください。
HDL コード生成の実行
この設計は既に固定小数点であり、HDL コード生成に適しています。この設計に対して浮動小数点から固定小数点へのアドバイザーを実行することは望ましくありません。
[ワークフロー アドバイザー] ボタンをクリックして HDL ワークフロー アドバイザーを開始します。
[HDL ワークフロー アドバイザー] タスクで [固定小数点の変換] を
Keep original typesに設定します。[HDL コード生成] タスクの [最適化] タブを選択します。
[永続配列変数を RAM にマッピング] チェックボックスをオフにします。このオプションをオフにすると、パイプラインが RAM と推定されなくなります。
さらに、[分散型パイプライン レジスタ] を選択し、[リソース共有係数] を
wordlength(ここでは 10) に設定して、[ループのストリーム] を選択できます。[HDL コード生成] タスクを右クリックし、[このタスクを実行] をクリックします。
コード生成ログのウィンドウにあるハイパーリンクをクリックして、生成された HDL コードを確認します。
合成結果の確認
ISE がマシンにインストールされている場合は、次の既定のオプションで論理合成ステップを実行します。
合成レポートで、最適化オプションが有効になっていない合成ツールによって報告されたクロック周波数を確認します。
通常、
Virtex7チップ ファミリ、デバイスxc7v285t、スピード グレード-3の Xilinx® ISE 合成ツールを使用するこの設計のタイミングのパフォーマンスは約229MHzとなり、連結パスの最大遅延は0.406nsとなります。この設計の最適化 (ループ ストリーミングと乗算器共有) は、タイミングに対する中程度のトレードオフによってリソース使用率を削減するように機能します。テスト ベンチにおける特定の語長サイズについては、乗算器の数が
nから 1 に減っていることがわかります。