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)
)