[Chisel]ポリモーフィズムは使わない
やりたいこと
類似したユニットが複数ある
これらの処理は大部分が共通で一部のみ異なる
条件に応じて適切なユニットを1つ選び、処理を実行させる
やろうとしたこと
これを実現するために
親クラスを定義し、共通処理はここに記述
各ユニットは上記を継承する子クラスとして定義し、独自の処理はここに記述
どのユニットに処理を実行させるかを決定
「実行するユニット」を表す変数を定義。型は親クラス。
選ばれたユニットを「実行するユニット」に割り当て、処理を実行させる
ということをしようとした。いわゆるポリモーフィズムというものだ。
class UnitBase{
}
class Unit1 extends UnitBase{
}
class Unit2 extends UnitBase{
}
val selectedUnit = Module(new UnitBase)
when(...){
selectedUnit := Module(new Unit1) //※
}
ただしこれは※のところで「型が違う」というコンパイルエラーになる。chiselコンパイラの型チェックは厳密らしい。
解決策
以前の「ループを途中で抜けたい」の時と同じで、これも「ハードウェアをどう操作するか」という観点で考えられていないから起こる。
現実の回路で「『実行ユニット』の枠が1つあって、条件に応じてどれか一つがそこに当てはめられる」なんて動作はしない。
「やりたいこと」をやるならば、
全てのユニットに必要な信号は接続しておく
さらに「処理を行うか否か」の有効信号を用意する。
選択されたユニットの有効信号のみをオンにする
というようにすればよい。
class UnitBase{
val io = IO(new Bundle {
val sig = Input(UInt(32.W))
val enb = Input(Bool())
}
}
val units:Seq[UnitBase] = Seq(Module(new Unit1), Module(new Unit2))
Seq.tabule(4){i => {
units(i).sig := ...
units(i).enb := Mux(..., ture.B, false.B)
}
}
最新記事
すべて表示現象 配列がある インデックスを表す変数が配列のサイズ内かをチェックし、サイズ内の場合のみ要素にアクセス というよくあることをやろうとした val array = Seq.fill(ARRAY_SIZE)(...) when(i.U < ARRAY_SIZE){...
概要 Queueを使ってデータのやり取りをする場合、以下のような操作が可能です。 Queue.io.enq.valid:falseにするとデータを入れない Queue.io.deq.valid:falseにするとデータを取り出さない これらの使い分けについてまとめてみます...
やりたいこと ★ 同種のモジュールが複数ある これらのうち、所定の条件を満たすものを1つ選択 これを実現するために モジュール一覧を配列で定義 Seq.tabulateでモジュール配列に対してループを回す 1つ1つ条件を満たすかチェック 満たせばそれを選択し、ループ終了...
Comments