前回、多次元配列をそのままChiselで扱うためにはどうすればよいか考えたが、さらにまだ考えないといけないことがある。さらに、以下のような構文について考えた。
circuit VecBundle2 : module VecBundle2 : input in: { a : { b : UInt<8>[2] } [3] }[4] input sel: UInt<2> output out : { b : UInt<8>[2] } out.b <= in[0].a[1].b
BundleTypeが多重構造になっているタイプだ。さらに、配列で覆いかぶせている。今回はとりあえずWSubIndex
で固定値のインデックスを取っている。これを扱うためには、最終的に以下のようになってほしい。
circuit VecBundle2 : module VecBundle2 : input in_a_b : UInt<8>[2][3][4] input sel : UInt<2> output out_b : UInt<8>[2] out_b <= in_a_b[0][1]
このような、in[0].a[1].b
をどのように変換するかという問題だが、これはSubField
が登場するたびにそのメンバ変数の名前を覚えておき、それを順繰りに並べてin_a_b[0][1]
とすれば良い。まあこれを作るのにもかなり苦労したけど。
def lowerTypesExp(memDataTypeMap: MemDataTypeMap, info: Info, mname: String, subfield_name: String = "")(e: Expression): Expression = { e match { case e: WRef => e.copy(name = subfield_name) ... case e: WSubField => { kind(e) match { case InstanceKind => ... case _ => { val new_subfield_name = subfield_name match { case "" => e.name case x => e.name + x } val exps = lowerTypesExp(memDataTypeMap, info, mname, new_subfield_name)(e.expr) exps match { case ex: WSubAccess => WSubAccess(WRef(loweredExpName(e), e.tpe, kind(e), flow(e)), ex.index, ex.tpe, flow(ex)) case ex: WSubIndex => ex ...
new_subfield_name
という変数を新たに定義した。これはSubField
の名前が来るたびに順繰りに文字列として繋げていく。最終的には_a_b
という文字列を作り、WRef
の参照が来たときに、
case e: WRef => e.copy(name = subfield_name)
で名前を更新する。そしてWSubIndex
のときに変数名の最初にため込んだ値を埋め込む、という訳だ。
def lowerTypesExp(memDataTypeMap: MemDataTypeMap, ... case (e: WSubIndex) => kind(e) match { ... case _ => { val exps = lowerTypesExp(memDataTypeMap, info, mname, subfield_name)(e.expr) exps match { case ex: WSubAccess => WSubIndex(WSubAccess(WRef(loweredExpName(e), e.tpe, kind(e), flow(e)), ex.index, ex.tpe, flow(ex)), e.value, e.tpe, flow(e)) case ex: WSubIndex => WSubIndex(WSubIndex(WRef(loweredExpName(e) + "_" + subfield_name, e.tpe, kind(e), flow(e)), ex.value, ex.tpe, flow(ex)), e.value, e.tpe, flow(e))
これで上記の回路の変換を試行した。
circuit VecBundle2 : module VecBundle2 : input in_a_b : UInt<8>[2][3][4] input sel : UInt<2> output out_b : UInt<8>[2] out_b <= in_a_b[0][1]
一応想定通りの形にはなったようだ。