28 |
BSVの設計トライアル (16) |
ベクター配列によるリターンスタック
前稿までのリターンスタックrsはレジスタファイルで構成しましたが、別法のベクター配列を試してみます。 まずベクターをインポートします。
import Vector::*;
次に、リターンスタックrsを3段インスタンシエートします。
// return stack
Vector#(3, Reg#(State_t)) rs <- replicateM(mkRegU);
さらにマクロ命令定義を書き換えます。ベクター配列はrs[sp]として扱えるので、直感的に分かりやすいです。
`define call(SUB) `_pushNext; state <= State_t {func:SUB, step:S0}
`define _pushNext rs[sp] <= State_t {func:state.func, step:nextStep()}; sp <= sp + 1
`define return state <= rs[sp-1]; sp <= sp - 1
`define next state.step <= nextStep()
説明は表248.1と同一です。これを用いて、前稿の検証FSMを実行してみます。
$ bsc -sim -u TestFSM3.bsv
checking package dependencies
compiling TestFSM3.bsv
code generation for mkTestFSM starts
Elaborated module file created: mkTestFSM.ba
All packages are up to date.
$ bsc -sim -e mkTestFSM -o mkTestFSM
Bluesim object created: mkTestFSM.{h,o}
Bluesim object created: model_mkTestFSM.{h,o}
Simulation shared library created: mkTestFSM.so
Simulation executable created: mkTestFSM
$ ./mkTestFSM -m 15 -V dump.vcd | tee result
L1 S0
L1 S1
L2 S0
L2 S1
L2 S2
L3 S0
L3 S1
L4 S0
L4 S1
L3 S2
L2 S3
L2 S4
L1 S2
L1 S2
$
正しく実行することが検証できました。波形を図249.1に示します。内部信号を見ると、rs_0, rs_1, rs_2という3個のレジスタインスタンスが生成されています。これが3段のリターンスタックを構成しています。
合成結果
Vivadoによる合成結果は21 LUTのサイズでした。レジスタファイルよりもベクター配列のほうが、わずかに小さくなることが分かりました。レジスタファイルは下位モジュールのレジスタファイルをインスタンスする必要がありますが、ベクター配列は上記のようにレジスタが展開されるだけです。従って、インタフェースが簡略化されるため、小さくなると考えられます。