FIRRTLの解析に際し、BundleTypeとVecTypeの解析を行っている。LowerType()
の中で、どのように変換されているのか解析をする。
以下の3つのコードを用意した。
circuit VecModules : module VecModules : input in: UInt<32>[4] input sel: UInt<2> output out : UInt<32> out <= in[sel]
circuit BundleUInt : module BundleUInt : input in: { a: UInt<32>, b: UInt<32> } input sel: UInt<1> output out : UInt<32> out <= mux(sel, in.a, in.b)
circuit VecModules : module VecModules : input in: { a: UInt<32> }[4] input sel: UInt<2> output out : UInt<32> out <= in[sel].a
LowerType
の時に、すべての配列型、Bundle型を分解されてしまう。これが具体的にどうなっているかを解析した。
firrtl/passes/LowerTypes.scala
def lowerTypes(renames: RenameMap)(m: DefModule): DefModule = { val memDataTypeMap = new MemDataTypeMap renames.setModule(m.name) // Lower Ports val portsx = m.ports flatMap { p => ... println(s"lowerTypes() p = ${p}") println(s"exps = ${exps}") println(s"names = ${names}")
まず、UIntだけを含む単純なVecModule
だが、
exps = Vector(WSubIndex( WRef(in,VectorType(UIntType(IntWidth(32)),4),PortKind,SourceFlow), 0, UIntType(IntWidth(32)),SourceFlow), WSubIndex( WRef(in,VectorType(UIntType(IntWidth(32)),4),PortKind,SourceFlow), 1, UIntType(IntWidth(32)),SourceFlow), WSubIndex( WRef(in,VectorType(UIntType(IntWidth(32)),4),PortKind,SourceFlow), 2, UIntType(IntWidth(32)),SourceFlow), WSubIndex( WRef(in,VectorType(UIntType(IntWidth(32)),4),PortKind,SourceFlow), 3, UIntType(IntWidth(32)),SourceFlow) )
VectorTypeは4つ分のExpsに分解される。それぞれは、
WSubIndex
というオブジェクトに変換される。WSubIndex
は、- Vecの型の情報
- インデックス
- Vecの内部の型の情報
から構成される。
つぎに、BundleInt
だが、
exps = ArrayBuffer(WSubField( WRef( in, BundleType(ArrayBuffer(Field(A,Default,UIntType(IntWidth(32))), Field(B,Default,UIntType(IntWidth(32))))), PortKind, SourceFlow), A, UIntType(IntWidth(32)), SourceFlow), WSubField( WRef( in, BundleType(ArrayBuffer(Field(A,Default,UIntType(IntWidth(32))), Field(B,Default,UIntType(IntWidth(32))))), PortKind, SourceFlow), B, UIntType(IntWidth(32)), SourceFlow) )
各フィールドは、
WSubField
に分解される。各SubField
は、WRef
によりBundleTypeの型自体の情報- フィールドの名前
- BundleTypeの内部の型の情報
つぎにVecBundle
はBundleType
とVectorType
の融合なので、これが組み合わさっているだけだ。
exps = Vector(WSubField( WSubIndex( WRef(in,VectorType(BundleType(ArrayBuffer(Field(A,Default,UIntType(IntWidth(32))))),4),PortKind,SourceFlow), 0, BundleType(ArrayBuffer(Field(A,Default,UIntType(IntWidth(32))))),SourceFlow), A, UIntType(IntWidth(32)), SourceFlow), WSubField( WSubIndex( WRef(in,VectorType(BundleType(ArrayBuffer(Field(A,Default,UIntType(IntWidth(32))))),4),PortKind,SourceFlow), 1, BundleType(ArrayBuffer(Field(A,Default,UIntType(IntWidth(32))))),SourceFlow), A, UIntType(IntWidth(32)), SourceFlow), WSubField( WSubIndex( WRef(in,VectorType(BundleType(ArrayBuffer(Field(A,Default,UIntType(IntWidth(32))))),4),PortKind,SourceFlow), 2, BundleType(ArrayBuffer(Field(A,Default,UIntType(IntWidth(32))))),SourceFlow), A, UIntType(IntWidth(32)), SourceFlow), WSubField( WSubIndex( WRef(in,VectorType(BundleType(ArrayBuffer(Field(A,Default,UIntType(IntWidth(32))))),4),PortKind,SourceFlow), 3, BundleType(ArrayBuffer(Field(A,Default,UIntType(IntWidth(32))))),SourceFlow), A, UIntType(IntWidth(32)), SourceFlow) )