9 |
Pongの作成 (4) |
疑似乱数生成器
ChatGPTにLFSRのアルゴリズムを持つ疑似乱数生成器を記述してもらいました。以下の完成したモジュールはそれを手直ししたものです。
interface Randomizer_ifc; method ActionValue#(Bit#(1)) random_01(); endinterface //(* synthesize *) モジュールをインライン化するためコメントアウト module mkRandomizer(Randomizer_ifc); Reg#(Bit#(16)) lfsr <- mkReg(16'hACE1); // 適当な非ゼロの初期値 method ActionValue#(Bit#(1)) random_01(); Bit#(1) newBit = lfsr[15] ^ lfsr[13] ^ lfsr[12] ^ lfsr[10]; lfsr <= {lfsr[14:0], newBit}; return lfsr[15]; endmethod endmodule
ActionValueメソッドの呼び出し方
作成した疑似乱数生成器の呼び出しが少々難しかったのでまとめておきます。BSVにおいてはモジュールインタフェース内に記述されるメソッドの型は
- Value Method
- ActionValue Method
- Action Method
の3種類があります。それぞれ入力、入出力、出力ポートに対応しますが、ActionValueの呼び出し方に少々困難がありました。単純にメソッドを変数に入れることができないためです。
特にFSMを構成するseqブロック内で、あるレジスタwにValueメソッドの戻り値を代入するだけなら、
seq : w <= random_01(); : endseq
等とすれば良いのですが、この場合のrandom関数は内部状態を持ち、それが呼び出しにより更新されるという副作用を持つため、ActionValueメソッドとして呼び出します。この呼び出し法が少々難しく、"<-"を用いてインスタンスした上で、かつ単純にseqの中で呼ぶことはできず、actionブロックを構成してその中でのみ有効な値となります。
実例を挙げると、
import Randomizer::*; Randomizer_ifc randomizer <- mkRandomizer; : seq action : Bit#(1) w <- randomizer.random_01(); : endaction endseq
のように、actionブロックの中で"<-"を用いて関数を呼び出します。特にactionブロックを構成することになかなか気づきませんでした。
Leave a Comment